图像边缘检测(sobel算子,prewitt算子,loG算子)c++代码opencv

话不多收,注释写的很详细,直接上代码
待提取边缘原图如下
在这里插入图片描述

	//sobel算子
	{
		Mat image = imread("D:/IInclude/opencv/images/hist_01.jpg");
		Mat resx, resy, rest;
		int dx1 = 2,  dy1=0, dsize1=1;
		int dx2 = 0, dy2=1, dsize2=3;
		//这三者的关系是任意一个方向的差分阶数都需要小于滤波器的尺寸,特殊情况是dsize=1时,任意一个方向的阶数都要小于3
		// 一般情况下,查分阶数的最大值为1时,滤波尺寸选3,查分阶数为2时,滤波尺寸选5,查分阶数为3时,滤波尺寸选7
		//当dsize=1时,程序尺寸不再为方形,为1*3或3*1的矩形
		Sobel(image, resx, CV_16S, 2, 0, 1);//x方向一阶边缘
		Sobel(image, resy, CV_16S, 0, 1, 3);//y方向的一阶边缘
		convertScaleAbs(resx, resx);
		convertScaleAbs(resy, resy);
		rest = resx + resy;
		imshow("sobel", rest);
	}

提取结果
在这里插入图片描述

//prewitt算子
void getPrewitt_oper(Mat& getPrewitt_horizontal, Mat& getPrewitt_vertical, Mat& getPrewitt_Diagonal1, Mat& getPrewitt_Diagonal2) {
	//水平方向
	getPrewitt_horizontal = (Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);
	//垂直方向
	getPrewitt_vertical = (Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
	//对角135°
	getPrewitt_Diagonal1 = (Mat_<float>(3, 3) << 0, 1, 1, -1, 0, 1, -1, -1, 0);
	//对角45°
	getPrewitt_Diagonal2 = (Mat_<float>(3, 3) << -1, -1, 0, -1, 0, 1, 0, 1, 1);

	//逆时针反转180°得到卷积核
	flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);
	flip(getPrewitt_vertical, getPrewitt_vertical, -1);
	flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);
	flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1);
}

void edge_Prewitt(Mat& src, Mat& dst1, Mat& dst2, Mat& dst3, Mat& dst4, Mat& dst, int ddepth, double delta = 0, int borderType = BORDER_DEFAULT) {
	//获取Prewitt算子
	Mat getPrewitt_horizontal;
	Mat getPrewitt_vertical;
	Mat getPrewitt_Diagonal1;
	Mat getPrewitt_Diagonal2;
	getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);

	//卷积得到水平方向边缘
	filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);

	//卷积得到4垂直方向边缘
	filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);

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

	//卷积得到135°方向边缘
	filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);

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

	convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图
	convertScaleAbs(dst4, dst4);
	dst = dst1 + dst2;
}
int mian(){
    Mat image = imread("D:/IInclude/opencv/images/hist_01.jpg");
	Mat dst, dst1, dst2, dst3, dst4;
	edge_Prewitt(image, dst1, dst2, dst3, dst4, dst, CV_32F);
	imshow("边缘强度prewitt", dst);
	waitKey(0);
}

提取结果
在这里插入图片描述

//loG算子
{
	if (image.channels() > 1)
		cvtColor(image, image, COLOR_RGB2GRAY);
	Mat dst;
	Mat gaussian_dst1, gaussian_dst2;
	//高斯滤波
	double sigma = 2, k = 1.6;
	GaussianBlur(image, gaussian_dst1, Size(7, 7) ,k * sigma);
	GaussianBlur(image, gaussian_dst2, Size(7, 7), sigma);

	dst = gaussian_dst1 - gaussian_dst2;
	threshold(dst, dst, 0, 255, THRESH_BINARY);
	imshow("loG算子", dst);
}

提取结果
在这里插入图片描述

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是MATLAB中使用Sobel算子进行边缘检测代码示例: ```matlab % 读取图像 img = imread('lena.png'); % 转换为灰度图像 gray_img = rgb2gray(img); % 定义Sobel算子 sobel_x = [-1 0 1; -2 0 2; -1 0 1]; sobel_y = [-1 -2 -1; 0 0 0; 1 2 1]; % 对图像进行卷积操作 Gx = conv2(double(gray_img), sobel_x, 'same'); Gy = conv2(double(gray_img), sobel_y, 'same'); % 计算边缘梯度和方向 gradient = sqrt(Gx.^2 + Gy.^2); theta = atan2(Gy, Gx); % 将梯度方向转换为整数值 theta = round(theta / (pi/4)) + 4; % 根据梯度方向进行非极大值抑制 [row, col] = size(gray_img); nms = zeros(row, col); for i = 2:row-1 for j = 2:col-1 if (theta(i,j)==1 && gradient(i,j)>gradient(i,j+1) && gradient(i,j)>gradient(i,j-1)) nms(i,j) = gradient(i,j); elseif (theta(i,j)==2 && gradient(i,j)>gradient(i+1,j+1) && gradient(i,j)>gradient(i-1,j-1)) nms(i,j) = gradient(i,j); elseif (theta(i,j)==3 && gradient(i,j)>gradient(i+1,j) && gradient(i,j)>gradient(i-1,j)) nms(i,j) = gradient(i,j); elseif (theta(i,j)==4 && gradient(i,j)>gradient(i+1,j-1) && gradient(i,j)>gradient(i-1,j+1)) nms(i,j) = gradient(i,j); end end end % 对非极大值抑制后的边缘进行双阈值处理 high_threshold = 0.1 * max(nms(:)); low_threshold = 0.05 * max(nms(:)); result = zeros(row, col); result(nms>high_threshold) = 1; result(nms>low_threshold & nms<high_threshold) = 0.5; % 显示图像边缘检测结果 figure; subplot(1,2,1), imshow(gray_img), title('原图'); subplot(1,2,2), imshow(result), title('边缘检测结果'); ``` 运行以上代码,即可得到Sobel算子边缘检测的结果。其中,`lena.png`是一个经典的测试图像,可以在网上下载得到。在代码中,我们首先将彩色图像转换为灰度图像,然后定义Sobel算子,对图像进行卷积操作,计算边缘梯度和方向。接着,根据梯度方向进行非极大值抑制,对边缘进行双阈值处理,得到最终的边缘检测结果。最后,使用MATLAB中的`imshow`函数显示原图和边缘检测结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值