recognition learning face_recognition dlib python linux opencv crop face-detection

python - learning - Detecta la cara y luego crea imágenes automáticas



opencv webcam python (8)

Creo que la mejor opción es Google Vision API. Se actualiza, utiliza aprendizaje automático y mejora con el tiempo.

Puede consultar la documentación en busca de ejemplos: https://cloud.google.com/vision/docs/other-features

Estoy tratando de encontrar una aplicación que pueda detectar caras en mis imágenes, hacer que la cara detectada se centre y recortar 720 x 720 píxeles de la imagen. Es bastante lento y meticuloso editar alrededor de cientos de fotos. Planeo hacerlo.

He intentado hacer esto usando python opencv mencionado aquí, pero creo que está desactualizado. También intenté usar esto pero también me está dando un error en mi sistema. También intenté usar el plugin de detección de rostros para GIMP pero está diseñado para GIMP 2.6 pero estoy usando 2.8 regularmente. También intenté hacer lo que se publicó en el blog ultrahigh, pero está muy desactualizado (ya que estoy usando un derivativo Precise de Ubuntu, mientras que el blog se remonta a cuando todavía era Hardy). También probé usar Phatch pero no hay detección de rostros, por lo que algunas imágenes recortadas se cortan la cara de inmediato.

He intentado todo lo anterior y perdí medio día tratando de hacer lo que tenía que hacer.

¿Tienen alguna sugerencia para lograr un objetivo de alrededor de 800 imágenes que tengo.

Mi sistema operativo es Linux Mint 13 MATE.

Nota: Iba a agregar 2 enlaces más pero stackexchange me impidió publicar dos enlaces más ya que aún no tengo mucha reputación.


Me las arreglé para tomar trozos de código de varias fuentes y unir esto. Es un trabajo que todavía está en progreso. Además, ¿tienes alguna imagen de ejemplo?

'''''' 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.tostring(), pil_im.size[0] ) return cv_im def cv2pil(cv_im): return Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring()) 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()

Prueba en la primera página de Google ("caras" en Google):

Actualizar

Este código debería hacer exactamente lo que quieras. Déjeme saber si usted tiene preguntas. Traté de incluir muchos comentarios en el código:

'''''' 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.tostring(), pil_im.size[0] ) return cv_im def cv2pil(cv_im): # Convert the cv image to a PIL image return Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring()) 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)

Usando la imagen de arriba, este código extrae 52 de las 59 caras, produciendo archivos recortados como:


Otra opción disponible es dlib , que se basa en enfoques de aprendizaje automático.

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)


Parece que podría ser una mejor pregunta para uno de los intercambios más centrados en la tecnología (de la computadora).

Dicho esto, ¿has investigado algo como este guión de detección de rostros jquery? No sé qué tan listo eres, pero es una opción que es independiente del sistema operativo.

Esta solución también parece prometedora, pero requeriría Windows.


Usé este comando de 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

Puede instalar opencv e imagemagick en OS X con brew install opencv imagemagick .


los códigos anteriores funcionan pero esta es una implementación reciente que usa OpenCV. No pude ejecutar lo anterior más arriba y encontré algo que funciona (desde varios lugares)

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")


Autocrop funcionó bastante bien para mí. Es tan fácil como autocrop -i pics -o crop -w 400 -H 400 . Puede obtener el uso en su archivo Léame.

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


facedetect

https://github.com/wavexx/facedetect es un buen contenedor Python OpenCV CLI, y acabo de agregar ese ejemplo a su archivo README utilizando ImageMagick:

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

Probado en Ubuntu 16.04 con fotos de perfil de Facebook (sin etiqueta), ver: