Skip to content

Instantly share code, notes, and snippets.

@miikka
Created April 7, 2012 20:00
Show Gist options
  • Save miikka/2331716 to your computer and use it in GitHub Desktop.
Save miikka/2331716 to your computer and use it in GitHub Desktop.
Create a thumbnail of a face photo.
#!/usr/bin/python
# A small script to create a square thumbnail out of a picture of a human face.
# Written by Miikka Koskinen (http://miikka.me/) on 2012-04-07.
# Based on:
# http://recursive-design.com/blog/2010/12/14/face-detection-with-osx-and-python/
import cv
import sys
from optparse import OptionParser
def crop_face_square(image, cascade, target_size = 100):
faces = cv.HaarDetectObjects(image, cascade, cv.CreateMemStorage(0))
if faces:
# Let's the face with most neighbors
((x, y, w, h), n) = sorted(faces, key=lambda x: x[1], reverse=True)[0]
# Calculate the center of the face
xc = x + w/2
yc = y + h/2
# Cropping just the detected rectangle is not enough - it probably
# doesn't containg the whole head.
size = int(max(w,h) * 1.5)
# We don't want to scale up
if size < target_size:
size = target_size
if size > image.width or size > image.height:
size = min(image.width, image.height)
# The actual top-left point of our ROI
x2 = xc - size/2
y2 = yc - size/2
# Let's keep our ROI rectangle inside the image
def limit(num, lower, upper):
return max(lower, min(upper, num))
x2 = limit(x2, 0, image.width - size)
y2 = limit(y2, 0, image.height - size)
# Actually crop the image
cropped = cv.CreateImage((size, size), 8, 3)
resized = cv.CreateImage((target_size, target_size), 8, 3)
cv.SetImageROI(image, (x2, y2, size, size))
cv.Copy(image, cropped)
cv.Resize(cropped, resized)
return resized
else:
return None
def main():
parser = OptionParser(usage = "usage: %prog [options] [input filename] [output filename]")
parser.add_option("-c", "--cascade",
action="store",
dest="cascade",
type="str",
help="Haar cascade file, default %default",
default = "/usr/local/Cellar/opencv/2.3.1a/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml")
(options, args) = parser.parse_args()
if len(args) != 2:
parser.print_help()
sys.exit(1)
input_name = args[0]
output_name = args[1]
cascade = cv.Load(options.cascade)
image = cv.LoadImage(input_name, 1)
face_square = crop_face_square(image, cascade)
if face_square:
cv.SaveImage(output_name, face_square)
else:
print "No faces found."
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment