Torch3Vision

jpegtopnm is obsolete under debian. Use djpeg instead

apt-get install libjpeg-progs

http://torch3vision.idiap.ch/

Quelle (grossteils) 1)

You will need the C++ Compiler 'g++' to make. When not compiling enter:

apt-get install g++

(Or on AMD 64: cp Linux_i686.cfg.vision2.1 Linux_x86_64.cfg )

../../../torch3make *.cc

Jetzt 3 Programme in neuen Unterverzeichnis Linux_i686_dbg_float:

Jedes dieser 3 Programme braucht eine Modeldatei zur Gesichtererkennung. Diese 3 Dateien liegen unter vision2.1/examples/facedetect/models/. Die jeweils passende Datei muss (mit Pfad) bei jeden Aufruf angegeben werden.

So now we have a working set of face-detection programmes. The command line interface isn’t too friendly, so they take a little playing around. For starters, the binaries on my Ubuntu system don’t read JPEG images (although the code seems to be there, the build system is non-standard and didn’t automatically pick up my jpeg libraries. So, I needed to convert my images to PPM format, which is one of those image formats that no-one uses but somehow is the lowest common denominator for image processing command line apps. I use the program ‘jpegtopnm’ from package ‘netpbm’.

jpegtopnm andy.jpg > andy.ppm

Of the three facial detection programs available, I found ‘mlpcascadescan’ to be the most effective and quickest, although they all have similar interfaces so this will basically be the same for all of them. We need to pass the source image and the model file, and we tell it to write the face position and to save a drawing with the face detected:

mlpcascadescan andy.ppm -savepos -draw \
 -model ~/temp/models/mlp-cascade19×19-20-2-110

This command takes about 20s to run on my creaky old laptop, and creates two files.

Source code of examples

Parmaters (as far as i found out):

The other file ‘andy.pos’ contains the results of face detection. Line one is the number of detections, then each line has format x y w h, very easy to parse.

 FACE_POS=`head -n 2 “andy.pos | tail -n 1`
 FACE_X=`echo $FACE_POS | awk ‘{print $1}’`
 FACE_W=`echo $FACE_POS | awk ‘{print $3}’`
 FACE_CENTER=`echo $FACE_X + $FACE_W/2 | bc` 

I played around with the step-factors in the x and y directions to shave a second or so off the face detection routine, the values I chose were 0.1 and 0.2 respectively (I don’t need any accuracy in the y direction really, since my use is to cut the face down the middle).

Then, since these are portrait photographs, I can speed up face detection by setting a minimum size for the face. I experimented and one sixth of the total image width gave good results - any larger and the face detection would fail with a crash. Adding this constraint provides better than 10X speed up, since the algorithm doesn’t waste time searching for small faces.

WIDTH=`identify -format “%w” “andy.jpg”`
 MIN_FACE_WIDTH=`echo $WIDTH / 6 | bc` 

So now here’s the final face detection command

mlpcascadescan “$ppm” -dir /tmp/ -savepos -model $MODEL \
 -minWsize $MIN_FACE_WIDTH -stepxfactor $STEPX -stepyfactor $STEPY 

And finally, as promised, I’ll tell you how to blank-out one side of the face: of course, using Image Magick. Using the ‘chop’ or ‘crop’ commands didn’t work for this purpose, where I wanted the image to keep it’s dimensions but have one half just be white. So I decided to draw a white rectangle over half of the picture. I apply the image manipulation to the original JPEG file, not the temporary PPM file that I used to detect the face position.

convert -fill white \
 -draw “rectangle $FACE_CENTER,0 $WIDTH,$HEIGHT” \
 “andy.jpg” “andy_half.jpg”

Whole script:

#!/bin/bash
 
. ~/local/bin/die
 
DRAW="-draw"
STEPX="0.05"
STEPY="0.25"
MODEL="$HOME/local/models/mlp-cascade19x19-20-2-110"
 
# Find the center of the face in the image. Crop the image along the center of
# the face.
 
# Requirements: 'torch3vision' http://torch3vision.idiap.ch/downloads.php
which mlpcascadescan > /dev/null || \
	die "Please install mlpcascadescan from torch3vision"
 
[ -e "$MODEL" ] || die "Model file $MODEL not found, get it from torch3vision"
 
FACE_CENTER=""
 
# Find the center of the face. Takes a jpeg and finds the face.
function find_center() {
	jpeg="$1"
	temp="/tmp/crop_center_face"
	ppm="$temp.ppm"
	pos="$temp.pos"
	echo "Converting to ppm"
	jpegtopnm $jpeg > $ppm
	if [ -e "$pos" ]; then
		rm "$pos"
	fi
    HEIGHT=`identify -format "%h" "$jpeg"`;
    WIDTH=`identify -format "%w" "$jpeg"`;
	MIN_FACE_WIDTH=`echo $WIDTH / 6 | bc`
	echo "Beginning face detection, min-width=$MIN_FACE_WIDTH"
	echo "mlpcascadescan "$ppm" -dir /tmp/ -savepos $DRAW -model $MODEL \
		-minWsize $MIN_FACE_WIDTH -stepxfactor $STEPX -stepyfactor $STEPY"
	mlpcascadescan "$ppm" -dir /tmp/ -savepos $DRAW -model $MODEL \
		-minWsize $MIN_FACE_WIDTH -stepxfactor $STEPX -stepyfactor $STEPY
	[ -e "$pos" ] || die "Face detection failed: $jpeg"
	FACE_POS=`head -n 2 "$pos" | tail -n 1`
	FACE_X=`echo $FACE_POS | awk '{print $1}'`
	FACE_W=`echo $FACE_POS | awk '{print $3}'`
	FACE_CENTER=`echo $FACE_X + $FACE_W/2 | bc`
	echo "FACE_X: $FACE_X   FACE_W: $FACE_W   FACE_CENTER: $FACE_CENTER"
}
 
function crop_image() {
	jpeg="$1"
	ext=${jpeg##*.}
    base=`basename "$jpeg" .$ext`
    crop="$base""_crop.jpg"
    HEIGHT=`identify -format "%h" "$jpeg"`;
    WIDTH=`identify -format "%w" "$jpeg"`;
	echo "Cropping $jpeg at $FACE_CENTER, saving to $crop"
	convert -fill white -draw "rectangle $FACE_CENTER,0 $WIDTH,$HEIGHT" "$jpeg" "$crop"
}
 
 
for file in $@; do
	echo "Processing file: $file"
	find_center $file
	crop_image $file
done