J'utilise Haarcascade_frontalface d'OpenCV pour reconnaître le visage, mais contrairement à SIFT et SURF, cela ne semble pas être une fonction invariante en rotation, et même si j'incline un peu le visage, le visage n'est pas reconnu.
Lors de la détection en temps réel avec une image de caméra, si vous mettez la caméra bien droite, elle sera reconnue raisonnablement parce que les gens ordinaires pointent la tête droite. Si vous détectez une photo qui est inclinée de cette manière par elle-même, elle ne sera pas reconnue correctement.
Sur cette photo, seule Reni Takashiro, qui fait face droit devant elle, a détecté son visage.
L'idée est que si seulement un certain angle est reconnu, l'image elle-même doit être inclinée, et si toutes les images dont l'inclinaison est modifiée par petits pas sont jugées, toutes les faces inclinées seront détectées. droite.
Les étapes sont les suivantes
Cela ressemble à ceci sur la figure
Ceci est le code source pour découper et enregistrer la photo du visage.
import cv2
import numpy as np
import os
from math import ceil
temp_face_img_path = 'work/temp/face/'
#Spécifiez le fichier xml utilisé pour le jugement de visage.
cascade_path = os.path.dirname(os.path.abspath(__file__)) + "/haarcascade_frontalface_alt2.xml"
class classifyPhoto:
def __init__(self):
print("init")
#Couper le visage de l'image, enregistrer, retourner le chemin
def crop_face(self, img_path):
#Analyse des noms de fichiers
base_name = os.path.basename(img_path)
name,ext = os.path.splitext(base_name)
if (ext != '.jpg') and (ext != '.jpeg') :
print('not a jpg image')
return
img_src = cv2.imread(img_path, 1)
#Convertir en échelle de gris
img_gray = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
cascade = cv2.CascadeClassifier(cascade_path)
org_width = img_src.shape[1]
org_height = img_src.shape[0]
i = 0
for j in range(0,71):
#Créer une image agrandie
big_img = np.zeros((org_height * 2, org_width * 2 ,3), np.uint8)
big_img[ceil(org_height/2.0):ceil(org_height/2.0*3.0), ceil(org_width/2.0):ceil(org_width/2.0*3.0)] = img_src
#Position centrale de l'image
center = tuple(np.array([big_img.shape[1] * 0.5, big_img.shape[0] * 0.5]))
#Obtenir la taille de l'image(côté,Verticale)
size = tuple(np.array([big_img.shape[1], big_img.shape[0]]))
#L'angle que vous souhaitez faire pivoter
angle = 5.0 * float(j)
#Taux d'expansion
scale = 1.0
#Calcul de la matrice de conversion de rotation
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)
#Conversion d'affine
img_rot = cv2.warpAffine(big_img, rotation_matrix, size, flags=cv2.INTER_CUBIC)
rot_gray = cv2.cvtColor(img_rot, cv2.COLOR_BGR2GRAY)
#Jugement de visage
faces = cascade.detectMultiScale(img_rot, scaleFactor=1.2, minNeighbors=2, minSize=(50, 50))
#S'il y a un visage
if len(faces) > 0:
for (x,y,w,h) in faces:
face = img_rot[y:y+h, x:x+w]
file_name = name + "_face_" + str(i) + ext
cv2.imwrite(temp_face_img_path + file_name, face )
i += 1
else :
print('does not have any faces')
return
if __name__ == '__main__':
classifier = classifyPhoto()
classifier.crop_faceo('image.jpg')
Il serait peut-être préférable de le régler, mais cela ne fonctionnera probablement pas.
Recommended Posts