bool RandomFeatureFinder::find( Pose_d& pose ) { if( !m_configured ) throw std::runtime_error("RandomFeatureFinder::find: not configured."); // find circles in pose std::vector<Eigen::Vector2d> posePoints = findCircles( *pose.image ); if( posePoints.size() < m_minPoints ) return false; // generate descriptors for detected points RFD poseRFD(true); poseRFD( posePoints ); // compare the resulting descriptors with the configured m_patternRFD.match( poseRFD, pose ); // assemble the result if( pose.pointIndices.size() >= m_minPoints ) { // set max number of points pose.pointsMax = m_points3D.size(); // run over the indices and set the 3D points pose.points3D.clear(); for( size_t i=0; i<pose.pointIndices.size(); i++ ) pose.points3D.push_back( m_points3D[pose.pointIndices[i] ] ); // we are happy return true; } else return false; }
void circles() { // Find edges Image i = readImage("circles.ppm"); GradientAndEdges gradientAndEdges = findGradientAndEdges(i, 5, 5, 3, 20); // Create buffer int bufferSize = 50; Image result = newImage(1, i.w + bufferSize * 2, i.h + bufferSize * 2); clearImage(result); // Find circles findCircles(gradientAndEdges, result, 32, 12, bufferSize, 15, 10); findCircles(gradientAndEdges, result, 16, 5, bufferSize, 15, 10); findCircles(gradientAndEdges, result, 48, 3, bufferSize, 51, 20); // Show result writeImage(result, "result.pgm"); return; }
std::vector<std::vector<struct ColouredCircle> > findColouredCirclesInFrame(cv::InputArray frame, cv::InputArray background) { cv::UMat foreground; cv::UMat processed; cv::Ptr<cv::BackgroundSubtractorMOG2> bs = cv::createBackgroundSubtractorMOG2(1, 254, false); // HEURISTIC: 254 = parameter for background subtractor bs->apply(background, foreground, 1); bs->apply(frame, foreground, 0); frame.copyTo(processed, foreground); cv::medianBlur(processed, processed, 9); // HEURISTIC: 9 = amount of blur applied before colour convertion cv::cvtColor(processed, processed, cv::COLOR_BGR2HSV); std::array<cv::UMat, 5> masks; // order: ball, blue, yellow, pink, green cv::inRange(processed, cv::Scalar(0, 100, 100), cv::Scalar(10, 255, 255), masks[0]); // HEURISTIC: range of HSV values cv::inRange(processed, cv::Scalar(76, 90, 90), cv::Scalar(146, 255, 255), masks[1]); // HEURISTIC: range of HSV values cv::inRange(processed, cv::Scalar(24, 200, 200), cv::Scalar(44, 255, 255), masks[2]); // HEURISTIC: range of HSV values cv::inRange(processed, cv::Scalar(165, 90, 90), cv::Scalar(180, 255, 255), masks[3]); // HEURISTIC: range of HSV values cv::inRange(processed, cv::Scalar(50, 200, 200), cv::Scalar(70, 255, 255), masks[4]); // HEURISTIC: range of HSV values std::array<std::vector<std::vector<cv::Point> >, 5> contours; // order: ball, blue, yellow, pink, green // TODO: potentially can be vectorized for(size_t i = 0; i < masks.size(); i++) { cv::findContours(masks[i], contours[i], cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); } std::vector<std::vector<struct ColouredCircle> > circles; // TODO: potentially can be vectorized for(size_t i = 0; i < contours.size(); i++) { std::vector<struct ColouredCircle> c; findCircles(contours[i], c, 1, 5); // HEURISTIC: deviation of circle and ellipse center and radius for(size_t j = 0; j < c.size(); j++) { c[j].colour = int(i); } circles.push_back(c); } return circles; }