Détecter le visage puis recadrer les images

J’essaie de trouver une application capable de détecter les visages dans mes images, de centrer le visage détecté et de recadrer 720 x 720 pixels de l’image. Il est plutôt fastidieux et méticuleux de modifier des centaines de photos que je compte faire.

J’ai essayé de le faire en utilisant python opencv mentionné ici mais je pense qu’il est dépassé. J’ai aussi essayé de l’ utiliser, mais cela me donne également une erreur dans mon système. Également essayé d’utiliser le plugin de détection de visage pour GIMP mais il est conçu pour GIMP 2.6 mais j’utilise régulièrement 2.8. J’ai aussi essayé de faire ce qui était posté sur le blog ultrahigh mais il est très obsolète (puisque j’utilise un dérivé d’Ubuntu Precise, alors que le blog a été refait quand il était encore Hardy). Aussi essayé d’utiliser Phatch mais il n’y a pas de détection de visage, donc certaines images recadrées ont leur visage coupé tout de suite.

J’ai essayé tout ce qui précède et j’ai perdu une demi-journée à essayer de faire ce que je voulais faire.

Avez-vous des suggestions pour atteindre un objective d’environ 800 photos?

Mon système d’exploitation est Linux Mint 13 MATE.

Note: J’allais append 2 liens de plus mais stackexchange m’a empêché de poster deux autres liens car je n’ai pas encore beaucoup de réputation.

J’ai réussi à saisir des bouts de code de différentes sources et à les assembler. C’est toujours un travail en cours. Avez-vous des images d’exemple?

''' Sources: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/ http://www.lucaamore.com/?p=638 ''' #Python 2.7.2 #Opencv 2.4.2 #PIL 1.1.7 import cv import Image def DetectFace(image, faceCascade): #modified from: http://www.lucaamore.com/?p=638 min_size = (20,20) image_scale = 1 haar_scale = 1.1 min_neighbors = 3 haar_flags = 0 # Allocate the temporary images smallImage = cv.CreateImage( ( cv.Round(image.width / image_scale), cv.Round(image.height / image_scale) ), 8 ,1) # Scale input image for faster processing cv.Resize(image, smallImage, cv.CV_INTER_LINEAR) # Equalize the histogram cv.EqualizeHist(smallImage, smallImage) # Detect the faces faces = cv.HaarDetectObjects( smallImage, faceCascade, cv.CreateMemStorage(0), haar_scale, min_neighbors, haar_flags, min_size ) # If faces are found if faces: for ((x, y, w, h), n) in faces: # the input to cv.HaarDetectObjects was resized, so scale the # bounding box of each face and convert it to two CvPoints pt1 = (int(x * image_scale), int(y * image_scale)) pt2 = (int((x + w) * image_scale), int((y + h) * image_scale)) cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0) return image def pil2cvGrey(pil_im): #from: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/ pil_im = pil_im.convert('L') cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1) cv.SetData(cv_im, pil_im.tossortingng(), pil_im.size[0] ) return cv_im def cv2pil(cv_im): return Image.fromssortingng("L", cv.GetSize(cv_im), cv_im.tossortingng()) pil_im=Image.open('testPics/faces.jpg') cv_im=pil2cv(pil_im) #the haarcascade files tells opencv what to look for. faceCascade = cv.Load('C:/Python27/Lib/site-packages/opencv/haarcascade_frontalface_default.xml') face=DetectFace(cv_im,faceCascade) img=cv2pil(face) img.show() 

Tests sur la première page de Google (Googled “faces”): entrer la description de l'image ici


Mettre à jour

