【问题标题】:Improve the detection OpenCV提高检测OpenCV
【发布时间】:2020-06-07 18:53:43
【问题描述】:

我目前正在尝试检测巢中的鸡蛋。为此,我正在使用 OpenCV。

首先,我用 2 个鸡蛋拍了一张照片。然后我将其转换为 HSV。并定义了阈值范围。

但正如您所见,当我尝试显示阈值窗口时,并没有删除所有内容。所以这是我的问题,我怎样才能只检测鸡蛋。

谢谢,

【问题讨论】:

  • 盒子(和地板)的颜色与鸡蛋的颜色非常相似,这可能是您没有得到清晰分割的原因。您可以尝试几件事。如果鸡蛋的位置相当稳定,您可以尝试从图像中crop 框。另一种解决方案是根据 circarity 过滤您的 blob,其想法是鸡蛋具有非常特定(和预期)的圆形值。您也可以尝试执行 Hough Circle Transform,但对于此应用程序来说可能有点过头了。

标签: c++ opencv detection threshold


【解决方案1】:

如果你想从那一点继续,你可以简单地应用你的阈值输出minAreaRect()函数,这将帮助你为每个轮廓绘制一个合适的矩形。之后,您可以比较这些矩形的长度,也可以检查这些矩形的颜色密度以得出结果。

作为替代我尝试了HoughCircle(),它也能够找到具有适当参数的鸡蛋。

这是 houghcircle 的结果和代码:

输入图像:

输出图像:

代码:

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
using namespace std;


int main()
{
    // Loads an image
    Mat src_hough_circle = imread("/ur/image/directory/eggs.png", IMREAD_COLOR );

    Mat gray;
    cvtColor(src_hough_circle, gray, COLOR_BGR2GRAY);

    Mat gray_segmentation = gray.clone();

    //medianBlur(gray, gray, 5);
    GaussianBlur(gray,gray,Size(5,5),0);
    vector<Vec3f> circles;
    HoughCircles(gray, circles, HOUGH_GRADIENT, 1,
                 gray.rows/8,  // change this value to detect circles with different distances to each other
                 100, 30, 80, 170 // change the last two parameters
            // (min_radius & max_radius) to detect larger circles
    );
    for( size_t i = 0; i < circles.size(); i++ )
    {
        Vec3i c = circles[i];
        Point center = Point(c[0], c[1]);
        // circle center
        circle( src_hough_circle, center, 1, Scalar(0,100,100), 3, LINE_AA);
        // circle outline
        int radius = c[2];
        circle( src_hough_circle, center, radius, Scalar(255,0,255), 3, LINE_AA);
    }

    imshow("detected circles", src_hough_circle);
    waitKey(0);



    return 0;
}

【讨论】:

    【解决方案2】:

    谢谢尤努斯,你的方法,这就是我所做的,我不知道它是否比你的方法更好。 (对不起,我没有评论:()

    Output Image

    代码:

    #include <iostream>
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    
    using namespace cv;
    using namespace std;
    
    int Compteur;
    int Area;
    int Contours;
    Mat ImageSource;
    Mat HSV;
    Mat Image_Blur;
    Mat Seuil;
    
    
    int main() {
    
    string FichierSource = "C:/Users/xxxxx/Desktop/TBT/cas.png";
    ImageSource = imread(FichierSource);
    
    cvtColor(ImageSource, HSV, COLOR_BGR2HSV);
    
    inRange(HSV, Scalar(0, 39 , 149), Scalar(179, 255, 255), Seuil);
    
    erode(Seuil, Seuil, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    dilate(Seuil, Seuil, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    
    dilate(Seuil, Seuil, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    erode(Seuil, Seuil, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
    
    blur(Seuil, Image_Blur, Size(5, 5));
    
    imshow("Image original", ImageSource);
    
    imshow("Image convertie en HSV", HSV);
    
    imshow("Image seuillé", Seuil);
    
    
    Mat Threshold_Output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    
    threshold(Image_Blur, Threshold_Output, 100, 255, THRESH_BINARY);
    findContours(Threshold_Output, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
    
    vector<RotatedRect> minRect(contours.size());
    vector<RotatedRect> minEllipse(contours.size());
    
    for (int i = 0; i < contours.size(); i++)
    {
    
        Area = contourArea(contours[i]);
        Contours = contours[i].size();
    
        // -------------------------- DEBUG ZONE ---------------------------- 
        cout << "Contours de la zone : " << contourArea(contours[i]) << endl;
        cout << "Nombre de contours : " << contours[i].size() << endl;
        // ------------------------------------------------------------------ 
    
        if (Contours >= 90 && Contours <= 100) {
            if (Area >= 2000 && Area <= 3200) {
                    minRect[i] = minAreaRect(Mat(contours[i]));
                    minEllipse[i] = fitEllipse(Mat(contours[i]));
            }
                Compteur++;
        }
    }
    
    for (int i = 0; i < contours.size(); i++)
    {
        Area = contourArea(contours[i]);
        Contours = contours[i].size();
    
        if (Contours >= 90 && Contours <= 100) {
            if (Area >= 2000 && Area <= 3200) {
                drawContours(ImageSource, contours, i, Scalar(0, 165, 255), 1, 8, vector<Vec4i>(), 0, Point());
    
                ellipse(ImageSource, minEllipse[i], Scalar(0, 165, 255), 2);
    
                Point2f rect_points[4]; minRect[i].points(rect_points);
                for (int j = 0; j < 4; j++)
                    line(ImageSource, rect_points[j], rect_points[(j + 1) % 4], Scalar(0, 165, 255));
            }
        }
    }
    
    imshow("Image Analysée", ImageSource);
    
    cout << "Nombre d'oeufs : " << Compteur;
    
    waitKey(0);
    
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-16
      • 2020-10-28
      • 2011-10-06
      • 1970-01-01
      • 2014-12-23
      • 2012-07-14
      • 1970-01-01
      • 2018-05-15
      相关资源
      最近更新 更多