我试图用绿色标记笔的尖端。我编写了一个程序,但无法正确标记它。我尝试了不同的HSV值,但结果是相同的。
我的拖拉方法是错误的还是我的方法中有小错误?

我的代码;

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include <iostream>

using namespace std;
using namespace cv;
int main(){

Mat image = imread("C:/denem5.jpg");
Mat bwRed;
Mat hsvImage;
int BiggestAreaIdx = 0;
int BiggestAreaValue = 20;
cvtColor(image, hsvImage, CV_BGR2HSV);
inRange(hsvImage, Scalar(130, 70, 70), Scalar(179, 255, 255), bwRed);
vector<vector<Point>> contours;
findContours(bwRed,
    contours,
    CV_RETR_TREE,
    CV_CHAIN_APPROX_SIMPLE);

//Here I find biggest contour because others are noise
for (int i = 0; i < contours.size(); i++)
{
    double area = contourArea(contours[i], false);
    if (area > BiggestAreaValue)
    {
        BiggestAreaValue = area;
        BiggestAreaIdx = i;
    }
}

Mat dst(image.size(), CV_8UC1, Scalar::all(0));
drawContours(dst, contours, BiggestAreaIdx, Scalar(255), CV_FILLED);

 vector<Moments> mu(contours.size() );
for( int i = 0; i < contours.size(); i++ )
   { mu[i] = moments( contours[i], false ); }

vector<Point2f> mc(contours.size());
 for (int i = 0; i < contours.size(); i++)
 {
  mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
 }
 circle(image, Point(mc[BiggestAreaIdx]), 5, Scalar(0,255,0), 5, 8, 0);
 namedWindow("myimage");
 imshow("myimage",image);
 waitKey(0);
 }

原始图片

我的结果

最佳答案

由于您正在搜索圆,因此可以使用HoughCircles。这是一种不同的方法,具有优缺点。

优点:

  • 与笔的颜色无关。
  • 您不需要选择适当的颜色值

  • 缺点:
  • 需要正确调整参数
  • 如果您需要非圆形,则不起作用。

  • 这里的代码:
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <string>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    int main(){
    
        Mat3b src = imread("path_to_image");
        Mat1b src_gray;
        cvtColor( src, src_gray, CV_BGR2GRAY );
    
        vector<Vec3f> circles;
        HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, 10, 200, 30, 0, 0);
    
        /// Draw the circles detected
        for (size_t i = 0; i < circles.size(); i++)
        {
            Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
            int radius = cvRound(circles[i][2]);
            // circle center
            circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
            // circle outline
            circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
        }
    
        imshow("src", src);
        waitKey();
    
        return 0;
    }
    

    结果如下:

    10-01 02:42