我正在尝试找到一个可以检测我的照片中的脸部的应用程序,使检测到的脸部居中并裁剪出720 x 720像素的照片。这是非常耗时的。一丝不苟地编辑我打算做的数百张图片。
我尝试使用python opencv mentioned here执行此操作,但我认为它已过时。我也试过using this,但它也在我的系统中给了我一个错误。还尝试使用GIMP的面部检测插件,但它是为GIMP 2.6设计的,但我定期使用2.8。我也尝试过在ultrahigh博客上发布的内容,但它已经过时了(因为我使用的是Ubuntu的精确衍生版本,而博客帖子在它仍然是Hardy的时候就已经回归了)。也尝试使用Phatch,但没有面部检测,所以一些裁剪的图片的脸被切断。
我已经尝试了上述所有内容并浪费了半天的时间,试图让上述任何一项做我需要做的事情。
你们有没有建议我实现约800张照片的目标。
我的操作系统是Linux Mint 13 MATE。
注意:我打算再添加2个链接但是stackexchange阻止我发布两个链接,因为我还没有太多的声誉。
答案 0 :(得分: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()
在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)
使用上面的图片,此代码从59个面中提取52个,生成裁剪文件,例如:
答案 1 :(得分:12)
<强> facedetect 强>
https://github.com/wavexx/facedetect是一个不错的Python OpenCV CLI包装器,我使用ImageMagick将这个示例作为自述文件的just added:
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
在Ubuntu 16.04上测试了数千条(未标记的)Facebook个人资料照片,请参阅:https://github.com/cirosantilli/art/tree/d4352a46064d156591817c4eae5199f5ac8f23be/facebook
答案 2 :(得分:11)
另一个可用选项是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)
答案 3 :(得分:5)
对于更多(计算机)技术重点交流之一来说,这似乎是一个更好的问题。
那就是说,你看过something like this jquery人脸检测脚本吗?我不知道你有多精明,但它是一个独立于操作系统的选项。
This solution看起来也很有希望,但需要Windows。
答案 4 :(得分:4)
以上代码有效,但这是最近使用OpenCV的实现 我无法通过最新的方式运行上述内容并找到了有效的方法(来自不同的地方)
app.get(prefix + '/GetAnalyticsByUserId', function (req, res, next) {
var instaid = req.query.instaid;
var lastdate = req.query.lastdate; // this is my date in the timestamp i want to using this equal or greater date and count
InstaAc.aggregate(
{ $match: { _id: ObjectId("595f6bcdeb3db12064f26336") } },
{ $unwind: '$History' },
{ $match: { 'History.Action': { $eq: "Comment" } } },
{ $match: { 'History.datetime': { $gte: "datetime" } } },
{ $group: { _id: '$_id', History: { $push: '$History' } } }).exec(function (err, data) {
if (err) {
console.log(err); res.send(err)
}
else {
console.log(data);
res.send(data);
}
})
});
答案 5 :(得分:1)
我使用了这个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 x y w h;do convert $f -gravity NorthWest -crop ${w}x$h+$x+$y ${f%jpg}-$x-$y.png;done;done
您可以使用opencv
在OS X上安装imagemagick
和brew install opencv imagemagick
。
答案 6 :(得分:1)
Autocrop很适合我。
它就像autocrop -i pics -o crop -w 400 -H 400
一样简单。
您可以在自述文件中获取用法。
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
答案 7 :(得分:1)
只需添加到@以色列阿贝贝的版本。如果在图像扩展之前添加计数器,该算法将给出检测到的所有面部。附加代码,与以色列安倍比的代码相同。只需添加一个计数器并接受级联文件作为参数即可。该算法效果很好!谢谢@以色列阿贝贝!
import cv2
import os
import sys
def facecrop(image):
facedata = sys.argv[1]
cascade = cv2.CascadeClassifier(facedata)
img = cv2.imread(image)
minisize = (img.shape[1],img.shape[0])
miniframe = cv2.resize(img, minisize)
faces = cascade.detectMultiScale(miniframe)
counter = 0
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_"+str(counter)+ext, sub_face)
counter += 1
return
facecrop("Face_detect_1.jpg")
PS:添加为答案。由于积分问题,无法添加评论。
答案 8 :(得分:1)
我已经使用python包'face_recognition'和'opencv-python'开发了一个“带有个人数据集的人脸识别”应用程序。 / p>
源代码和安装指南位于GitHub-Face-Recognition-with-Own-Data-Set
或运行源代码-
import face_recognition
import cv2
import numpy as np
import os
'''
Get current working director and create a Data directory to store the faces
'''
currentDirectory = os.getcwd()
dirName = os.path.join(currentDirectory, 'Data')
print(dirName)
if not os.path.exists(dirName):
try:
os.makedirs(dirName)
except:
raise OSError("Can't create destination directory (%s)!" % (dirName))
'''
For the given path, get the List of all files in the directory tree
'''
def getListOfFiles(dirName):
# create a list of file and sub directories
# names in the given directory
listOfFile = os.listdir(dirName)
allFiles = list()
# Iterate over all the entries
for entry in listOfFile:
# Create full path
fullPath = os.path.join(dirName, entry)
# If entry is a directory then get the list of files in this directory
if os.path.isdir(fullPath):
allFiles = allFiles + getListOfFiles(fullPath)
else:
allFiles.append(fullPath)
return allFiles
def knownFaceEncoding(listOfFiles):
known_face_encodings=list()
known_face_names=list()
for file_name in listOfFiles:
# print(file_name)
if(file_name.lower().endswith(('.png', '.jpg', '.jpeg'))):
known_image = face_recognition.load_image_file(file_name)
# known_face_locations = face_recognition.face_locations(known_image)
# known_face_encoding = face_recognition.face_encodings(known_image,known_face_locations)
face_encods = face_recognition.face_encodings(known_image)
if face_encods:
known_face_encoding = face_encods[0]
known_face_encodings.append(known_face_encoding)
known_face_names.append(os.path.basename(file_name[0:-4]))
return known_face_encodings, known_face_names
# Get the list of all files in directory tree at given path
listOfFiles = getListOfFiles(dirName)
known_face_encodings, known_face_names = knownFaceEncoding(listOfFiles)
video_capture = cv2.VideoCapture(0)
cv2.namedWindow("Video", flags= cv2.WINDOW_NORMAL)
# cv2.namedWindow("Video")
cv2.resizeWindow('Video', 1024,640)
cv2.moveWindow('Video', 20,20)
# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
while True:
# Grab a single frame of video
ret, frame = video_capture.read()
# print(ret)
# Resize frame of video to 1/4 size for faster face recognition processing
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
# Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
rgb_small_frame = small_frame[:, :, ::-1]
k = cv2.waitKey(1)
# Hit 'c' on capture the image!
# Hit 'q' on the keyboard to quit!
if k == ord('q'):
break
elif k== ord('c'):
face_loc = face_recognition.face_locations(rgb_small_frame)
if face_loc:
print("Enter Name -")
name = input()
img_name = "{}/{}.png".format(dirName,name)
(top, right, bottom, left)= face_loc[0]
top *= 4
right *= 4
bottom *= 4
left *= 4
cv2.imwrite(img_name, frame[top - 5 :bottom + 5,left -5 :right + 5])
listOfFiles = getListOfFiles(dirName)
known_face_encodings, known_face_names = knownFaceEncoding(listOfFiles)
# Only process every other frame of video to save time
if process_this_frame:
# Find all the faces and face encodings in the current frame of video
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
# print(face_locations)
face_names = []
for face_encoding,face_location in zip(face_encodings,face_locations):
# See if the face is a match for the known face(s)
matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance= 0.55)
name = "Unknown"
distance = 0
# use the known face with the smallest distance to the new face
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
#print(face_distances)
if len(face_distances) > 0:
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
# distance = face_distances[best_match_index]
#print(face_distances[best_match_index])
# string_value = '{} {:.3f}'.format(name, distance)
face_names.append(name)
process_this_frame = not process_this_frame
# Display the results
for (top, right, bottom, left), name in zip(face_locations, face_names):
# Scale back up face locations since the frame we detected in was scaled to 1/4 size
top *= 4
right *= 4
bottom *= 4
left *= 4
# Draw a box around the face
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
# Draw a label with a name below the face
cv2.rectangle(frame, (left, bottom + 46), (right, bottom+11), (0, 0, 155), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom +40), font, 1.0, (255, 255, 255), 1)
# Display the resulting image
cv2.imshow('Video', frame)
# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()
它将在当前位置创建一个“数据”目录,即使该目录不存在。
当用矩形标记人脸时,按'c'捕获图像,然后在命令提示符下询问人脸名称。输入图像名称并输入。您可以在“数据” 目录中找到此图片。
答案 9 :(得分:0)
我认为最好的选择是Google Vision API。 它已经更新,它使用机器学习,随着时间的推移而改进。
您可以查看文档中的示例: https://cloud.google.com/vision/docs/other-features
答案 10 :(得分:0)
检测面部,然后进行裁剪并将裁剪后的图像保存到文件夹..
import numpy as np
import cv2 as cv
face_cascade = cv.CascadeClassifier('./haarcascade_frontalface_default.xml')
#eye_cascade = cv.CascadeClassifier('haarcascade_eye.xml')
img = cv.imread('./face/nancy-Copy1.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
#eyes = eye_cascade.detectMultiScale(roi_gray)
#for (ex,ey,ew,eh) in eyes:
# cv.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
sub_face = img[y:y+h, x:x+w]
face_file_name = "face/" + str(y) + ".jpg"
plt.imsave(face_file_name, sub_face)
plt.imshow(sub_face)