如何使用OpenCV区分圆形和其他形状?

时间:2019-01-09 02:59:13

标签: c++ visual-studio opencv

我是OpenCV和C ++的新手。 而且我被这个问题困住了,这看起来似乎很琐碎。

我正在尝试将圆形与其他形状(例如矩形,正方形,三角形等)区分开来。

这是我使用的代码

void setLabel(Mat& image, string str, vector<Point> contour){

int fontface = FONT_HERSHEY_SIMPLEX;
double scale = 0.5;
int thickness = 1;
int baseline = 0;

Size text = getTextSize(str, fontface, scale, thickness, &baseline);
Rect r = boundingRect(contour);

Point pt(r.x + ((r.width - text.width) / 2), r.y + ((r.height + text.height) / 2));
rectangle(image, pt + Point(0, baseline), pt + Point(text.width, -text.height), CV_RGB(200, 200, 200), CV_FILLED);
putText(image, str, pt, fontface, scale, CV_RGB(0, 0, 0), thickness, 8);

}

int main(){
    Mat img_input, img_result, img_gray;

    String filepath("C:\\Users\\PC\\Desktop\\kist\\test.png");
    img_input = imread(filepath, IMREAD_COLOR);

    if (img_input.empty()){
        cout << "Could not open or find the image" << std::endl;
        return -1;
    }          
    cvtColor(img_input, img_gray, COLOR_BGR2GRAY);

    medianBlur(img_gray, img_gray, 5);

    vector <Vec3f> circles;
    HoughCircles(img_gray, circles, CV_HOUGH_GRADIENT, 1, 20, 200, 50, 0, 0);

    threshold(img_gray, img_gray, 125, 255, THRESH_BINARY_INV | THRESH_OTSU);

    vector<vector<Point> > contours;
    findContours(img_gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);

    vector<Point2f> approx;
    img_result = img_input.clone();

    for (size_t i = 0; i < contours.size(); i++){
        approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);

        if (fabs(contourArea(Mat(approx))) > 0){   

            int size = approx.size();

            if (size % 2 == 0) {
                line(img_result, approx[0], approx[approx.size() - 1], Scalar(0, 255, 0), 2);

                for (int k = 0; k < size - 1; k++) 
                    line(img_result, approx[k], approx[k + 1], Scalar(0, 255, 0), 2);

                for (int k = 0; k < size; k++)  
                    circle(img_result, approx[k], 3, Scalar(0, 0, 255));

                for (size_t j = 0; j < circles.size(); j++) {
                    Vec3i c = circles[j];
                    Point center = Point(c[0], c[1]);

                    circle(img_result, center, 2, Scalar(0, 255, 0), 2, LINE_AA);

                    int radius = c[2];

                    circle(img_result, center, radius, Scalar(0, 255, 0), 2, LINE_AA);

                }

            }

            else if (size % 2 > 0) {
                line(img_result, approx[0], approx[approx.size() - 1], Scalar(0, 255, 0), 2);

                for (int k = 0; k < size - 1; k++)
                    line(img_result, approx[k], approx[k + 1], Scalar(0, 255, 0), 2);

                for (int k = 0; k < size; k++)
                    circle(img_result, approx[k], 3, Scalar(0, 0, 255));

            }

            if (size == 3)
                setLabel(img_result, "triangle", contours[i]);


            else if (size == 4 && isContourConvex(Mat(approx)))
                setLabel(img_result, "rectangle", contours[i]); 

            else if (size == 5 && isContourConvex(Mat(approx)))
                setLabel(img_result, "pentagon", contours[i]); 

            else if (size == 6 && isContourConvex(Mat(approx)))
                setLabel(img_result, "hexagon", contours[i]);  

            else if (size == 10 && isContourConvex(Mat(approx)))
                setLabel(img_result, "decagon", contours[i]);   

            else {
                setLabel(img_result, to_string(approx.size()), contours[i]);                        
            }
        } 
        else if (fabs(contourArea(Mat(approx))) == 0) {
            for (size_t i = 0; i < circles.size(); i++) {
                Vec3i c = circles[i];
                Point center = Point(c[0], c[1]);

                circle(img_result, center, 2, Scalar(0, 100, 100), 2, LINE_AA);

                int radius = c[2];

                circle(img_result, center, radius, Scalar(255, 0, 255), 2, LINE_AA);

            }
            setLabel(img_result, to_string(approx.size()), contours[i]);
        }
    }

    imshow("input", img_input);
    imshow("result", img_result);

如下图所示,我能够找出每个图的顶点并绘制线条。

但是,我要删除顶点和直线,并从圆形中保留圆形轮廓。此外,我想将圆形描述为“圆形”并计算每种形状的数量。

请帮助我~~

谢谢!

enter image description here

enter image description here

0 个答案:

没有答案