Roberts算子边缘检测原理及实现

写在前面

我们知道,进行边缘检测有两种方法:一阶导数的极值、二阶导数的过零点。

Robert算子是一种一阶微分算子,而且Robert算子是第一个边缘检测算子,提出者是Lawrence Roberts in 1963。

从这篇博客开始,会陆续介绍几种经典的边缘检测算子。先附上各种边缘检测算法的优缺点:

                      Roberts算子边缘检测原理及实现_第1张图片

原理

Roberts算子是一种斜向偏差分的梯度计算方法,梯度的大小代表边缘的强度,梯度的方向与边缘的走向垂直(正交)。

梯度算子定义为:               

                                                            G(x, y)=\sqrt{\nabla_{x} f(x, y)^{2}+\nabla_{y} f\left(x, y^{2}\right)}

为了简化计算,一般梯度算子可以近似为:

                                                               G(x, y)=\left|\nabla_{x} f(x, y)\right|+\left|\nabla_{y} f(x, y)\right|

由此,我们可得图像离散化(差分代替偏导)的对角线Roberts算子:

                                                            \left\{\begin{array}{l}{\bigtriangledown {x} f(x, y)=f(x, y)-f(x-1, y-1)} \\ {\bigtriangledown {y} f(x, y)=f(x-1, y)-f(x, y-1)}\end{array}\right.

Roberts算子边缘检测原理及实现_第2张图片

优缺点

 从图像处理的实际效果来看,计算简单,边缘定位较准,但对噪声极敏感。适用于边缘明显且噪声较少的图像分割。

 

代码实现

#include 
#include 
#include 
#include 

void getRobert_oper(cv::Mat& getRobert_oper1, cv::Mat& getRobert_oper2){
	//135°方向
	getRobert_oper1 = (cv::Mat_(2, 2) << 1, 0, -1, 0);
	//45°方向
	getRobert_oper2 = (cv::Mat_(2, 2) << 0, 1, -1, 0);

	//逆时针反转180°得到卷积核(这里反转之后与原来一样,为了严谨还是做这个操作)
	cv::flip(getRobert_oper1, getRobert_oper1, -1);
	cv::flip(getRobert_oper2, getRobert_oper2, -1);
}

void edge_Robert(cv::Mat& src, cv::Mat& dst1, cv::Mat& dst2, cv::Mat& dst,int ddepth, double delta = 0, int borderType = cv::BORDER_DEFAULT){
	//获取Robert算子
	cv::Mat getRobert_oper1;
	cv::Mat getRobert_oper2;
	getRobert_oper(getRobert_oper1, getRobert_oper2);

	//卷积得到135°方向边缘
	cv::filter2D(src, dst1, ddepth, getRobert_oper1, cv::Point(0, 0), delta, borderType);

	//卷积得到45°方向边缘
	cv::filter2D(src, dst2, ddepth, getRobert_oper2, cv::Point(1, 0), delta, borderType);

	//边缘强度(近似)
	cv::convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图
	cv::convertScaleAbs(dst2, dst2);
	dst = dst1 + dst2;
}

int main(){
	cv::Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\Fig1025(a)(building_original).tif");
	if (src.empty()){
		return -1;
	}
	if (src.channels() > 1) cv::cvtColor(src, src, CV_RGB2GRAY);
	cv::Mat dst, dst1, dst2;

	//注意:要采用CV_32F,因为有些地方卷积后为负数,若用8位无符号,则会导致这些地方为0
	edge_Robert(src, dst1, dst2, dst, CV_32F); 

	imshow("src", src);
	imshow("135°边缘", dst1);
	imshow("45°边缘", dst2);
	imshow("边缘强度", dst);
	cv::waitKey(0);
	return 0;
}

效果

Roberts算子边缘检测原理及实现_第3张图片

 

Roberts算子边缘检测原理及实现_第4张图片

Roberts算子边缘检测原理及实现_第5张图片

 

参考

https://zhuanlan.zhihu.com/p/49447503

http://imgtec.eetrend.com/d6-imgtec/blog/2018-09/17673.html

https://blog.csdn.net/tigerda/article/details/61192943

https://blog.csdn.net/Augusdi/article/details/9028331

你可能感兴趣的:(【图像处理算法】,图像处理经典算法c++实现)