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;
}
``
原文地址: https://www.cveoy.top/t/topic/cuYx 著作权归作者所有。请勿转载和采集!