An Area of Application of Computer Visio1
An Area of Application of Computer Visio1
In this post we present the possibility to locate, within the context of pictures,
human beings or their parts like faces, eyes, nose, and so on. This functionality
is available in the most advanced photo gallery applications, and it is currently in
the implementation phase as for social network applications. Once photos are
loaded, the system will scan them to search for people’s faces, will find them out
and will give a chance to associate a name. If, by chance, the same person is
present in different pictures, he/she is recognized and automatically “ registered
”, notwithstanding privacy concerns. This last functionality is the one we
previously cited as the one for identification or recognition.
In the model employed for the extraction of the features from the images, the
reference matrices have different shapes, such as the ones that can be seen in
figure, that are more suitable for determining the shapes belonging to the human
body, like the eyes or the nose. From this comes their denomination of Haar
Features, to distinguish them from their original meaning. The same picture
shows the shape of the features used by OpenCV and SimpleCV. The presence or
not of a Haar “ feature ” in a portion of the picture happens by subtracting the
median pixel value that are present in the black “ mask ” portion, from the
median value of the pixels that are present in the clear part of the “ mask ”. If
the difference is above a certain threshold value, the feature is considered as
present. The threshold value is determined, for each feature, during the function
training, to detect particular objects or parts of the human body. The learning
process materializes itself when “ presenting ” to the Vision System the highest
possible number of images concerning the “ objects ” family that we want to
identify, and the highest possible number of images that have nothing to share
with the object itself. From the amount of data that are “ studied ”, the threshold
values are calculated, for each of the features that, in the case of OpenCV and
SimpleCV, are memorized as a file in .xml format.
The portions of the picture that are analyzed are usually formed by 24×24 pixel
matrices, that have to be “ compared ” with all the expected features. Here a
first problem arises. By processing a 24×24 pixels matrix, something like more
than 160.000 features are obtained. The gentlemen mentioned before have
introduced a simplification in the calculation that is based on the integral image,
allowing to represent the whole matrix with just four pixels. Incidentally, this
method has been developped mathematically in 1984. You may expand your
knowledge on the method at thislink
The process consists in assigning to a certain pixel with a certain position
within the matrix (image) the sum of all the pixels that are there in the area
above and on the left of its position. Starting from the pixel up and on the left
and continuing to the right and downwards, the incremental calculation process
of the value for each pixel is definitely efficient.
Despite the simplification, the processing volume is still too big to be efficient.
The authors of the method noticed that certain features were more significant
than other ones, for the purpose of recognizing certain parts, e. g.: the eyes, but
were not at all significant to detect, e. g.: the cheeks. Some other features are
not at all significant. How to select the most significant features and discard the
other ones? It can be done by means of a mathematical algorithm for “ machine
learning ”, created to optimize the performances of other learning algorithms.
In extremely plain terms, that would horrify purists, its purpose is to research
the smallest possible set that would grant a given percentage (for example, 75%)
of accuracy as the result for detecting or discarding the required object. The
paper mentioned in the beginning shows that with 200 features it is possible to
obtain a degree of localization with an accuracy percentage of 95%.
For the sake of completeness and greater accuracy, the implementations of the
method employ about 6.000 features from the 160.000 initial ones. If we had
stopped here, for each 24×24 pixels matrix we should compare 6.000 features.
Still definitely too long.
apt-get update
apt-get upgrade
apt-get dist-upgrade
If your distribution is not really one of the latest, it will need some time to
complete the updates. In cases like this one, before starting it is always right to
perform a good:
reboot
Let’s install now the “ picamera ” library, purposely developed for the python
environment to interface Camera Pi. The documentation of the “ picamera ”
library, along with other useful information concerning the available
functionalities and Camera Pi’s running, can be found at the address:
http://picamera.readthedocs.org/en/release-1.5/
Let’s install the library, with the command:
/usr/local/lib/python2.7/dist-packages/SimpleCV/Features/HaarCascades/
We will now disclose a pair of warnings, just in case you’d run into some
problems. For the moment, do notice that the SimpleCV library is installed under
the python2.7 folder, therefore you have to make sure to be using this python
version to follow the examples. If you launch the examples under python3 you
will probably get some errors. Secondly, to reach the .xml file within the said
folder, the name is usually enough, e. g.: “ face ”, as indicated by the greatest
part of the examples that can be downloaded from Internet. If in this way you get
some errors, you need only to use the complete path. In our case we have found
that it works fine to name the “ Features ” with their extension, e. g.: “ face.xml
”. In the said folder we find the following files, that can be different in the case
you installed a SimpleCV version that is different from the 1.3 version that we
have installed:
?
1 #!/usr/bin/python2.7
2
# Programma test Haar Features
3
4
import picamera
5 from SimpleCV import Image
6 import time
7
8 with picamera.PiCamera() as camera:
9 camera.resolution = (640, 480)
camera.start_preview()
10 time.sleep(10)
11 camera.capture('foto.jpg')
12 foto=Image("foto.jpg")
13
14 print(foto.listHaarFeatures())
trovati=foto.findHaarFeatures('face.xml')
15
16
17 if trovati:
18 for trovato in trovati:
19 print "Trovato alle coordinate : " + str(trovato.coordinates())
trovato.draw()
20 else:
21 print "Non trovato"
22 camera.stop_preview()
23 foto.save('foto1.jpg')
24 foto.show()
25 time.sleep(10)
26
27
Just a small curiosity: in the SimpleCV version that we installed, the lefteye.xml
file has been written without underscore. Let’s remember this anomaly if we
have to recall it in the programs. To start, copy the program, as a file in the
/home folder. This program executes the following tasks:
Importing the picamera library to manage Camera Pi, directly from python
language;
Importing the Image function from the SimpleCV library and the “ time ”
function to manage the delays and let us “ see ” the images;
The “ with ” instruction allows a “ clean ” management of the resources it
is associated with, generally being external resources as our Camera Pi.
The resource is employed at the moment the instruction is executed, and
is properly released, be it at the time of the program termination or in the
case of its termination because of errors. The second part of the
instruction creates the “ camera ” item, as instance of the Picamera class,
supplied by the library we installed before;
Sets up the Camera Pi resolution;
Starts the “ preview ” of the picture taken by the video camera (do you
remember “ raspistill ”?);
“ Time sleep ” keeps the active preview for 10 seconds: this way we have
the time to place ourselves before the camera in a proper way. We may
also use photos or pictures from magazines. Try different alternatives. You
will convince yourself that probably this is not the best way to have your
home door open;
Capturing a photogram and saving it as a file;
Recalling the file as Image item to make it available for SimpleCV;
With the listHaarFeatures() function, we print to console the list of the
available “ Features ”;
We finally execute the research of the “ anatomic ” detail, indicated by the
corresponding “ Feature ” recalled in the function;
For each “ detail ” that has been determined, we print to console the
coordinates of the “ center ” of the detail, and highlight with a rectangle
the area where the detail is present;
At the end of the process, we interrupt the preview and save the image
with the recognized details being highlighted, then show it on video for 10
seconds.
By modifying the instructions of this simple program, we may experiment with
the whole range of the recognizable details and get an idea, from a practical
point of view, of the weight of the size of the framed picture, of the lighting
conditions and of the direction, for example, of the face in the picture. One thing
is to recognize a nose from a face taken in frontal position, while it is very
different to recognize a nose from the profile.
While you have your face being framed by the camera and recognized, you will
notice that even the face of your grandpa in the photo on the cupboard in the
small dining room is being recognized. For all these tests, you may always use
this program, by simply modifying the parameter of the findHaarFeatures()
function. We shall give some examples below.
In figure we see the recognition process console, as for the face in the picture.
Here you will see the detected face. Can you recognize it?
We shall use the program of Listing 1, with the lefteye.xml features, to recognize
the left eye and highlight it with a box.
trovati=foto.findHaarFeatures(‘lefteye.xml’)
In figure the result of the program is shown, with the nose.xml features.
trovati=foto.findHaarFeatures(‘nose.xml’)
The two_eyes_big.xml features allow us to locate the areas within the image
where both eyes are present.
trovati=foto.findHaarFeatures(‘two_eyes_big.xml’)
trovati=foto.findHaarFeatures(‘mouth.xml’)
In the case the program doesn’t detect the wanted detail, try with the alternative
Features: for example, in the case of the eyes, try two_eyes_small.xml. Modify
the program to acquire an already memorized image and search inside of it for
the details you’re looking for: full or medium shot, faces, eyes, ears, people with
glasses or not. To finish, we will propose another program, one that is a bit more
complex and that will allow you to memorize a face and verify if the faces that
are shown the following times are the same or not. A sort of “ human password ”
that could be used, for example, to allow or not the access to a place or a
computer. We recommend you to not use it, if not for fun or as a demonstration.
For the moment, the program is very simple and for demonstration purposes
only. It is “ trained ” with a single image that remains in jpeg format.
Consequently, to be recognized you need to be taken from a camera angle and
with a position that have to be very similar to the ones used for saving the
reference picture.
After having trained the program, try to have it “ recognize ” a photo depicting
yourself, or train it directly with the said photo. You will be surprised by the
behaviour of such a system. One thing is to consider teaching systems as the
ones we show, another one is the management of the security of accesses to
places and systems. This last one is a very serious matter, and has to be
managed with professional systems, that are projected and manufactured by
specialists in the field. Let’s see the program:
?
1 #!/usr/bin/python
2
import picamera
3
import time
4 from SimpleCV import Color, Image, np
5 import wiringpi2 as wiringpi
6
7 pin_base = 65
8 i2c_addr = 0x20
9
10 quality = 400 # Parametro "quality" per la funzione findKeypointMatch
11 minMatch = 0.3 # Parametro "minDist" per la funzione findKeypointMatch
12
try:
13 password = Image("password.jpg")
14 except:
15 password = None
16
17 mode = "unsaved"
18 saved = False
minDist = 0.25
19
20 wiringpi.wiringPiSetup()
21 wiringpi.mcp23017Setup(pin_base,i2c_addr)
22 wiringpi.pinMode(65, 1) # imposta GPA0 come output
23 wiringpi.digitalWrite(65, 0) # imposta GPA0 a 0 (0V, off)
24 wiringpi.pinMode(72, 1) # imposta GPA7 come output
wiringpi.digitalWrite(72, 0) # imposta GPA7 a 0 (0V, off)
25
26 with picamera.PiCamera() as camera:
27 while True:
28 camera.start_preview()
29 time.sleep(10)
camera.capture('pifacepw.jpg')
30 image=Image("pifacepw.jpg")
31 camera.stop_preview()
32 faces = image.findHaarFeatures("face.xml") # Riconosce il viso mediante il file Ha
33 if faces:
34 if not password:
faces.draw()
35 face = faces[-1]
36 password = face.crop().save("password.jpg")
37 print "Salvataggio volto di riferimento eseguito"
print "Termino il programma"
38
break
39 else:
40 faces.draw()
41 face = faces[-1]
42 template = face.crop()
template.save("passwordmatch.jpg")
43 keypoints = password.findKeypointMatch(template,quality,minDist,minMatch)
44 if keypoints:
45 print "Bentornato - mi sembri il viso giusto"
46 wiringpi.digitalWrite(65, 1)
47 wiringpi.digitalWrite(72, 0)
domanda = raw_input("Desideri utilizzare l'ultima foto come password?
48 if domanda == "Y":
49 image = cam.getImage().scale(320, 240)
50 faces = image.findHaarFeatures("face.xml")
51 tryit = 1
while not tryit == 10 or not faces:
52 image = cam.getImage().scale(320, 240)
53 faces = image.findHaarFeatures("face.xml")
54 tryit += 1
55 if not faces:
56 "Non trovo nessauna faccia"
break
57 else:
58 faces.draw()
59 face = faces[-1]
60 password = face.crop().save("password.jpg")
61 face.crop().show()
print "Salvataggio eseguito"
62 print "Termino il programma"
63 time.sleep(1)
64 break
65 else:
print "OK..."
66 break
67
68 else:
69 print "Non ti riconosco"
70 print "Attivo l'allarme"
71 wiringpi.digitalWrite(65, 0)
wiringpi.digitalWrite(72, 1)
72 break
73 else:
74 break
75
76
77
78
79
80
81
82
83
84
85
86
87
88
The shield requires a separate powering, with a voltage of 9V. The jumper for the
powering selection has to be plugged into the 5VR position (separate powering).
Let’s briefly summarize the operations that have to be performed for the
installation of the shield management software. As a first thing, “ free ” the i2C
management driver, by commenting it in the raspi-blacklist.conf placed in the
/etc/modprobe.d. folder. Perform then a “ reboot ”, to make the new configuration
effective. Give then the command to load the i2C bus management driver:
modprobe i2c-dev
Install the “ wiringpi2 ” library, with the command:
More or less, relays aside, this is the method that is used by the software for
archiving pictures that we mentioned in the article, to identify, give a name and
then recognize successively the framed characters in our pictures. Before the
conclusion, we present an examination of the keypoints that are mentioned by
the matching method used by the program in Listing. The keypoints are
significant points that allow us to “ register ” an image: they are calculated and
extracted by the findKeypoints() function.
?
1
#!/usr/bin/python
2
3 import time
4 from SimpleCV import Image, Color
5
6 immagine = Image("password.jpg")
7 keys = immagine.findKeypoints()
8 keys.draw(color=Color.BLUE)
immagine.show()
9 immagine.save('foto_2.jpg')
10 time.sleep(10)
11
You may have fun experimenting with the results of this function by launching
the program in Listing and changing the filename. Use them with the “
password.jpg ” and “ passwordmatch.jpg ” images. Do they correspond?
That’s all, for now! Hopefully we managed to communicate the complexity of the
topic: identifying items, and especially details of human bodies, it’s no easy task.
All this have been made easy thanks to a deep research for algorithms and
image processing methods.