I am trying to find an app that can detect faces in my pictures, make the detected face centered and crop 720 x 720 pixels of the picture. It is rather very time consuming &
facedetect
https://github.com/wavexx/facedetect is a nice Python OpenCV CLI wrapper, and I have just added that example to their README using 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
Tested on Ubuntu 16.04 with thousands of (unlabeled) Facebook profile pictures, see: https://github.com/cirosantilli/art/tree/d4352a46064d156591817c4eae5199f5ac8f23be/facebook
Another available option is dlib, which is based on machine learning approaches.
import dlib
from PIL 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)
This sounds like it might be a better question for one of the more (computer) technology focused exchanges.
That said, have you looked into something like this jquery face detection script? I don't know how savvy you are, but it is one option that is OS independent.
This solution also looks promising, but would require Windows.
the above codes work but this is recent implementation using OpenCV I was unable to run the above by the latest and found something that works (from various places)
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")
Detect face and then crop and save the cropped image into folder ..
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)
Autocrop worked out for me pretty well.
It is as easy as autocrop -i pics -o crop -w 400 -H 400
.
You can get the usage in their readme file.
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