OpenCV | 二值圖像分析的技巧都在這裡[輪廓分析/ ​形態學]

OpenCV | 二值圖像分析的技巧都在這裡[輪廓分析/ ​形態學]

OpenCV | 二值圖像分析的技巧都在這裡[輪廓分析/ 形態學]


資料來源: https://mp.weixin.qq.com/s/MGKDtYJd5Yw96SirHZh0Yw

01.輪廓分析相關的常用函數功能列表

    –輪廓面積

    -輪廓周長

    -輪廓幾何矩

    -輪廓的最小外接矩形[長方形]

    -輪廓的最大外接矩形

    -輪廓的最小外接圓

    -輪廓的最小外接三角形

    -輪廓擬合(支持擬合直線、橢圓、圓)

    -輪廓的凸包

    -輪廓層次信息提取

    -多邊形逼近

    -計算歐拉數


02.輪廓分析相關的常用函數原型宣告:

// 计算轮廓面积
double cv::contourArea(
InputArray contour,
bool oriented = false
)
// 计算轮廓周长
double cv::arcLength(
InputArray      curve,
bool        closed
)
// 计算几何矩与中心距
Moments cv::moments(
InputArray      array,
bool        binaryImage = false
)
// 计算最小外接矩形
RotatedRect cv::minAreaRect(
InputArray      points
)
// 计算最大外接矩形
Rect cv::boundingRect(
InputArray      array
)
// 计算最小外接圆/拟合圆
void cv::minEnclosingCircle(
InputArray      points,
Point2f &        center,
float &    radius
)
// 计算最小外接三角形/拟合三角形
double cv::minEnclosingTriangle(
InputArray      points,
OutputArray   triangle
)
// 拟合直线
void cv::fitLine(
InputArray      points,
OutputArray   line,
int   distType,
double    param,
double    reps,
double    aeps
)
// 拟合椭圆
RotatedRect cv::fitEllipse(
InputArray      points
)
// 计算凸包
void cv::convexHull(
InputArray      points,
OutputArray   hull,
bool        clockwise = false,
bool        returnPoints = true
)
// 多边形逼近-逼近真实形状
void cv::approxPolyDP(
InputArray      curve,
OutputArray   approxCurve,
double    epsilon,
bool        closed
)


03.這裡再分享一個硬幣計數的例子!

// 加载图像
Mat img = imread("D:/CoinsB.png");
imshow("Original Image", img);

// 阈值化操作
Mat gray, binary;
cvtColor(img, gray, COLOR_BGR2GRAY);
float t = threshold(gray, binary, 0, 255, THRESH_BINARY|THRESH_OTSU);
imshow("binary", binary);
imwrite("D:/binary1.png", binary);

// 形态学操作
Mat se = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(binary, binary, MORPH_OPEN, se, Point(-1, -1));

// 轮廓发现
vector<Vec4i> hireachy;
vector<vector<Point>> contours;
bitwise_not(binary, binary);
findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
Mat result = img.clone();
Point2f center;
float radius;

// 轮廓分析
for (size_t t = 0; t < contours.size(); t++) {
    double area = contourArea(contours[t]);
    if (area < 1000) {
        continue;
    }
    RotatedRect rrt = fitEllipse(contours[t]);
    radius = min(rrt.size.width, rrt.size.height)/2.0;
    circle(result, rrt.center, radius, Scalar(0, 0, 255), 4, 8, 0);
    Moments mm = moments(contours[t]);
    double cx = mm.m10 / mm.m00;
    double cy = mm.m01 / mm.m00;
    circle(result, Point(cx, cy), 2, Scalar(255, 0, 0), 2, 8, 0);
}

// 显示结果
imshow("result", result);
imwrite("D:/drawing.png", result);
waitKey(0);

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *