opencv实践::对象的提取

 

问题描述
  真实案例,对图像中对象进行提取,获取这样对象,去掉其它干扰和非目标对象。

 

解决思路 
  二值分割 + 形态学处理 +横纵比计算

 

 

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

#define IMAGE_IMAGE "D:/case4.png"

using namespace cv;
using namespace std;

Mat src, binary, dst;
int main(int argc, char** argv) {
    src = imread(IMAGE_IMAGE, 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);

    Mat circleImage = src.clone();
    cvtColor(circleImage, circleImage, COLOR_GRAY2BGR);
    circle(circleImage, cc, 2, Scalar(0, 0, 255), 2, 8, 0);
    imshow("Final Result", circleImage);

    waitKey(0);
    return 0;
}

 

 

 




 

posted @ 2019-10-12 15:50  osbreak  阅读(570)  评论(0编辑  收藏  举报