| 62 | m_assertInvariants(); |
| 63 | } |
| 64 | bool VideoBasedTracker::processImage(cv::Mat frame, cv::Mat grayImage, |
| 65 | PoseHandler handler) { |
| 66 | m_assertInvariants(); |
| 67 | bool done = false; |
| 68 | m_frame = frame; |
| 69 | m_imageGray = grayImage; |
| 70 | |
| 71 | //================================================================ |
| 72 | // Tracking the points |
| 73 | |
| 74 | // Threshold the image based on the brightness value that is between |
| 75 | // the darkest and brightest pixel in the image. |
| 76 | // @todo Make this a parameter. |
| 77 | double minVal, maxVal; |
| 78 | cv::minMaxLoc(m_imageGray, &minVal, &maxVal); |
| 79 | double thresholdValue = 220; |
| 80 | cv::threshold(m_imageGray, m_thresholdImage, thresholdValue, 255, |
| 81 | CV_THRESH_BINARY); |
| 82 | |
| 83 | // @todo are any of the above steps already being performed in the blob |
| 84 | // detector (if configured in a given way?) |
| 85 | // http://docs.opencv.org/master/d0/d7a/classcv_1_1SimpleBlobDetector.html#details |
| 86 | |
| 87 | // Construct a blob detector and find the blobs in the image. |
| 88 | // This set of parameters is optimized for the OSVR HDK prototype |
| 89 | // that has exposed LEDs. |
| 90 | /// @todo: Make a different set of parameters optimized for the |
| 91 | /// Oculus Dk2. |
| 92 | /// @todo: Determine the maximum size of a trackable blob by seeing |
| 93 | /// when we're so close that we can't view at least four in the |
| 94 | /// camera. |
| 95 | cv::SimpleBlobDetector::Params params; |
| 96 | params.minThreshold = static_cast<float>(thresholdValue); |
| 97 | params.maxThreshold = static_cast<float>( |
| 98 | thresholdValue + (maxVal - thresholdValue) * 0.3); |
| 99 | params.thresholdStep = (params.maxThreshold - params.minThreshold) / 10; |
| 100 | params.blobColor = static_cast<uchar>(255); |
| 101 | params.filterByColor = |
| 102 | false; // Look for bright blobs: there is a bug in this code |
| 103 | params.minInertiaRatio = 0.5; |
| 104 | params.maxInertiaRatio = 1.0; |
| 105 | params.filterByInertia = false; // Do we test for non-elongated blobs? |
| 106 | params.minArea = 1; // How small can the blobs be? |
| 107 | params.filterByConvexity = false; // Test for convexity? |
| 108 | params.filterByCircularity = false; // Test for circularity? |
| 109 | params.minDistBetweenBlobs = 3; |
| 110 | #if CV_MAJOR_VERSION == 2 |
| 111 | cv::Ptr<cv::SimpleBlobDetector> detector = |
| 112 | new cv::SimpleBlobDetector(params); |
| 113 | #elif CV_MAJOR_VERSION == 3 |
| 114 | auto detector = cv::SimpleBlobDetector::create(params); |
| 115 | #else |
| 116 | #error "Unrecognized OpenCV version!" |
| 117 | #endif |
| 118 | /// @todo this variable is a candidate for hoisting to member |
| 119 | std::vector<cv::KeyPoint> foundKeyPoints; |
| 120 | detector->detect(m_imageGray, foundKeyPoints); |
| 121 | |