Home | History | Annotate | Download | only in tapi
      1 #include "opencv2/core/utility.hpp"
      2 #include "opencv2/core/ocl.hpp"
      3 #include "opencv2/video/tracking.hpp"
      4 #include "opencv2/imgproc/imgproc.hpp"
      5 #include "opencv2/videoio/videoio.hpp"
      6 #include "opencv2/highgui/highgui.hpp"
      7 
      8 #include <iostream>
      9 #include <cctype>
     10 
     11 static cv::UMat image;
     12 static bool backprojMode = false;
     13 static bool selectObject = false;
     14 static int trackObject = 0;
     15 static bool showHist = true;
     16 static cv::Rect selection;
     17 static int vmin = 10, vmax = 256, smin = 30;
     18 
     19 static void onMouse(int event, int x, int y, int, void*)
     20 {
     21     static cv::Point origin;
     22 
     23     if (selectObject)
     24     {
     25         selection.x = std::min(x, origin.x);
     26         selection.y = std::min(y, origin.y);
     27         selection.width = std::abs(x - origin.x);
     28         selection.height = std::abs(y - origin.y);
     29 
     30         selection &= cv::Rect(0, 0, image.cols, image.rows);
     31     }
     32 
     33     switch (event)
     34     {
     35     case cv::EVENT_LBUTTONDOWN:
     36         origin = cv::Point(x, y);
     37         selection = cv::Rect(x, y, 0, 0);
     38         selectObject = true;
     39         break;
     40     case cv::EVENT_LBUTTONUP:
     41         selectObject = false;
     42         if (selection.width > 0 && selection.height > 0)
     43             trackObject = -1;
     44         break;
     45     default:
     46         break;
     47     }
     48 }
     49 
     50 static void help()
     51 {
     52     std::cout << "\nThis is a demo that shows mean-shift based tracking using Transparent API\n"
     53             "You select a color objects such as your face and it tracks it.\n"
     54             "This reads from video camera (0 by default, or the camera number the user enters\n"
     55             "Usage: \n"
     56             "   ./camshiftdemo [camera number]\n";
     57 
     58     std::cout << "\n\nHot keys: \n"
     59             "\tESC - quit the program\n"
     60             "\ts - stop the tracking\n"
     61             "\tb - switch to/from backprojection view\n"
     62             "\th - show/hide object histogram\n"
     63             "\tp - pause video\n"
     64             "\tc - use OpenCL or not\n"
     65             "To initialize tracking, select the object with mouse\n";
     66 }
     67 
     68 int main(int argc, const char ** argv)
     69 {
     70     help();
     71 
     72     cv::VideoCapture cap;
     73     cv::Rect trackWindow;
     74     int hsize = 16;
     75     float hranges[2] = { 0, 180 };
     76 
     77     const char * const keys = { "{@camera_number| 0 | camera number}" };
     78     cv::CommandLineParser parser(argc, argv, keys);
     79     int camNum = parser.get<int>(0);
     80 
     81     cap.open(camNum);
     82 
     83     if (!cap.isOpened())
     84     {
     85         help();
     86 
     87         std::cout << "***Could not initialize capturing...***\n";
     88         std::cout << "Current parameter's value: \n";
     89         parser.printMessage();
     90 
     91         return EXIT_FAILURE;
     92     }
     93 
     94     cv::namedWindow("Histogram", cv::WINDOW_NORMAL);
     95     cv::namedWindow("CamShift Demo", cv::WINDOW_NORMAL);
     96     cv::setMouseCallback("CamShift Demo", onMouse);
     97     cv::createTrackbar("Vmin", "CamShift Demo", &vmin, 256);
     98     cv::createTrackbar("Vmax", "CamShift Demo", &vmax, 256);
     99     cv::createTrackbar("Smin", "CamShift Demo", &smin, 256);
    100 
    101     cv::Mat frame, histimg(200, 320, CV_8UC3, cv::Scalar::all(0));
    102     cv::UMat hsv, hist, hue, mask, backproj;
    103     bool paused = false;
    104 
    105     for ( ; ; )
    106     {
    107         if (!paused)
    108         {
    109             cap >> frame;
    110             if (frame.empty())
    111                 break;
    112         }
    113 
    114         frame.copyTo(image);
    115 
    116         if (!paused)
    117         {
    118             cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
    119 
    120             if (trackObject)
    121             {
    122                 int _vmin = vmin, _vmax = vmax;
    123 
    124                 cv::inRange(hsv, cv::Scalar(0, smin, std::min(_vmin, _vmax)),
    125                         cv::Scalar(180, 256, std::max(_vmin, _vmax)), mask);
    126 
    127                 int fromTo[2] = { 0,0 };
    128                 hue.create(hsv.size(), hsv.depth());
    129                 cv::mixChannels(std::vector<cv::UMat>(1, hsv), std::vector<cv::UMat>(1, hue), fromTo, 1);
    130 
    131                 if (trackObject < 0)
    132                 {
    133                     cv::UMat roi(hue, selection), maskroi(mask, selection);
    134                     cv::calcHist(std::vector<cv::Mat>(1, roi.getMat(cv::ACCESS_READ)), std::vector<int>(1, 0),
    135                                  maskroi, hist, std::vector<int>(1, hsize), std::vector<float>(hranges, hranges + 2));
    136                     cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX);
    137 
    138                     trackWindow = selection;
    139                     trackObject = 1;
    140 
    141                     histimg = cv::Scalar::all(0);
    142                     int binW = histimg.cols / hsize;
    143                     cv::Mat buf (1, hsize, CV_8UC3);
    144                     for (int i = 0; i < hsize; i++)
    145                         buf.at<cv::Vec3b>(i) = cv::Vec3b(cv::saturate_cast<uchar>(i*180./hsize), 255, 255);
    146                     cv::cvtColor(buf, buf, cv::COLOR_HSV2BGR);
    147 
    148                     {
    149                         cv::Mat _hist = hist.getMat(cv::ACCESS_READ);
    150                         for (int i = 0; i < hsize; i++)
    151                         {
    152                             int val = cv::saturate_cast<int>(_hist.at<float>(i)*histimg.rows/255);
    153                             cv::rectangle(histimg, cv::Point(i*binW, histimg.rows),
    154                                        cv::Point((i+1)*binW, histimg.rows - val),
    155                                        cv::Scalar(buf.at<cv::Vec3b>(i)), -1, 8);
    156                         }
    157                     }
    158                 }
    159 
    160                 cv::calcBackProject(std::vector<cv::UMat>(1, hue), std::vector<int>(1, 0), hist, backproj,
    161                                     std::vector<float>(hranges, hranges + 2), 1.0);
    162                 cv::bitwise_and(backproj, mask, backproj);
    163 
    164                 cv::RotatedRect trackBox = cv::CamShift(backproj, trackWindow,
    165                                     cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 10, 1));
    166                 if (trackWindow.area() <= 1)
    167                 {
    168                     int cols = backproj.cols, rows = backproj.rows, r = (std::min(cols, rows) + 5)/6;
    169                     trackWindow = cv::Rect(trackWindow.x - r, trackWindow.y - r,
    170                                        trackWindow.x + r, trackWindow.y + r) &
    171                                   cv::Rect(0, 0, cols, rows);
    172                 }
    173 
    174                 if (backprojMode)
    175                     cv::cvtColor(backproj, image, cv::COLOR_GRAY2BGR);
    176 
    177                 {
    178                     cv::Mat _image = image.getMat(cv::ACCESS_RW);
    179                     cv::ellipse(_image, trackBox, cv::Scalar(0, 0, 255), 3, cv::LINE_AA);
    180                 }
    181             }
    182         }
    183         else if (trackObject < 0)
    184             paused = false;
    185 
    186         if (selectObject && selection.width > 0 && selection.height > 0)
    187         {
    188             cv::UMat roi(image, selection);
    189             cv::bitwise_not(roi, roi);
    190         }
    191 
    192         cv::imshow("CamShift Demo", image);
    193         if (showHist)
    194             cv::imshow("Histogram", histimg);
    195 
    196         char c = (char)cv::waitKey(10);
    197         if (c == 27)
    198             break;
    199 
    200         switch(c)
    201         {
    202         case 'b':
    203             backprojMode = !backprojMode;
    204             break;
    205         case 't':
    206             trackObject = 0;
    207             histimg = cv::Scalar::all(0);
    208             break;
    209         case 'h':
    210             showHist = !showHist;
    211             if (!showHist)
    212                 cv::destroyWindow("Histogram");
    213             else
    214                 cv::namedWindow("Histogram", cv::WINDOW_AUTOSIZE);
    215             break;
    216         case 'p':
    217             paused = !paused;
    218             break;
    219         case 'c':
    220             cv::ocl::setUseOpenCL(!cv::ocl::useOpenCL());
    221         default:
    222             break;
    223         }
    224     }
    225 
    226     return EXIT_SUCCESS;
    227 }
    228