Ce code devrait faire exactement ce que vous voulez. Faites moi savoir si vous avez des questions. J’ai essayé d’inclure beaucoup de commentaires dans le code:

 ''' Sources: http://opencv.willowgarage.com/documentation/python/cookbook.html http://www.lucaamore.com/?p=638 ''' #Python 2.7.2 #Opencv 2.4.2 #PIL 1.1.7 import cv #Opencv import Image #Image from PIL import glob import os def DetectFace(image, faceCascade, returnImage=False): # This function takes a grey scale cv image and finds # the patterns defined in the haarcascade function # modified from: http://www.lucaamore.com/?p=638 #variables min_size = (20,20) haar_scale = 1.1 min_neighbors = 3 haar_flags = 0 # Equalize the histogram cv.EqualizeHist(image, image) # Detect the faces faces = cv.HaarDetectObjects( image, faceCascade, cv.CreateMemStorage(0), haar_scale, min_neighbors, haar_flags, min_size ) # If faces are found if faces and returnImage: for ((x, y, w, h), n) in faces: # Convert bounding box to two CvPoints pt1 = (int(x), int(y)) pt2 = (int(x + w), int(y + h)) cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0) if returnImage: return image else: return faces def pil2cvGrey(pil_im): # Convert a PIL image to a greyscale cv image # from: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/ pil_im = pil_im.convert('L') cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1) cv.SetData(cv_im, pil_im.tossortingng(), pil_im.size[0] ) return cv_im def cv2pil(cv_im): # Convert the cv image to a PIL image return Image.fromssortingng("L", cv.GetSize(cv_im), cv_im.tossortingng()) def imgCrop(image, cropBox, boxScale=1): # Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)] # Calculate scale factors xDelta=max(cropBox[2]*(boxScale-1),0) yDelta=max(cropBox[3]*(boxScale-1),0) # Convert cv box to PIL box [left, upper, right, lower] PIL_box=[cropBox[0]-xDelta, cropBox[1]-yDelta, cropBox[0]+cropBox[2]+xDelta, cropBox[1]+cropBox[3]+yDelta] return image.crop(PIL_box) def faceCrop(imagePattern,boxScale=1): # Select one of the haarcascade files: # haarcascade_frontalface_alt.xml <-- Best one? # haarcascade_frontalface_alt2.xml # haarcascade_frontalface_alt_tree.xml # haarcascade_frontalface_default.xml # haarcascade_profileface.xml faceCascade = cv.Load('haarcascade_frontalface_alt.xml') imgList=glob.glob(imagePattern) if len(imgList)<=0: print 'No Images Found' return for img in imgList: pil_im=Image.open(img) cv_im=pil2cvGrey(pil_im) faces=DetectFace(cv_im,faceCascade) if faces: n=1 for face in faces: croppedImage=imgCrop(pil_im, face[0],boxScale=boxScale) fname,ext=os.path.splitext(img) croppedImage.save(fname+'_crop'+str(n)+ext) n+=1 else: print 'No faces found:', img def test(imageFilePath): pil_im=Image.open(imageFilePath) cv_im=pil2cvGrey(pil_im) # Select one of the haarcascade files: # haarcascade_frontalface_alt.xml <-- Best one? # haarcascade_frontalface_alt2.xml # haarcascade_frontalface_alt_tree.xml # haarcascade_frontalface_default.xml # haarcascade_profileface.xml faceCascade = cv.Load('haarcascade_frontalface_alt.xml') face_im=DetectFace(cv_im,faceCascade, returnImage=True) img=cv2pil(face_im) img.show() img.save('test.png') # Test the algorithm on an image #test('testPics/faces.jpg') # Crop all jpegs in a folder. Note: the code uses glob which follows unix shell rules. # Use the boxScale to scale the cropping area. 1=opencv box, 2=2x the width and height faceCrop('testPics/*.jpg',boxScale=1) 

En utilisant l'image ci-dessus, ce code extrait 52 des 59 faces, produisant des fichiers rognés tels que: entrer la description de l'image icientrer la description de l'image icientrer la description de l'image icientrer la description de l'image icientrer la description de l'image icientrer la description de l'image icientrer la description de l'image icientrer la description de l'image ici

faceetect

