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
|
IplImage *image;
// Position of the object we overlay
CvPoint objectPos = cvPoint(-1, -1);
// Color tracked and our tolerance towards it
int h = 30, s = 150, v = 255, tolerance = 10;
CvPoint binarisation(IplImage* image, int *nbPixels) {
int x, y;
CvScalar pixel;
IplImage *hsv, *mask;
IplConvKernel *kernel;
int sommeX = 0, sommeY = 0;
*nbPixels = 0;
// Create the mask &initialize it to white (no color detected)
mask = cvCreateImage(cvGetSize(image), image->depth, 1);
// Create the hsv image
hsv = cvCloneImage(image);
cvCvtColor(image, hsv, CV_BGR2HSV);
// We create the mask
cvInRangeS(hsv, cvScalar(h - tolerance -1, s - tolerance, 0), cvScalar(h + tolerance -1, s + tolerance, 255), mask);
//cvInRangeS(hsv, cvScalar(5, 100, 255), cvScalar(15, 200, 255), mask);
// Create kernels for the morphological operation
kernel = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE);
// Morphological opening (inverse because we have white pixels on black background)
cvDilate(mask, mask, kernel, 1);
cvErode(mask, mask, kernel, 1);
// We go through the mask to look for the tracked object and get its gravity center
for(x = 0; x < mask->width; x++) {
for(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)++;
}
}
}
// Show the result of the mask image
cvShowImage("GeckoGeek Mask", mask);
// We release the memory of kernels
cvReleaseStructuringElement(&kernel);
// We release the memory of the mask
cvReleaseImage(&mask);
// We release the memory of the hsv image
cvReleaseImage(&hsv);
// 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;
CvPoint objectPos = cvPoint(-1, -1) ;
// 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 camera 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("GeckoGeek Color Tracking", image);
}
void getObjectColor(int event, int x, int y, int flags, void *param) {
// Vars
CvScalar pixel;
IplImage* hsv= NULL;
if(event == CV_EVENT_LBUTTONUP) {
//Get the hsv image
//hsv = cvCloneImage(image);
//cvCvtColor(image, hsv, CV_BGR2HSV);
// Get the selected pixel
pixel = cvGet2D(hsv, y, x);
// Change the value of the tracked color with the color of the selected pixel
h = (int)pixel.val[0];
s = (int)pixel.val[1];
v = (int)pixel.val[2];
// Release the memory of the hsv image
cvReleaseImage(&hsv);
}
} |
Partager