Back

transfering labelme masked image to a random background

it's been awhile since my last post (it wasn't even complete lol) , but during that time i've been tinkering around with various deep learning models and frameworks, and what i've found out is that augmented data is important in order to train accurate ML models, while there are libraries made for augmentations like albumentations readily available , the type of augmentation that i want to do is not avialable anywhere (if there is a library that can do this ,please do tell). what im trying to do is taking a labeled image from labelme and then putting it in a different background, so let's get to it!

first of all , we need to setup our folders properly! below is an example

├── projectFolder 
│   ├── imgs     //images labeled in label me and thier json files
│   │   ├── img1.jpeg
│   │   ├── img1.json
│   ├── random   // random image of your choosing to be used as background
│   │   ├── random1.jpeg
│   │   ├── random2.png
│   ├── test.py
│   ├── test //outputs folder

the code below should cut labels from the imgs and then put them in the test folder with a random background from random assigned.


test.py


import os
import cv2
import json
from pathlib import Path
import numpy as np
import random


class labelCut:
    def __init__(self, folder,randomImgFolder,randomImageArray=None, jsonArray=None,imageArray=None):
        self.folder = folder
        self.jsonArray = jsonArray
        self.imageArray = imageArray
        self.randomImgFolder = randomImgFolder
        
    def lookForJson(self, folder):
        folder = Path(self.folder)
        jsons = []
        for roots, dir, files in os.walk(folder):
            for file in files:
                if file.endswith(".json"):
                    jsons.append((os.path.join(folder, file)))
        self.jsonArray = jsons
        return self.jsonArray

    def readImageFromLabelme(self):
        imagefiles = []
        
        jsons = self.lookForJson(self.folder)
        for jsonfile in jsons:
            imagePath = ""
            imageName = ""
            extension = os.path.splitext(Path(json.load(open(jsonfile))['imagePath']))[1]       
            localDir = Path(json.load(open(jsonfile))['imagePath']).stem.split('.')[0]
            if localDir != "":
                imagePath = Path(json.load(open(jsonfile))['imagePath']).stem.split('.')[0].split('\\')[1] 
            else:
                continue        
            frontpath = (os.path.join(os.getcwd(),self.folder))
            fullpath = (frontpath + "/" +imagePath + extension)
            imagefiles.append(fullpath)
        self.imageArray = imagefiles
        return imagefiles
     
    def getRandomBackground(self):
        randomimg = []
        imgfmts = (".jpg", ".jpeg", ".png")
        for root, dirs, files in os.walk(self.randomImgFolder):
            for file in files:
                if file.endswith(imgfmts):
                    randomimg.append(os.path.join(os.getcwd(), (self.randomImgFolder + "/" + file)))
        return randomimg


    def randomBgFromLabelme(self):
        self.readImageFromLabelme() #load json
        randomimg = self.getRandomBackground()
        for index, label in enumerate(self.jsonArray): 
            loadjson = json.load(open(label))
            try:
                pts = loadjson["shapes"][index]["points"]
                mask = np.array(pts, np.int32)
                img = cv2.imread(self.imageArray[index])
                blackbg = np.zeros((img.shape[0], img.shape[1], 3))
                gg = cv2.fillPoly(blackbg, pts = [mask], color=(255,255,255))
                gg = gg.astype(np.uint8)
                
                result = cv2.cvtColor(cv2.bitwise_and(img, gg), 1)
                _,alpha = cv2.threshold(result, 0, 255, cv2.THRESH_BINARY)
                alpha = cv2.cvtColor(alpha, cv2.COLOR_BGR2GRAY)
                b,g,r = cv2.split(img)
                rgba = [b,g,r,alpha]
                dst = cv2.merge(rgba,4)
                
                loadrandimg = cv2.imread(randomimg[random.randint(0, len(randomimg))])
                loadrandimg = cv2.resize(loadrandimg, (img.shape[1], img.shape[0]))
                
                alpha = cv2.merge([alpha,alpha,alpha])
                front = dst[:,:,0:3]
                result = np.where(alpha==(0,0,0), loadrandimg, front)
                    
                cv2.imwrite(f"test/t{index}.png", result)
            except:
                continue

test = labelCut(folder="imgs", randomImgFolder="random")
test.randomBgFromLabelme()

that's it for now, until next time!