Exam Project Part One
In the previous article we saw a little library to semplify my work, today I’m going to talk about a software that allows to track any color and at the same time tell other softwares which colour we have chosen
The software we talk about is this:
/*
# This file is part of Computer Vision Exam Project
#
# Copyright(c) 2012 Domenico Luciani
# [email protected]
#
#
# This file may be licensed under the terms of of the
# GNU General Public License Version 3 (the ``GPL'').
#
# Software distributed under the License is distributed
# on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
# express or implied. See the GPL for the specific language
# governing rights and limitations.
#
# You should have received a copy of the GPL along with this
# program. If not, go to http://www.gnu.org/licenses/gpl.html
# or write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cv.h>
#include <highgui.h>
#include "../lib/funzioni.h"
//File di configurazione
#define FILE_CONFIG "config.txt"
//Nomi delle GUI
#define NORMAL "Calibra"
#define BINARY "Calibra - Binaria"
int main(int argc,char *argv[])
{
int web;
//Controllo se i parametri sono corretti
if(argc != 2)
printf("usage: %s <mode>\n0 - integrate webcam\n1 - external webcam",argv[0]);
else
{
web = atoi(argv[1]);
if(web >= 0 && web <= 1)
{
//Inizializzo la webcam
CvCapture *capt = cvCaptureFromCAM(web);
//Setto le proprietà della webcam a 640x480
cvSetCaptureProperty(capt,CV_CAP_PROP_FRAME_WIDTH,640);
cvSetCaptureProperty(capt,CV_CAP_PROP_FRAME_HEIGHT,480);
//Prendo il primo frame dalla webcam e lo salvo
IplImage *imm = cvQueryFrame(capt);
//Creo immagini
IplImage *hsv = cvCreateImage(cvGetSize(imm),8,3);
IplImage *binary = cvCreateImage(cvGetSize(imm),8,1);
//Variabili varie
int i,j,step = binary->widthStep/sizeof(uchar);
uchar *target = (uchar*)binary->imageData;
char tasto;
//Alloco spazio per i valori HSV
HSV *low = (HSV*)malloc(sizeof(HSV));
HSV *high = (HSV*)malloc(sizeof(HSV));
//Alloco spazio per il rettangolo
Rettangolo *punti = (Rettangolo*)malloc(sizeof(Rettangolo));
//Leggo i dati dal file di configurazione
leggiConfig(low,high,(char*)FILE_CONFIG);
//Creo le GUI
cvNamedWindow(NORMAL,CV_WINDOW_AUTOSIZE);
cvNamedWindow(BINARY,CV_WINDOW_AUTOSIZE);
//Ciclo while che si occuperà di prendere i frame
while(imm)
{
//Creo le trackbar
cvCreateTrackbar("HMIN",NORMAL,&low->H,255,NULL);
cvCreateTrackbar("SMIN",NORMAL,&low->S,255,NULL);
cvCreateTrackbar("VMIN",NORMAL,&low->V,255,NULL);
cvCreateTrackbar("HMAX",NORMAL,&high->H,255,NULL);
cvCreateTrackbar("SMAX",NORMAL,&high->S,255,NULL);
cvCreateTrackbar("VMAX",NORMAL,&high->V,255,NULL);
//Ruoto l'immagine
cvFlip(imm,imm,1);
//Converto in hsv
cvCvtColor(imm,hsv,CV_BGR2HSV);
//cerco il colore
cvInRangeS(hsv,cvScalar(low->H,low->S,low->V),cvScalar(high->H,high->S,high->V),binary);
//Riduco i disturbi
riduciNoise(binary,binary);
//Resetto il rettangolo
*punti = {10000,0,10000,0};
//Controllo pixel per pixel
for(i=0; i < binary->height; i++)
{
for(j=0; j < binary->width; j++)
{
if(target[i*step+j] == 255)
{
//I punti del nostro rettangolo
if(j < punti->xmin)
punti->xmin = j;
if(j > punti->xmax)
punti->xmax = j;
if(i < punti->ymin)
punti->ymin = i;
if(i > punti->ymax)
punti->ymax = i;
}
}
}
//Creo il rettangolo
cvRectangle(imm,cvPoint(punti->xmin,punti->ymin),cvPoint(punti->xmax,punti->ymax),CV_RGB(255,0,0),2,8,0);
//Creo il baricentro
cvCircle(imm,cvPoint((punti->xmin+punti->xmax)/2,(punti->ymin+punti->ymax)/2),2,CV_RGB(0,0,255),-1,CV_AA,0);
//Mostro le GUI
cvShowImage(NORMAL,imm);
cvShowImage(BINARY,binary);
//Aspetto 15 millisecondi
tasto = cvWaitKey(15);
switch(tasto)
{
//Se premo 'q' esco
case 'q':
return 2;
break;
case 's':
//Se premo 's' salvo i dati che mi servono
scriviConfig(low,high,(char*)FILE_CONFIG);
break;
}
//Prendo un altro frame
imm = cvQueryFrame(capt);
}
//Libero tutto ciò che ho allocato in precedenza
cvReleaseImage(&imm);
cvReleaseImage(&binary);
cvReleaseImage(&hsv);
cvReleaseCapture(&capt);
}
else
puts("webcam not found");
}
return 0;
}
it is in the config
directory called calibra.c
- I start included the OpenCV libraries like
cv.h
,highgui.h
and apart my libraryfunzioni.h
- I define where we can find the configuration file, the name of the GUI where we are going to show the frame taken from the webcam and the name of the GUI where we are going to show the binary result of the taken values.
- I check if I inserted the right parameters to know which webcam we want to use.
- I initialize the webcam with the function
cvCaptureFromCAM
specifying with parameter0
for the internal webcam and1
for the external one. - I set the property of the webcam using as dimensions
640×480
. - I take the first frame and set it into
imm
- I create an image HSV where I am going to save the converted image in HSV with the same size of
imm
. - I create an image where I am going to save the binary image that we will found
- I take the
step
of the binary image, thewidthStep
field that tell the number of bytes between the start of every pixels row. - After that we have
target
, the real pixels of the image. - I need to cast as
unsigned char
the variable because as default is achar*
and we need anunsigned char
. - I define a
tasto
variable that I use to hook the input of the user. - I alloc 2 pointers to the
HSV
structure and one pointer to theRettangolo
structure. - I take the values from the configuration file and set it in
low
andhigh
- I create 2 GUI
- Now I loop until
false
- I create some trackbars that allows the user to interact to see changes in real time
- 6 trackbrs, each of them are going to manage the mininum and maximum value of
H
,S
,V
we want to analyze - The values are between 0 and 255 and the trackbar will be on he
NORMAL
GUI. - I rotate the frame
- I convert the image from
BGR
toHSV
and I insert the converted image inHSV
. - The function
cvInRangeS
is a filter function - Using the maximum and minimum values I am able to create a binary image with white pixels as ROI abd black the rest
- I reduce the noises on the binary image
- Now I want to find the white region to follows the colour, to do that I need to do a search over every pixel that make the image: if I find a white pixel I save the points of vertices of our rectangle
- With the
cvRectangle
function I draw a red rectangle inimm
- With the
cvCircle
function I draw a blue center of gravity of the our rectangle. - After that I show the GUIs with the our frame (with draws) and the binary image I found
- With the
cvWaitKey
I wait15ms
to allows to check if a key was press, using the switch/case I check:q
key -> exit ;s
key -> I write the datas taken on the configuation file to allows other software to know which colour they have to follow. - I take another frame and restart
Here a screenshot:
As we can see the red rectangle is only around the colour we have choose.