Hi, I'm cute while studying Deep learning. This time, I tried a program that automatically generates a mosaic on an image.
MacOS, VScode, python3.6(anaconda)
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()
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
.
・ 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
(x coordinate, y coordinate, width, height)
・ First argument → file path (add .jpg at the end) ・ Second argument → Variable of the image you want to save (ndarray)
① 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.
・ Variable to be checked in the first argument -Type
as the second argument
Duplicate elements enclosed in {} are ignored
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.
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