ElfikCo

CamShift - ICK4

Jan 17th, 2021 (edited)
234
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifdef _CH_
  2. #pragma package <opencv>
  3. #endif
  4.  
  5. #define CV_NO_BACKWARD_COMPATIBILITY
  6.  
  7. #ifndef _EiC
  8. #include "cv.h"
  9. #include "highgui.h"
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #endif
  13.  
  14. IplImage* image = 0, * hsv = 0, * hue = 0, * mask = 0, * backproject = 0, * histimg = 0, * tracker;
  15. CvHistogram* hist = 0;
  16.  
  17. int backproject_mode = 0;
  18. int select_object = 0;
  19. int track_object = 0;
  20. int show_hist = 1;
  21. CvPoint origin;
  22. CvRect selection;
  23. CvRect track_window;
  24. CvBox2D track_box;
  25. CvConnectedComp track_comp;
  26. int hdims = 16;
  27. float hranges_arr[] = { 0,180 };
  28. float* hranges = hranges_arr;
  29. int vmin = 10, vmax = 256, smin = 30;
  30.  
  31. void on_mouse(int event, int x, int y, int flags, void* param)
  32. {
  33.     if (!image)
  34.         return;
  35.  
  36.     if (image->origin)
  37.         y = image->height - y;
  38.  
  39.     if (select_object)
  40.     {
  41.         selection.x = MIN(x, origin.x);
  42.         selection.y = MIN(y, origin.y);
  43.         selection.width = selection.x + CV_IABS(x - origin.x);
  44.         selection.height = selection.y + CV_IABS(y - origin.y);
  45.  
  46.         selection.x = MAX(selection.x, 0);
  47.         selection.y = MAX(selection.y, 0);
  48.         selection.width = MIN(selection.width, image->width);
  49.         selection.height = MIN(selection.height, image->height);
  50.         selection.width -= selection.x;
  51.         selection.height -= selection.y;
  52.     }
  53.  
  54.     switch (event)
  55.     {
  56.     case CV_EVENT_LBUTTONDOWN:
  57.         origin = cvPoint(x, y);
  58.         selection = cvRect(x, y, 0, 0);
  59.         select_object = 1;
  60.         break;
  61.     case CV_EVENT_LBUTTONUP:
  62.         select_object = 0;
  63.         if (selection.width > 0 && selection.height > 0)
  64.             track_object = -1;
  65.         break;
  66.     }
  67. }
  68.  
  69.  
  70. CvScalar hsv2rgb(float hue)
  71. {
  72.     int rgb[3], p, sector;
  73.     static const int sector_data[][3] =
  74.     { {0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2} };
  75.     hue *= 0.033333333333333333333333333333333f;
  76.     sector = cvFloor(hue);
  77.     p = cvRound(255 * (hue - sector));
  78.     p ^= sector & 1 ? 255 : 0;
  79.  
  80.     rgb[sector_data[sector][0]] = 255;
  81.     rgb[sector_data[sector][1]] = 0;
  82.     rgb[sector_data[sector][2]] = p;
  83.  
  84.     return cvScalar(rgb[2], rgb[1], rgb[0], 0);
  85. }
  86.  
  87. int main(int argc, char** argv)
  88. {
  89.     CvCapture* capture = 0;
  90.     CvPoint* points = malloc(1);
  91.     int size = 1;
  92.     CvScalar track_color;
  93.  
  94.     if (argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
  95.         capture = cvCaptureFromCAM(argc == 2 ? argv[1][0] - '0' : 0);
  96.     else if (argc == 2)
  97.         capture = cvCaptureFromAVI(argv[1]);
  98.  
  99.     if (!capture)
  100.     {
  101.         fprintf(stderr, "Could not initialize capturing...\n");
  102.         return -1;
  103.     }
  104.  
  105.     printf("Hot keys: \n"
  106.         "\tESC - quit the program\n"
  107.         "\tc - stop the tracking\n"
  108.         "\tb - switch to/from backprojection view\n"
  109.         "\th - show/hide object histogram\n"
  110.         "To initialize tracking, select the object with mouse\n");
  111.  
  112.     cvNamedWindow("Histogram", 1);
  113.     cvNamedWindow("CamShiftDemo", 1);
  114.     cvNamedWindow("Tracker", 1);
  115.     cvSetMouseCallback("CamShiftDemo", on_mouse, 0);
  116.     cvCreateTrackbar("Vmin", "CamShiftDemo", &vmin, 256, 0);
  117.     cvCreateTrackbar("Vmax", "CamShiftDemo", &vmax, 256, 0);
  118.     cvCreateTrackbar("Smin", "CamShiftDemo", &smin, 256, 0);
  119.  
  120.     for (;;)
  121.     {
  122.         IplImage* frame = 0;
  123.         int i, bin_w, c;
  124.  
  125.         frame = cvQueryFrame(capture);
  126.         if (!frame)
  127.             break;
  128.  
  129.         if (!image)
  130.         {
  131.             /* allocate all the buffers */
  132.             image = cvCreateImage(cvGetSize(frame), 8, 3);
  133.             image->origin = frame->origin;
  134.             hsv = cvCreateImage(cvGetSize(frame), 8, 3);
  135.             hue = cvCreateImage(cvGetSize(frame), 8, 1);
  136.             mask = cvCreateImage(cvGetSize(frame), 8, 1);
  137.             backproject = cvCreateImage(cvGetSize(frame), 8, 1);
  138.             hist = cvCreateHist(1, &hdims, CV_HIST_ARRAY, &hranges, 1);
  139.             histimg = cvCreateImage(cvSize(320, 200), 8, 3);
  140.             cvZero(histimg);
  141.             tracker = cvCreateImage(cvGetSize(frame), 8, 3);
  142.         }
  143.  
  144.         cvCopy(frame, image, 0);
  145.         cvCvtColor(image, hsv, CV_BGR2HSV);
  146.  
  147.         if (track_object)
  148.         {
  149.             int _vmin = vmin, _vmax = vmax;
  150.  
  151.             cvInRangeS(hsv, cvScalar(0, smin, MIN(_vmin, _vmax), 0),
  152.                 cvScalar(180, 256, MAX(_vmin, _vmax), 0), mask);
  153.             cvSplit(hsv, hue, 0, 0, 0);
  154.  
  155.             if (track_object < 0)
  156.             {
  157.                 float max_val = 0.f;
  158.                 cvSetImageROI(hue, selection);
  159.                 cvSetImageROI(mask, selection);
  160.                 cvCalcHist(&hue, hist, 0, mask);
  161.                 cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0);
  162.                 cvConvertScale(hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0);
  163.                 cvResetImageROI(hue);
  164.                 cvResetImageROI(mask);
  165.                 track_window = selection;
  166.                 track_object = 1;
  167.  
  168.                 cvZero(histimg);
  169.                 bin_w = histimg->width / hdims;
  170.                 for (i = 0; i < hdims; i++)
  171.                 {
  172.                     int val = cvRound(cvGetReal1D(hist->bins, i) * histimg->height / 255);
  173.                     CvScalar color = hsv2rgb(i * 180.f / hdims);
  174.                     if (val == 200) {
  175.                         track_color = color;
  176.                     }
  177.                     cvRectangle(histimg, cvPoint(i * bin_w, histimg->height),
  178.                         cvPoint((i + 1) * bin_w, histimg->height - val),
  179.                         color, -1, 8, 0);
  180.                 }
  181.             }
  182.  
  183.             cvCalcBackProject(&hue, backproject, hist);
  184.             cvAnd(backproject, mask, backproject, 0);
  185.             cvMeanShift(backproject, track_window,
  186.                 cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1),
  187.                 &track_comp, &track_box);
  188.  
  189.             double x = track_window.width / 2;
  190.             double y = track_window.height / 2;
  191.  
  192.             points[size - 1] = cvPoint(track_window.x + x, track_window.y + y);
  193.  
  194.             size++;
  195.             points = realloc(points, size * sizeof(CvPoint));
  196.  
  197.             int j;
  198.             for (j = 1; j < size; j++) {
  199.                 cvLine(tracker, points[j], points[j], track_color, 5, 4, 0);
  200.             }
  201.  
  202.             track_window = track_comp.rect;
  203.  
  204.             if (backproject_mode)
  205.                 track_box.angle = -track_box.angle;
  206.             cvEllipseBox(image, track_box, CV_RGB(255, 0, 0), 3, CV_AA, 0);
  207.             //cvRectangle(image, cvPoint(track_window.x, track_window.y),
  208.             //    cvPoint(track_window.x + track_window.width, track_window.y + track_window.height), CV_RGB(0, 0, 255), 3, CV_AA, 0);
  209.         }
  210.  
  211.         if (select_object && selection.width > 0 && selection.height > 0)
  212.         {
  213.             cvSetImageROI(image, selection);
  214.             cvXorS(image, cvScalarAll(255), image, 0);
  215.             cvResetImageROI(image);
  216.         }
  217.  
  218.         cvShowImage("CamShiftDemo", image);
  219.         cvShowImage("Histogram", histimg);
  220.         cvShowImage("Tracker", tracker);
  221.  
  222.         c = cvWaitKey(10);
  223.         if ((char)c == 27)
  224.             break;
  225.         switch ((char)c)
  226.         {
  227.         case 'b':
  228.             backproject_mode ^= 1;
  229.             break;
  230.         case 'c':
  231.             track_object = 0;
  232.             cvZero(histimg);
  233.             break;
  234.         case 'h':
  235.             show_hist ^= 1;
  236.             if (!show_hist)
  237.                 cvDestroyWindow("Histogram");
  238.             else
  239.                 cvNamedWindow("Histogram", 1);
  240.             break;
  241.         default:
  242.             ;
  243.         }
  244.     }
  245.  
  246.     cvReleaseCapture(&capture);
  247.     cvDestroyWindow("CamShiftDemo");
  248.     cvDestroyWindow("Tracker");
  249.  
  250.     return 0;
  251. }
  252.  
  253. #ifdef _EiC
  254. main(1, "camshiftdemo.c");
  255. #endif
  256.  
RAW Paste Data