[PYTHON] Automatic mosaic generation

Hi, I'm cute while studying Deep learning. This time, I tried a program that automatically generates a mosaic on an image.

Execution environment

MacOS, VScode, python3.6(anaconda)

Execution program

In writing this program, Face recognition (OpenCV) in 30 lines and output to a file! Mosaic processing on images with Python, OpenCV (whole surface, part, face, etc.) Basic image transformation of opencv: 12 examples in total! I referred to these articles!

#Images stored in str type like Man ~ Women can be displayed only after adding to this path
DATADIR = "/Users/username/Documents/Documents- MacBook Pro/HelloWorld.py/"

First of all, I think that there is a folder where the image file is saved like this, but assign the path up to the previous one to the variable. In this case, the folder HelloWorld.py contains the folders Man ~ Women.

#Read haarcascade xml file(Read the front face)
xml_path = "./haarcascade_frontalface_default.xml"

It is possible to detect the site with Cascade. ・ Front face detection: haarcascade_frontalface_default_xml ・ Eye detection: haarcascade_eye.xml ・ Smile detection: haarcascade_smile.xml

It is good to think about what you want to detect and read each.

Categories = ["Man", "Men", "Woman", "Women"]
img_size = 250
mosaic_size = 10
training_data = []

#Program for face detection+Data set generation
def create_training_data():  # Man->Arguments in the order of Women
    #Set face area classifier
    classifier = cv2.CascadeClassifier(xml_path)
    cnt = 1   

    for class_num, category in enumerate(Categories):   #You can retrieve both index and element with enumerate
        path = os.path.join(DATADIR, category)  #Combine each element of Categories and DATADIR->Access to Man ~ Women
         
        for image_name in os.listdir(path): #Get a list of Man and Woman photos-> image_all names are str type
            
            #Grayscale image(For identification) <-Take out images one by one
            gray_img = cv2.imread(os.path.join(path, image_name), cv2.IMREAD_GRAYSCALE)    #Imread cannot be read unless it is a series of paths-> image_I get an error with just name
            #The return values are x-coordinate, y-coordinate, width, and height.
            face_points = classifier.detectMultiScale(gray_img, minSize=(20, 20))
        
            #Crop the color image from the identification result
            for x, y, width, height in face_points: #Get the coordinate points of the face area
                #Trim face area
                dst_img = gray_img[y:y+height, x:x+width] #The image is vertical x horizontal
                face_img = cv2.resize(dst_img, (mosaic_size, mosaic_size), interpolation=cv2.INTER_NEAREST)    #Image resizing-> resize(Image to resize, (line,Column))
                mosaic_img = cv2.resize(face_img, (width, height), interpolation=cv2.INTER_NEAREST) #Restore to original size-> (width, height)Back in
                gray_img[y:y+height, x:x+width] = mosaic_img    #The mosaic part is inserted in the original image
                cv2.imwrite('mosaic' + str(cnt) + '.jpg', gray_img)    #Save image
            try:    
                training_data.append([gray_img, class_num]) #Added image data and label information-> class_Index number is also stored in the list with num
            except Exception as e:  #If an exception type called Exception comes, do not make an error and go through
                pass  
            cnt += 1 

create_training_data()

cv2.imread (): Image file can be read

However, please note that the data type will be in the form of 3D ndarray. You can determine the type of image with the second argument. This time, it is a grayscale image.

detectMultiScale: You can change the level of the object that can be detected in the image.

・ ScaleFactor: The larger the value, the more falsely detected, and the smaller the size, the more undetected. The closer it is to 1.01, the finer the detection can be. ┗ Larger range can be detected ・ MinNeighbors: The larger it is, the more reliable it is. ⇄ The possibility of missing a face increases. ┗ Duplicate detection locations → Overlapping objects are highly reliable -MinSize: The smallest size an object can take, objects smaller than this are ignored

imwrite: Can save image files

・ First argument → file path (add .jpg at the end) ・ Second argument → Variable of the image you want to save (ndarray)

Mosaic generation method

① Trim the area you want to mosaic. (2) Reduce the image size of that part once. ③ Return to the original size ④ Insert the mosaicked part into the original image

random.shuffle(create_training_data)   #Shuffle data


x_train = []    #image data
t_train = []    #Correct label

#Data set creation->The feature is the odd number, and the label is the even number.
for feature, label in create_training_data:
    x_train.append(feature)
    t_train.append(label)

#Convert to numpy array
x_train = np.array(x_train)
t_train = np.array(t_train)

#Checking the dataset
for i in range(0, 4):
    print("Training data label", t_train[i])
    plt.subplot(2, 2, i+1)  # subplot(How many lines,How many columns,Area you want to draw)
    plt.axis('off') #Hide axes
    #Label a man if the index number is 0 or 1, and a woman if the index number is 2 or 3.
    if t_train[i] == 0 or t_train[i] == 1:
        plt.title(label =  "Man")
        # plt.title("male", fontname="MS Gothic") # ->Japanese notation is possible
    else:
        plt.title(label = 'Woman')
        # plt.title("Female", fontname="MS Gothic") # ->Japanese notation is possible
    plt.imshow(x_train[i], cmap='gray')

plt.show()

The code on this side has nothing to do with mosaic generation, but I used it to check if the mosaic is done properly. After that, I didn't have to create a dataset this time, but I was able to grasp the flow of creating a dataset.

Notes not used this time

isinstance: Returns True or False whether the variable is of that type

・ Variable to be checked in the first argument -Type as the second argument

set method

Duplicate elements enclosed in {} are ignored

os.remove ('file path'): Remove unnecessary files

Impressions

It ended up being easier to implement than I had originally imagined. I was wondering if I had to do some complicated work after creating the dataset, but it didn't happen at all and it ended immediately. After all, I think that the face detection Cascade was convenient. Another thing is that the mosaic method was insanely easy.

At first I thought it would be difficult and I thought I needed more preparation, but when I started making it, it was fun.

The code has a lot of comments, but if I don't make a note of what the process is doing, I'll forget it and panic, so I wrote it.

Summary

For the first time, I was able to implement it from start to finish with my own power. It's not a big deal yet, but I hope I can write a lot of programs from here.

Recommended Posts

Automatic mosaic generation
Collage template automatic generation
Automatic quiz generation with COTOHA
PyCharm test code automatic generation
Masashi Sada Automatic generation of senryu
Permutation generation
Easily try automatic image generation with DCGAN-tensorflow
Automatic PowerPoint generation with python-pptx (personal memo)
[Python3] Automatic sentence generation using janome and markovify