检测面部然后自动拍摄照片

Ais*_*yes 53 python linux opencv crop face-detection

我正在尝试找到一个可以检测我的照片中的脸部的应用程序,使检测到的脸部居中并裁剪720 x 720像素的照片.编辑我计划做的数百张图片是非常耗时和细致的.

我尝试过使用这里提到的python opencv做这个,但我认为它已经过时了.我也试过使用它,但它也在我的系统中给了我一个错误.还尝试使用GIMP的面部检测插件,但它是为GIMP 2.6设计的,但我定期使用2.8.我也尝试过在ultrahigh博客上发布的内容,但它已经过时了(因为我使用的是Ubuntu的精确衍生版本,而博客帖子在它仍然是Hardy的时候又回来了).也尝试使用Phatch,但没有面部检测,所以一些裁剪的图片的脸被切断.

我已经尝试了以上所有这些并且浪费了半天时间试图让上述任何一项做我需要做的事情.

你们有没有建议实现我拥有的大约800张照片的目标.

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

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

Onl*_*jus 88

我已经设法从各种来源获取代码并将其拼接在一起.它仍在进行中.另外,你有任何示例图像吗?

'''
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()
Run Code Online (Sandbox Code Playgroud)

在Google的第一页上进行测试(Google搜索"面孔"): 在此输入图像描述


更新

这段代码应该完全符合您的要求.如果您有疑问,请告诉我.我试图在代码中包含很多注释:

'''
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)
Run Code Online (Sandbox Code Playgroud)

使用上面的图像,此代码从59个面中提取52个,生成裁剪文件,例如: 在此输入图像描述在此输入图像描述在此输入图像描述在此输入图像描述在此输入图像描述在此输入图像描述在此输入图像描述在此输入图像描述

  • 我只是更新我的答案.这应该够了吧.如果您有任何疑问,请告诉我. (3认同)
  • 似乎不适用于最新的 python + opencv 版本:( (2认同)

Cir*_*四事件 12

facedetect

https://github.com/wavexx/facedetect是一个不错的Python OpenCV CLI包装器,我刚刚使用ImageMagick将该示例添加到他们的README:

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
Run Code Online (Sandbox Code Playgroud)

在Ubuntu 16.04上测试了(未标记的)Facebook个人资料照片,请参阅:


Kat*_*ova 12

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

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在此输入图像描述


小智 5

对于更多(计算机)技术重点交换之一来说,这听起来可能是一个更好的问题.

那就是说,你有没有看过这样的 jquery人脸检测脚本?我不知道你有多精明,但它是一个独立于操作系统的选项.

这个解决方案看起来很有希望,但需要Windows.


Abh*_*ngh 5

Autocrop对我来说效果很好。就这么简单autocrop -i pics -o crop -w 400 -H 400。您可以在他们的自述文件中获取用法。

usage: autocrop [-h] [-i INPUT] [-o OUTPUT] [-r REJECT] [-w WIDTH] [-H HEIGHT]
                [-v] [--no-confirm] [--facePercent FACEPERCENT] [-e EXTENSION]

Automatically crops faces from batches of pictures

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        Folder where images to crop are located. Default:
                        current working directory
  -o OUTPUT, --output OUTPUT, -p OUTPUT, --path OUTPUT
                        Folder where cropped images will be moved to. Default:
                        current working directory, meaning images are cropped
                        in place.
  -r REJECT, --reject REJECT
                        Folder where images that could not be cropped will be
                        moved to. Default: current working directory, meaning
                        images that are not cropped will be left in place.
  -w WIDTH, --width WIDTH
                        Width of cropped files in px. Default=500
  -H HEIGHT, --height HEIGHT
                        Height of cropped files in px. Default=500
  -v, --version         show program's version number and exit
  --no-confirm          Bypass any confirmation prompts
  --facePercent FACEPERCENT
                        Percentage of face to image height
  -e EXTENSION, --extension EXTENSION
                        Enter the image extension which to save at output
Run Code Online (Sandbox Code Playgroud)