[PYTHON] Generate an incorrect image of the cascade classifier by cutting it out from the place where the correct image of the correct image is not shown.

This is the first post. It's almost my own memorandum.

Introduction

Cascade classifier is an algorithm for detecting target objects from images. When learning the cascade classifier, it is necessary to prepare a correct image, a file that specifies where the target object is, and an image that does not show the target object (incorrect image). There are many examples of using images randomly collected from the Internet as incorrect answers when googled. However, given the property of the cascade classifier that "continue learning until the false positive rate becomes lower than a certain level", the random collection of incorrect images is not always possible considering the situation where the created cascade classifier is used in a limited number of situations. I think it may not be a good idea. (It takes more time to calculate than necessary. The false negative rate rises too much to achieve the false positive rate quota. In the first place, the image that should be the correct answer is mixed in the incorrect answer image (There are quite a few human faces etc. Then?)) In other words, assuming that the input is limited, I wrote the program introduced this time based on the idea that the incorrect answers to be prepared should be limited to the incorrect answers within the limited conditions. .. Or it can be used in situations where you want to increase the number of incorrect images that seem to be effective quickly. I used it to detect eyes from a dataset that "moved a person's face from the front (distance from the camera, etc.)".

What is a cascade classifier?

Here is a link with an easy-to-understand explanation of the cascade classifier

code

Specify a rectangular area by left-click hold + release. to the next image with a Erase the latest rectangle with d Program end with esc When it finishes, it is supposed to save how far it has progressed, but detailed operations have not been confirmed. Since it is a defective program, it will not work unless you put a text file (file name is log.txt) with 0 0 written in the go-path directory.

make_neg_img.py


#
# written by hdnkt 2020/8/28
#

import os
import cv2
import numpy as np
#Handling mouse events and preserving rectangular areas
class Img_maker:
    sx = 0
    sy = 0
    gx = 0
    gy = 0
    boxes = []
    state = 0#0:Before pressing 1:In the middle of pushing
    def __init__(self):
        self.sx = 0
        self.sy = 0
        self.gx = 0
        self.gy = 0
        self.boxes = []
        self.state = 0

    #Handling mouse events
    def mouse_event(self,event,x,y,flags,param):
        self.gx = x
        self.gy = y
        if event == cv2.EVENT_LBUTTONDOWN:
            self.sx = x
            self.sy = y
            self.state = 1
        if event == cv2.EVENT_LBUTTONUP:
            self.gx = x
            self.gy = y
            self.boxes.append([self.sx,self.sy,self.gx,self.gy])
            self.state = 0
    
    #Delete the newest rectangular area
    def pop_box(self):
        if len(self.boxes)<=0:
            return
        self.boxes.pop(len(self.boxes)-1)
    
    #I will teach you all the areas
    def get_boxes(self):
        for i in self.boxes:
            yield i
    
    #What are you doing now? 0:Not pushed in 1:Pushing in
    def get_state(self):
        return self.state

    #I will return the coordinates of the square I am drawing now. Do not call it only while pushing
    def get_nowRect(self):
        if self.state == 0:
            return
        else:
            return self.sx,self.sy,self.gx,self.gy
        


if __name__ == "__main__":

    #For prepath, specify the folder containing the original image.
    pre_path =
    #For gopath, specify the folder to put the generated incorrect image.
    go_path =
    subject_num = os.listdir(pre_path)

    #I want to save the counter and which image I saw last time. Should I write it out to a text file?
    counter = 0
    start = 0
    with open(go_path+"log.txt") as f:
        s = f.read()
        counter,start = map(int,s.split())

    for i in range(start,len(subject_num)):
        with open(go_path+"log.txt",mode="w") as f:
            f.write(str(counter)+" "+str(i))

        i = subject_num[i]
        #Load image
        tmp_img = cv2.imread(pre_path+i)
        raw = tmp_img.copy()
        cv2.namedWindow(i)
        #Set up image maker
        img_Maker = Img_maker()
        cv2.setMouseCallback(i,img_Maker.mouse_event)
        #Display image on screen
        while 1:
            #Prepare a copy for drawing
            tmp_img=raw.copy()
            for j in img_Maker.get_boxes():
                cv2.rectangle(tmp_img, (j[0],j[1]),(j[2],j[3]), (255,255,255), thickness=2)
            #Also draw the square you are drawing now
            if img_Maker.get_state()==1:
                sx,sy,gx,gy = img_Maker.get_nowRect()
                cv2.rectangle(tmp_img, (sx,sy),(gx,gy), (255,255,255), thickness=2)

            cv2.imshow(i,tmp_img)

            end = False
            #Key operation
            k = 0
            k = cv2.waitKey(1)
            if k==ord("a"):#To the next image
                break
            if k==ord("d"):#Delete the previous image
                img_Maker.pop_box()
            if k==27:#Save the result and exit
                end = True
                break
        
        #Export image
        for j in img_Maker.get_boxes():
            counter+=1
            print(go_path+str(counter)+".bmp")
            cv2.imshow("a",raw[j[1]:j[3],j[0]:j[2]])
            cv2.imwrite(go_path+str(counter)+".bmp",raw[j[1]:j[3],j[0]:j[2]])
        
        #Destroy.
        cv2.destroyAllWindows()

        if end:
            break

Summary

After learning the cascade classifier, add the results together.

Recommended Posts

Generate an incorrect image of the cascade classifier by cutting it out from the place where the correct image of the correct image is not shown.
Find out the name of the method that called it from the method that is python
Around the place where the value of Errbot is stored
Judge whether it is my child from the picture of Shiba Inu by deep learning (1)
Judging whether or not it is my child from the picture of Shiba Inu by deep learning (2) Data increase, transfer learning, fine tuning