====== Torch3Vision ======
{{tag>face_detecton gesichtererkennung}}
jpegtopnm is obsolete under debian. Use djpeg instead
apt-get install libjpeg-progs
[[http://torch3vision.idiap.ch/]]
Quelle (grossteils) ((http://ultrahigh.org/2008/10/14/command-line-face-detection/))
You will need the C++ Compiler 'g++' to make. When not compiling enter:
apt-get install g++
* Download Torch3Vision and un-tar it: tar -zxf Torch3vision2.1.tgz
* Build Torch3vision: cp Linux_i686.cfg.vision2.1 Linux_i686.cfg
(Or on AMD 64: cp Linux_i686.cfg.vision2.1 Linux_x86_64.cfg )
* ./torch3make
* Build the vison examples for face detection: cd vision2.1/examples/facedetect/
../../../torch3make *.cc
Jetzt 3 Programme in neuen Unterverzeichnis ''Linux_i686_dbg_float'':
* haarscan - Schnelle, zuverlässige Erkennung
* mlpcascadescan - Sehr zuverlössige Erkennung, bei ganz kleinen Bildern geht es nicht richtig, grosse (>3MPixel) dauert lange.
* mlpscan - Seh keinen rechten Unterschied zum vorherigen.
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.
[[http://torch3vision.idiap.ch/examples2.0/|Source code of examples]]
Parmaters (as far as i found out):
* -minWsize n: min size n in pixel to recognize a face
* -nbest n : save the best n results only
* -dir -> directory to store ouput files [.]
* -savepos -> save pos file
* -draw -> draw ppm image with detections
* -savejpg -> save in jpeg instead of jpeg (jpeg ist wrong, should be ppm, but not working)
* -verbose: tell a little bit more what you doing...
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