欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 11:19:38
...

写在前面

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

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

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

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

原理

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

梯度算子定义为:               

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

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

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

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

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

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

优缺点

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

 

代码实现

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

void getRobert_oper(cv::Mat& getRobert_oper1, cv::Mat& getRobert_oper2){
	//135°方向
	getRobert_oper1 = (cv::Mat_<float>(2, 2) << 1, 0, -1, 0);
	//45°方向
	getRobert_oper2 = (cv::Mat_<float>(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算子边缘检测原理及实现

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

 

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

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

 

参考

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