检测脸部然后autocrop图片

我试图find一个应用程序,可以检测到我的照片中的脸部,使检测到的脸部居中,裁剪720 x 720像素的图片。 编辑数百张我打算这样做的照片是非常耗时和细致的。

我已经尝试使用这里提到的python opencv做这个,但是我认为它已经过时了。 我也试过使用这个,但它也给我在我的系统中的错误。 也尝试使用GIMP的脸部检测插件,但它是专为GIMP 2.6,但我定期使用2.8。 我也尝试过在超高博客上发布的内容,但这已经过时了(因为我使用的是Ubuntu的精确派生版,而博客文章还是在哈代之前取消了)。 也尝试使用Phatch,但没有面部检测,所以一些裁剪图片,他们的脸被切断了。

我已经尝试了上述所有,浪费了半天的时间,试图让上述任何一个做我所需要做的事情。

你们有没有build议,以达到我有约800张照片的目标。

我的操作系统是Linux Mint 13 MATE。

注意:我打算再添加2个链接,但是stackexchange阻止我发布两个链接,因为我没有太多的声望。

我已经设法从各种来源获取一些代码并将它们缝合在一起。 这仍然是一项正在进行中的工作。 另外,你有任何示例图像?

''' 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() 

在Google的第一页上进行testing(谷歌search“面孔”): 在这里输入图像说明


更新

这个代码应该做你想要的。 如果你有问题,请告诉我。 我试图在代码中包含大量的注释:

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

使用上面的图片,这段代码从59个面中提取了52个,生成裁剪文件,例如: 在这里输入图像说明在这里输入图像说明在这里输入图像说明在这里输入图像说明在这里输入图像说明在这里输入图像说明在这里输入图像说明在这里输入图像说明

facedetect

https://github.com/wavexx/facedetect是一个不错的Python OpenCV CLI包装器,我刚刚使用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 

使用(未标记的)Facebook个人资料图片在Ubuntu 16.04上testing,请参阅:

这听起来似乎是更多(计算机)技术集中交stream的一个更好的问题。

这就是说,你有没有像这个 jQuery面部检测脚本? 我不知道你是多么的聪明,但它是一个独立于操作系统的选项。

这个解决scheme也看起来很有希望,但是需要Windows。

另一个可用的选项是基于机器学习方法的dlib 。

 import dlib import Image from skimage import io 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) 

在这里输入图像说明 在这里输入图像说明

我使用了这个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

你可以在OS X上安装opencvimagemagick ,使用brew install opencv imagemagick

我认为最好的select是Google Vision API。 它被更新,它使用机器学习,并随着时间的推移而改进。

您可以查看相关示例文档: https : //cloud.google.com/vision/docs/other-features

上面的代码工作,但这是最近使用OpenCV的实现我无法运行最新的以上,并find了一些工作(从各地)

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