https://github.com/wavexx/facedetect est un joli wrapper Python OpenCV CLI, et je viens d’append cet exemple à leur fichier README en utilisant ImageMagick:

 for file in path/to/pictures/*.jpg; do name=$(basename "$file") i=0 facedetect "$file" | while read xywh; do convert "$file" -crop ${w}x${h}+${x}+${y} "path/to/faces/${name%.*}_${i}.${name##*.}" i=$(($i+1)) done done 

Testé sur Ubuntu 16.04 avec des images de profil Facebook (sans étiquette), voir:

Une autre option disponible est dlib , basée sur des approches d’apprentissage automatique.

 import dlib import Image from skimage import io import matplotlib.pyplot as plt def detect_faces(image): # Create a face detector face_detector = dlib.get_frontal_face_detector() # Run detector and get bounding boxes of the faces on image. detected_faces = face_detector(image, 1) face_frames = [(x.left(), x.top(), x.right(), x.bottom()) for x in detected_faces] return face_frames # Load image img_path = 'test.jpg' image = io.imread(img_path) # Detect faces detected_faces = detect_faces(image) # Crop faces and plot for n, face_rect in enumerate(detected_faces): face = Image.fromarray(image).crop(face_rect) plt.subplot(1, len(detected_faces), n+1) plt.axis('off') plt.imshow(face) 

entrer la description de l'image ici entrer la description de l'image ici

Cela semble être une meilleure question pour l’un des échanges plus axés sur la technologie (informatique).

Cela dit, avez-vous examiné quelque chose comme ce script de détection de visage jquery? Je ne sais pas à quel point vous êtes intelligent, mais c’est une option qui est indépendante du système d’exploitation.

Cette solution semble également prometteuse, mais nécessiterait Windows.

les codes ci-dessus fonctionnent, mais il s’agit d’une implémentation récente utilisant OpenCV. Je n’ai pas pu exécuter ce qui précède au plus tard et j’ai trouvé quelque chose qui fonctionne (à partir de différents endroits)

 import cv2 import os def facecrop(image): facedata = "haarcascade_frontalface_alt.xml" cascade = cv2.CascadeClassifier(facedata) img = cv2.imread(image) minisize = (img.shape[1],img.shape[0]) miniframe = cv2.resize(img, minisize) faces = cascade.detectMultiScale(miniframe) for f in faces: x, y, w, h = [ v for v in f ] cv2.rectangle(img, (x,y), (x+w,y+h), (255,255,255)) sub_face = img[y:y+h, x:x+w] fname, ext = os.path.splitext(image) cv2.imwrite(fname+"_cropped_"+ext, sub_face) return facecrop("1.jpg") 

J’ai utilisé cette commande shell:

for f in *.jpg;do PYTHONPATH=/usr/local/lib/python2.7/site-packages python -c 'import cv2;import sys;rects=cv2.CascadeClassifier("/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml").detectMultiScale(cv2.cvtColor(cv2.imread(sys.argv[1]),cv2.COLOR_BGR2GRAY),1.3,5);print("\n".join([" ".join([str(item) for item in row])for row in rects]))' $f|while read xywh;do convert $f -gravity NorthWest -crop ${w}x$h+$x+$y ${f%jpg}-$x-$y.png;done;done

Vous pouvez installer opencv et imagemagick sur OS X avec brew install opencv imagemagick .

Je pense que la meilleure option est l’API Google Vision. Il est mis à jour, il utilise l’apprentissage automatique et il s’améliore avec le temps.

Vous pouvez consulter la documentation pour des exemples: https://cloud.google.com/vision/docs/other-features

Autocrop a bien fonctionné pour moi. C’est aussi simple que l’ autocrop -i pics -o crop -w 400 -H 400 . Vous pouvez obtenir l’utilisation dans leur fichier readme.

 usage: [-h] [-o OUTPUT] [-i INPUT] [-w WIDTH] [-H HEIGHT] [-v] Automatically crops faces from batches of pictures optional arguments: -h, --help Show this help message and exit -o, --output, -p, --path Folder where cropped images will be placed. Default: current working directory -i, --input Folder where images to crop are located. Default: current working directory -w, --width Width of cropped files in px. Default=500 -H, --height Height of cropped files in px. Default=500 -v, --version Show program's version number and exit