OBJETIVOS ESPECIFICOS:
1 MARCO TEÓRICO
1.4 ENSAYOS DE TOXICIDAD O BIOENSAYOS
WITH OPENCV
You’ve got a Raspberry Pi Camera Module? You’ve taken a few images?
Let’s do something really clever and use them to detect faces…
ou’ve set up your motion-triggered webcam, but that pesky dog keeps triggering it. How do you figure out if that alert is someone poking around or Fido searching for socks again? In this tutorial, we’ll show you how to get your Raspberry Pi to separate the dogs from the faces, using the computer vision library, OpenCV.
We’re going to make a simple Python script that will work its way through a directory of pictures, copying the ones that have faces in them. Not only that, it’ll also draw a box around each face.
>STEP-01
Install OpenCV
By default, OpenCV isn’t shipped with Raspbian. Never fear – everything is a simple apt-get away. First, we need to install OpenCV. In a terminal, type: sudo apt-get update, press ENTER, then: sudo-apt-get install python-opencv libopencv-dev and follow the instructions. We’ll see if it’s installed correctly by running the Python interactive interpreter and loading the OpenCV module. Type: python (and ENTER), then import cv (and ENTER again). If everything is installed correctly, you should see an empty prompt. If you see something along the lines of ImportError, go back and see if the apt-get worked correctly.
>STEP-02
Understanding Haar-like features
We’re going to use an algorithm called a ‘Haar cascade’. Because computers have no understanding of what a face looks like, we have to give it a rule book. In this case, a Haar cascade describes the ‘brightness signature’. A face contains two eyes surrounded by skin. The area surrounding the eye is a different intensity to the eye itself. A Haar cascade describes these patterns to provide us with a way to detect faces (and other objects).
>STEP-03
Begin the code!
Enough chit-chat! Let’s write some code. We need to import the various libraries we are going to use and set some sensible defaults for the Haar detector. These defaults provide a trade-off between speed and accuracy. First, we set minSize to limit the smallest detectable face to a 20-pixel square. imageScale scales the image before we feed it into the detector; smaller
Y
> An internet connection > Camera Module (or webcam) > OpenCVYou’ll
Need
WILLEM KOOPMAN
Peripatetic sysadmin, providing grumpy solutions to grumpy problems; also maker of whatcaniseefromtheshard.com. Stumbled upon the field of computer vision while working in the magical world of visual effects.
secretbatcave.co.uk
Tutorial
raspberrypi.org/magpi The Official Raspberry Pi Projects Book 93
FACE DETECTION
import os, sys, time
import cv2.cv as cv minSize = (20, 20) imageScale = 1 haarScale = 2 minNeighbors = 3 haarFlags = cv.CV_HAAR_DO_CANNY_PRUNING
def detectFace(img, cascade): # allocate temporary images
gray = cv.CreateImage((img.width,img.height), 8, 1) small_img = cv.CreateImage((cv.Round(img.width /
imageScale),cv.Round (img.height / imageScale)), 8, 1) # convert color input image to grayscale
cv.CvtColor(img, gray, cv.CV_BGR2GRAY) # scale input image for faster processing
cv.Resize(gray, small_img, cv.CV_INTER_LINEAR) cv.EqualizeHist(small_img, small_img)
faces = cv.HaarDetectObjects(small_img, cascade,
cv.CreateMemStorage(0),haarScale, minNeighbors, haarFlags, minSize) if faces:
print"\tDetected ", len(faces), " object(s)"
for ((x, y, w, h), n) in faces:
#the input to cv.HaarDetectObjects was resized, scale the #bounding box of each face and convert it to two CvPoints
pt1 = (int(x * imageScale), int(y * imageScale)) pt2 = (int((x + w) * imageScale), int((y + h) *
imageScale))
cv.Rectangle(img, pt1, pt2, cv.RGB(255, 0, 0), 3, 8, 0) return img
else:
return False
# scan all directories and subdirectories for jpg images
def readDirectory(fileLocation, cascade): for root, dirs, files in os.walk(fileLocation): print root, "has:"
for name in files:
if name.find(".jpg") >=1 :
#sequentially loop, load and detect.
print"Analysing " + name +":"
#measure how long it takes
t = cv.GetTickCount() #load in the image
image = cv.LoadImage(os.path.join(root,name), 1) match = detectFace(image, cascade)
if match:
#save a new image with a box round each face
cv.SaveImage( fileLocation + "/face_" + name, match) t = cv.GetTickCount() -t
print"\tTime = %gms" %(t/(cv.GetTickFrequency()*1000.0))
if __name__ == '__main__':
cdir = "/usr/share/opencv/haarcascades/"
cascade = cv.Load(cdir + "haarcascade_frontalface_default.xml") if len(sys.argv) != 2:
print'please provide a directory to read'
sys.exit(1)
readDirectory(sys.argv[1], cascade)
Facedetect.py
CodeLanguage
>PYTHON
images mean faster detect times, but less accuracy. minNeighbors tells the detector that a match must be made up of a minimum number. Finally, haarFlags are special flags telling the detector what bits to ignore.
>STEP-04
Prepare the image
The first function we’re going to create is detectFace(). Because the Haar detector only works with greyscale images, we make a greyscale copy; grey is resized and copied into the small_img container. Lastly, we equalise the histogram (using EqualizeHist). This evens out the contrast, making the Haar detector more effective. We pass the variables, small_img and cascade, along with the rest of the defaults we defined at the very start, into the function cv.HaarDetectObjects. It then spits out a list of objects, with attached coordinates, and dumps it into the variable faces.
>STEP-05
Mark the faces
We then ‘iterate’ through all the objects and extract the ‘bounding box’ (the area where the object detector thinks there is a face.) Now, this is where we do something vaguely confusing. Remember in the previous step, we made a few copies of the original image? Well, we didn’t throw away the original. We can mark where we think the faces are on the original, so that we can save full-sized images in full colour!
We’ve scaled up the coordinates so that we can accurately tell cv.Rectangle where the top-left and bottom-right corners of the box should be.
>STEP-06
Final touches
readDirectory() goes through the directory supplied as a command-line argument and extracts files ending with ‘.jpg’. It then opens the image and passes it to detectFace(). If it finds some faces, it’ll save out the marked images into a new file using cv.SaveImage(). To use your new program, you first need to find a Haar cascade XML file and put the path into cv.Load(). They can be found in /usr/share/opencv/haarcascades/. Running the program is as simple as storing some JPG files in the folder and typing python facedetect.py. With any luck, you’ll see something like the following: samples/ has:
Analysing 292942_10151131251926133.jpg: Detected 2 object(s)
Time = 1268.761ms
Above How the face detector works under the hood: high-contrast boxes are mapped to parts of the face