OpenCV 八领域断点检测+断点缺陷修补

在图像Canny边缘检测、形态学操作后还是存在边缘上的断点。
本文理论来自链接1,代码从链接2 、链接3修改来的。

八领域做个简单的记录。

0 (x, y + 1) 0
(x - 1, y) P(x, y) (x +1, y)
0 (x, y - 1) 0
表1
表1为四领域
(x - 1,y + 1) 0 (x + 1, y + 1)
0 P(x, y) 0
(x - 1,y - 1) 0 (x + 1,y - 1)
表2
表2为D领域

八领域 = 四领域 + D领域

P9 P2 P3
P8 p1 p4
P7 p6 P5

p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 == 1表示该点为端点.

OpenCV 八领域断点检测+断点缺陷修补_第1张图片
图片来自链接1。

断点修补的方法时判断两个端点的距离是否小于一个阈值,如果小于该阈值则将两个端点连接。
代码:

int main()
{
	Mat src = imread("lena.bmp", 0);
	imshow("src", src);
	Canny(src, src, 60, 120);
	imshow("canny", src);

	Mat dst;
	vector<Point>P;
	P = breakImage(src, dst, 10);
	imshow("dst", dst); 
	
	int nsize = P.size();
	Mat temp = Mat::zeros(dst.size(), CV_8UC3);
	for (int i = 0; i < nsize; i++)
	{
		circle(temp, P[i], 1, Scalar(0, 255, 255));
	}
	Mat circleadd;
	cvtColor(src, src, COLOR_GRAY2BGR);
	addWeighted(tp, 0.5, src, 0.5, 0, circleadd);

	imshow("circleadd", circleadd);

	waitKey(0);

}

vector<Point> breakImage(Mat &src, Mat &dst, int DisThre)
{
	if (dst.data != src.data) src.copyTo(dst);

	vector<Point> pointxy;
	Point ptPoint;
	Size size = src.size();
	int nSize, dx, dy;
	float distance;

	for (int i = 1; i < size.height - 1; i++)
	{
		uchar *dataPre = dst.ptr<uchar>(i - 1);
		uchar *dataCurr = dst.ptr<uchar>(i);
		uchar *dataNext = dst.ptr<uchar>(i + 1);
		for (int j = 1; j < size.width - 1; j++)
		{
			//  p9 p2 p3    
			//  p8 p1 p4    
			//  p7 p6 p5
			int p1 = dataCurr[j];
			if (p1 != 255) continue;
			int p2 = dataPre[j];
			int p3 = dataPre[j + 1];
			int p4 = dataCurr[j + 1];
			int p5 = dataNext[j + 1];
			int p6 = dataNext[j];
			int p7 = dataNext[j - 1];
			int p8 = dataCurr[j - 1];
			int p9 = dataPre[j - 1];

			if (p1 == 255)
			{
				if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) == 255)
				{
					printf("p1 = 1");
					ptPoint.x = j;
					ptPoint.y = i;
					pointxy.push_back( ptPoint );
					printf("x:%d y:%d\n", j, i);
				}
			}

		}
	}
	nSize = (int)pointxy.size();
	printf("size:%d\n", nSize);
	for (int i = 0; i < nSize - 1; i++)
	{
		for (int j = i + 1; j < nSize; j++)
		{
			dx = pointxy[i].x - pointxy[j].x;
			dy = pointxy[i].y - pointxy[j].y;
			distance = (float)(dx * dx + dy * dy);
			if (distance <= DisThre * DisThre)
			{
				line(dst, pointxy[i], pointxy[j], Scalar(255, 255, 255));
			}
		}
	}
	return pointxy;
}

OpenCV 八领域断点检测+断点缺陷修补_第2张图片
OpenCV 八领域断点检测+断点缺陷修补_第3张图片
OpenCV 八领域断点检测+断点缺陷修补_第4张图片
OpenCV 八领域断点检测+断点缺陷修补_第5张图片
我自己实际应用了下,感觉效果并不是很好,但让我改进项目里的算法可能可以用。
参考链接:
1.OpenCV学习(13) 细化算法(1)
2.八邻域断点检测
3.图像轮廓缺陷修补
4.边缘断裂处理算法-边缘连接算法
5.图像处理(五):八邻域边缘跟踪与区域生长算法
6.数字图像处理入门(二)-邻域、连通性

你可能感兴趣的:(OpenCv)