C++ OpenCV 月牙形图像凹点填充算法 - 填充凹陷区域,原理与代码

本文介绍使用 C++ 和 OpenCV 对月牙形二值化图像中未闭合的凹点区域进行白色填充的算法。

原理

对于月牙形二值化图像,我们可以使用 OpenCV 中的轮廓检测函数 findContours() 来找到所有的轮廓,然后对每一个轮廓进行处理。

对于每一个轮廓,我们可以使用 cv::convexHull() 函数来找到其凸包,然后使用 cv::fillConvexPoly() 函数将凸包填充为白色。

但是,由于凸包是包含了轮廓的所有点的最小凸多边形,所以可能会出现凹陷的情况。为了解决这个问题,我们可以使用 cv::approxPolyDP() 函数来对轮廓进行多边形逼近,然后找到多边形中的凹点,将其填充为白色。

代码

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

using namespace cv;
using namespace std;

int main()
{
    // 读入二值化图像
    Mat img = imread('moon.png', IMREAD_GRAYSCALE);

    // 膨胀操作,使得轮廓更加连续
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
    dilate(img, img, kernel);

    // 轮廓检测
    vector<vector<Point>> contours;
    findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    // 遍历每一个轮廓
    for (int i = 0; i < contours.size(); i++)
    {
        // 多边形逼近
        vector<Point> approx;
        approxPolyDP(contours[i], approx, 3, true);

        // 找到凹点并填充
        vector<Point> hull;
        convexHull(approx, hull);
        vector<Point> concave;
        for (int j = 0; j < hull.size(); j++)
        {
            int k = (j + 1) % hull.size();
            int z = (j + 2) % hull.size();
            if ((hull[k].x - hull[j].x) * (hull[z].y - hull[k].y) - (hull[k].y - hull[j].y) * (hull[z].x - hull[k].x) < 0)
            {
                concave.push_back(hull[k]);
            }
        }
        fillConvexPoly(img, concave.data(), concave.size(), Scalar(255));
    }

    // 显示结果
    imshow('result', img);
    waitKey(0);

    return 0;
}

总结

通过以上代码,我们可以有效地对月牙形二值化图像中未闭合的凹点区域进行白色填充。该算法利用了 OpenCV 中的轮廓检测、凸包提取、多边形逼近等功能,可以帮助我们快速完成图像处理中的凹点填充任务。

C++ OpenCV 月牙形图像凹点填充算法 - 填充凹陷区域,原理与代码

原文地址: https://www.cveoy.top/t/topic/jXc8 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录