1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#include "traitement.h"
int h = 0;
int s = 0;
CvPoint objectPos = cvPoint (-1, -1);
IplImage *img;
void trackColor (unsigned char* buffer, int width, int height)
{
int nbPixels;
const int channel = 3;
CvPoint objectNextPos;
img = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, channel);
for (int i=0;i<channel*width*height;i+=channel)
{
img->imageData[i] = buffer[i+2];
img->imageData[i+1] = buffer[i+1];
img->imageData[i+2] = buffer[i];
}
objectNextPos = binarization (img, &nbPixels);
addObjectToVideo (img, objectNextPos, nbPixels);
}
CvPoint binarization (IplImage* img_orig, int* nbPixels)
{
int tolerance = 10;
const int ROWS_KERNEL = 5;
const int COLS_KERNEL = 5;
const int ANCHOR_X_KERNEL = 2;
const int ANCHOR_Y_KERNEL = 2;
const int CHANNEL_HSV = 3;
const int CHANNEL_MASK = 1;
int sommeX = 0;
int sommeY = 0;
IplConvKernel* kernel;
*nbPixels = 0;
/* Convert BGR image to a HSV image */
IplImage* img_hsv = cvCreateImage (cvGetSize (img_orig), img_orig->depth, CHANNEL_HSV);
cvCvtColor (img_orig, img_hsv, CV_BGR2HSV);
/* Binarization of the HSV image */
IplImage* mask = cvCreateImage (cvGetSize (img_hsv), img_hsv->depth, CHANNEL_MASK);
/*
* We take a group of pixels around an HSV color without taking the V, in order to ignore the lighting
* We therefore use a tolerance value for the color, such that we take a set of pixels with colors in the specified interval. The formula is:
* H studied pixel <= H color chosen +/- tolerance
* and S studied pixel <= S color chosen +/- tolerance
*/
cvInRangeS (img_hsv, cvScalar (h - tolerance - 1, s - tolerance), cvScalar (h + tolerance - 1, s + tolerance, 255), mask);
/* We created a core elliptical with 5x5 */
kernel = cvCreateStructuringElementEx (COLS_KERNEL, ROWS_KERNEL, ANCHOR_X_KERNEL, ANCHOR_Y_KERNEL, CV_SHAPE_ELLIPSE);
/* Dilation to build dense groups of pixels of our object */
cvDilate (mask, mask, kernel);
/* Erosion to remove isolated pixels that do not correspond to our object */
cvErode (mask, mask, kernel);
/* We go through the mask to look for the tracked object and get its gravity center */
for (int x=0;x<mask->width;x++)
{
for (int y=0;y<mask->height;y++)
{
/* If its a tracked pixel, count it to the center of gravity's calcul */
if (((uchar *)(mask->imageData + y*mask->widthStep))[x] == 255)
{
sommeX += x;
sommeY += y;
(*nbPixels)++;
}
}
}
cvShowImage("mask", mask);
cvReleaseStructuringElement (&kernel);
cvReleaseImage (&img_hsv);
cvReleaseImage (&mask);
/* If there is no pixel, we return a center outside the image, else we return the center of gravity */
if (*nbPixels > 0)
{
return cvPoint ((int)(sommeX / (*nbPixels)), (int)(sommeY / (*nbPixels)));
}
else
{
return cvPoint (-1, -1);
}
}
void addObjectToVideo (IplImage* image, CvPoint objectNextPos, int nbPixels)
{
int objectNextStepX, objectNextStepY;
/* Calculate circle next position (if there is enough pixels) */
if (nbPixels > 10)
{
/* Reset position if no pixel were found */
if (objectPos.x == -1 || objectPos.y == -1)
{
objectPos.x = objectNextPos.x;
objectPos.y = objectNextPos.y;
}
/* Move step by step the object position to the desired position */
if (abs (objectPos.x - objectNextPos.x) > STEP_MIN)
{
objectNextStepX = max (STEP_MIN, min (STEP_MAX, abs(objectPos.x - objectNextPos.x) / 2));
objectPos.x += (-1) * sign (objectPos.x - objectNextPos.x) * objectNextStepX;
}
if (abs (objectPos.y - objectNextPos.y) > STEP_MIN)
{
objectNextStepY = max (STEP_MIN, min (STEP_MAX, abs (objectPos.y - objectNextPos.y) / 2));
objectPos.y += (-1) * sign (objectPos.y - objectNextPos.y) * objectNextStepY;
}
/* -1 = object isn't within the picture range */
}
else
{
objectPos.x = -1;
objectPos.y = -1;
}
/* Draw an object (circle) centered on the calculated center of gravity */
if (nbPixels > 10)
{
cvDrawCircle (image, objectPos, 15, CV_RGB (255, 0, 0), -1);
}
/* We show the image on the window */
cvShowImage ("img", image);
}
void getObjectColor(int event, int x, int y, int flags, void *param)
{
FILE *fichier = fopen ("test.txt", "r");
FILE *fichier2 = fopen ("test2.txt", "w");
int hs[2];
if (fichier != NULL && fichier2 != NULL)
{
fscanf (fichier, "%d %d", &hs[0], &hs[1]);
fprintf (fichier2, "h:%d s:%d", hs[0], hs[1]);
fclose (fichier);
fclose (fichier2);
}
h = hs[0];
s = hs[1];
}
} |
Partager