OpenCV——八邻域断点检测

在这里插入图片描述

OpenCV——八邻域断点检测由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。

一、理论基础

1、八邻域

在这里插入图片描述

图1 八邻域示意图

在这里插入图片描述

图2 八邻域对应坐标关系

2、断点检测

  首先将图像进行二值化,然后检测以 P 1 P_1 P1为中心的它的八个领域,

  • P 2 + P 3 + P 4 + P 5 + P 6 + P 7 + P 8 + P 9 ≤ 255 × 6 P_2+P_3+P_4+P_5+P_6+P_7+P_8+P_9\leq255\times6 P2+P3+P4+P5+P6+P7+P8+P9255×6,则 P 1 P_1 P1点是一个边界点。
  • P 2 + P 3 + P 4 + P 5 + P 6 + P 7 + P 8 + P 9 ≥ 255 × 6 P_2+P_3+P_4+P_5+P_6+P_7+P_8+P_9\geq255\times6 P2+P3+P4+P5+P6+P7+P8+P9255×6,则 P 1 P_1 P1点是一个内部点。
  • P 2 + P 3 + P 4 + P 5 + P 6 + P 7 + P 8 + P 9 = 0 P_2+P_3+P_4+P_5+P_6+P_7+P_8+P_9=0 P2+P3+P4+P5+P6+P7+P8+P9=0,则 P 1 P_1 P1点是一个孤立点。
  • P 2 + P 3 + P 4 + P 5 + P 6 + P 7 + P 8 + P 9 = 255 P_2+P_3+P_4+P_5+P_6+P_7+P_8+P_9=255 P2+P3+P4+P5+P6+P7+P8+P9=255,则 P 1 P_1 P1点是一个端点。
    在这里插入图片描述
图3 点的类型

二、代码实现

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

vector<Point> breakImage(Mat& src);

int main()
{
     // 加载RGB图片
	Mat colorImage, grayImage, binImage;
	colorImage = imread("2.png");
	// 显示图片
	namedWindow("原始图像", cv::WINDOW_NORMAL); // 图像窗口函数
	imshow("原始图像", colorImage);
	// 图像二值化
	cvtColor(colorImage, grayImage, COLOR_BGR2GRAY);
	threshold(grayImage, binImage, 1, 255, THRESH_BINARY);

	vector<Point>P;
	P = breakImage(binImage);
	
	int nsize = P.size();
	Mat temp = Mat::zeros(binImage.size(), CV_8UC3);
	// 用圆圈出端点
	for (int i = 0; i < nsize; i++)
	{
   
		circle(temp, P[i], 10, Scalar(0, 255, 0));
	}
	Mat circleadd;
	
	addWeighted(temp, 1, colorImage, 1, 0, circleadd);
	imwrite("端点.png",circleadd);
	namedWindow("circleadd", cv::WINDOW_NORMAL);
	imshow("circleadd", circleadd);

	waitKey(0);
	   
}
#pragma region//8邻域提取端点
vector<Point> breakImage(Mat& src)
{
   
	vector<Point> pointxy;
	Point ptPoint;
	Size size = src.size();
	int nSize;

	for (int i = 1; i < size.height - 1; i++)
	{
   
		uchar* dataPre = src.ptr<uchar>(i - 1);
		uchar* dataCurr = src.ptr<uchar>(i);
		uchar* dataNext = src.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)
				{
   
					ptPoint.x = j;
					ptPoint.y = i;
					pointxy.push_back(ptPoint);
					printf("端点的坐标为:x:%d y:%d\n", j, i);
				}
			}

		}
	}
	nSize = (int)pointxy.size();
	printf("提取端点个数:%d\n", nSize);
	
	return pointxy;
}
#pragma endregion

三、结果展示

在这里插入图片描述
在这里插入图片描述

四、参考链接

[1] 八邻域断点检测
[2] OpenCV 八领域断点检测+断点缺陷修补

相关推荐

  1. ccf 202104-2 均值

    2024-01-17 02:36:02       39 阅读
  2. unity3d在汽车应用浅谈

    2024-01-17 02:36:02       55 阅读
  3. 【CSP试题回顾】202104-2-均值(优化)

    2024-01-17 02:36:02       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-17 02:36:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-17 02:36:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-17 02:36:02       82 阅读
  4. Python语言-面向对象

    2024-01-17 02:36:02       91 阅读

热门阅读

  1. Linux IDEA 安装及环境配置

    2024-01-17 02:36:02       56 阅读
  2. c++八股3

    2024-01-17 02:36:02       51 阅读
  3. 面试官:什么是垂直越权?有哪些解决方案?

    2024-01-17 02:36:02       49 阅读
  4. 02-k8s学习笔记之相关组件

    2024-01-17 02:36:02       47 阅读