opencv之圆形检测

注:此教程是对贾志刚老师的opencv课程学习的一个记录,在此表示对贾老师的感谢.
需求: 找出下图中的圆形.在这里插入图片描述
如果直接用霍夫圆检测 的话,效果很差.
代码:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;


int main() {
    
    


    Mat frame = imread("/home/fuhong/code/cpp/opencv_learning/src/small_case/imgs/case3.png", IMREAD_COLOR);
    imshow("frame", frame);

    Mat grayImg;
    cvtColor(frame, grayImg, COLOR_BGR2GRAY);
    imshow("grayimg", grayImg);

    vector<Vec3f> circles;
//      HoughCircles(grayImg,circles,HOUGH_GRADIENT,1,150,100,30,50,90);
    HoughCircles(grayImg, circles, HOUGH_GRADIENT, 1, 10, 100, 30, 5, 30);


    for (int i = 0; i < circles.size(); ++i) {
    
    
        Vec3f c = circles.at(i);
        Point center(c[0], c[1]);
        float radius = c[2];
        cout << radius << endl;
        circle(frame, center, radius, Scalar(0, 255, 0), 2, LINE_AA);
    }


    imshow("rest", frame);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

效果如下图所示:
在这里插入图片描述
正确的操作: 二值分割 + 形态学处理 +横纵比计算
代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;

Mat src, binary, dst;

int main(int argc, char **argv) {
    
    
    src = imread("/home/fuhong/code/cpp/opencv_learning/src/small_case/imgs/case3.png", IMREAD_GRAYSCALE);
    if (src.empty()) {
    
    
        printf("could not load image...\n");
        return -1;
    }
    namedWindow("input image", CV_WINDOW_AUTOSIZE);
    imshow("input image", src);

    threshold(src, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    imshow("binary image", binary);

    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
    morphologyEx(binary, dst, MORPH_CLOSE, kernel, Point(-1, -1));
    imshow("close image", dst);

    kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
    morphologyEx(dst, dst, MORPH_OPEN, kernel, Point(-1, -1));
    imshow("open image", dst);

    vector<vector<Point>> contours;
    vector<Vec4i> hireachy;
    findContours(dst, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());

    Mat resultImage = Mat::zeros(src.size(), CV_8UC3);
    Point cc;
    for (size_t t = 0; t < contours.size(); t++) {
    
    
        double area = contourArea(contours[t]);
        if (area < 100) continue;
        Rect rect = boundingRect(contours[t]);
        float ratio = float(rect.width) / float(rect.height);

        if (ratio < 1.1 && ratio > 0.9) {
    
    
            drawContours(resultImage, contours, t, Scalar(0, 0, 255), -1, 8, Mat(), 0, Point());
            printf("circle area : %f\n", area);
            printf("circle length : %f\n", arcLength(contours[t], true));
            int x = rect.x + rect.width / 2;
            int y = rect.y + rect.height / 2;
            cc = Point(x, y);
            circle(resultImage, cc, 2, Scalar(0, 0, 255), 2, 8, 0);
        }
    }
    imshow("Result", resultImage);
    
    waitKey(0);
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hongge_smile/article/details/108673748