opencv_18 Sobel边缘提取

//边缘是像素发生阶跃的地方,使图像的显著特征之一,对图像求一阶导数,提取边缘。
//对图像求导,如下图。左边是原图像素图像,右边是像素变化率的图像。
在这里插入图片描述
//Sobel 算子:计算图像灰度的近似梯度。
//Sobel 算子集合了高斯平滑和微分求导,在x,y
方向上求导,得到X,Y方向上的梯度。
//下图是Sobel算子的卷积核,引入权重增大像素差异,提取边缘,左边是X梯度,右边是Y梯度。
在这里插入图片描述
//最后将X,Y方向的梯度融合,绝对值和的形式可以减小运算量。优化算法
在这里插入图片描述
//以下代码是,像素梯度平方和开根号的结果

for (int row = 0; row < height; row++)
	{
		for (int column = 0; column <width ; column++)
		{
			int xg=Xgrad.at<char>(row, column);
			int yg = Ygrad.at<char>(row, column);
			int xyg = sqrt(xg*xg + yg*yg);
			imgmix.at<char>(row, column) = saturate_cast<char>(xyg);
		}
	}

在这里插入图片描述
//Sobel API
Sobel(输入图像(灰度图),输出图像,输出图像深度,X方向导数,Y方向导数, ksize(卷积核大小),scale=1(图像缩放),delta=0(像素增亮),borderType=BORDER_DEFAULT);
//此处对图像深度做特殊说明,输出图像深度应该大于输入图像深度。(-1是默认值,这里通常不取)
//但输出图像的类型仍然是八位.
在这里插入图片描述
//代码步骤:
1.因为Sobel对噪声格外敏感,先对图像高斯模糊。
2.装灰度
3.求梯度X,Y
4.混合X,Y梯度
//convertScaleAbs(对像素梯度取绝对值,梯度有可能是负的)
//以下是操作的两种方式,一种是基于API,一种是基于像素搜索。

Mat src = imread("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\timg6ZAGKYHR.jpg");
	if (src.empty())
	{
		printf("ould not find image \n");
		return -1;
	}
	namedWindow("opencv set up demo", WINDOW_AUTOSIZE);
	imshow("opencv set up demo", src);
	Mat dst, gray_sc;
	GaussianBlur(src, dst, Size(3, 3), 0, 0);
	cvtColor(dst, gray_sc, COLOR_BGR2GRAY);


	Sobel(gray_sc, Xgrad, CV_32F, 1, 0, 3);
	Sobel(gray_sc, Ygrad, CV_32F, 1, 0, 3);
	convertScaleAbs(Xgrad, Xgrad);
	convertScaleAbs(Ygrad, Ygrad);
	printf("%d", Ygrad.type());
	imshow("xgrad", Xgrad);
	imshow("ygrad", Ygrad);
	Mat imgmix;
	addWeighted(Xgrad, 1, Ygrad, 1,0, imgmix);

//基于像素搜索

Mat src = imread("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\timg6ZAGKYHR.jpg");
	if (src.empty())
	{
		printf("ould not find image \n");
		return -1;
	}
	namedWindow("opencv set up demo", WINDOW_AUTOSIZE);
	imshow("opencv set up demo", src);
	Mat dst, gray_sc;
	GaussianBlur(src, dst, Size(3, 3), 0, 0);
	cvtColor(dst, gray_sc, COLOR_BGR2GRAY);


	Sobel(gray_sc, Xgrad, CV_32F, 1, 0, 3);
	Sobel(gray_sc, Ygrad, CV_32F, 1, 0, 3);
	convertScaleAbs(Xgrad, Xgrad);
	convertScaleAbs(Ygrad, Ygrad);
	printf("%d", Ygrad.type());
	imshow("xgrad", Xgrad);
	imshow("ygrad", Ygrad);
	Mat imgmix;
	//addWeighted(Xgrad, 1, Ygrad, 1,0, imgmix);
	Mat imgmix=Mat(Xgrad.size(),Xgrad.type());
	int height = Xgrad.rows;
	int width = Ygrad.cols;
	for (int row = 0; row < height; row++)
	{
		for (int column = 0; column <width ; column++)
		{
			int xg=Xgrad.at<char>(row, column);
			int yg = Ygrad.at<char>(row, column);
			int xyg = xg + yg;
			imgmix.at<char>(row, column) = saturate_cast<char>(xyg);
		}
	}

	imshow("sobel", imgmix);

在这里插入图片描述

//opencv 自己有Scharr(输入灰度图,输出,输出图向深度,x方向梯度,y方向梯度,缩放scale,delta(像素增值))
Scharr(gray_sc, Ygrad, CV_32F, 1, 0, 1, 0);
Soble易受噪声影响,Scharr不易受影响
在这里插入图片描述

	Mat src = imread("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\timg6ZAGKYHR.jpg");
	if (src.empty())
	{
		printf("ould not find image \n");
		return -1;
	}
	namedWindow("opencv set up demo", WINDOW_AUTOSIZE);
	imshow("opencv set up demo", src);
	Mat dst, gray_sc;
	GaussianBlur(src, dst, Size(3, 3), 0, 0);
	cvtColor(dst, gray_sc, COLOR_BGR2GRAY);
	Mat Xgrad, Ygrad;
	Scharr(gray_sc, Xgrad, CV_32F, 1, 0, 1, 0);
	Scharr(gray_sc, Ygrad, CV_32F, 1, 0, 1, 0);

	//Sobel(gray_sc, Xgrad, CV_32F, 1, 0, 3);
	//Sobel(gray_sc, Ygrad, CV_32F, 1, 0, 3);
	convertScaleAbs(Xgrad, Xgrad);
	convertScaleAbs(Ygrad, Ygrad);
	printf("%d", Ygrad.type());
	imshow("xgrad", Xgrad);
	imshow("ygrad", Ygrad);
	Mat imgmix;
	//addWeighted(Xgrad, 1, Ygrad, 1,0, imgmix);
	Mat imgmix=Mat(Xgrad.size(),Xgrad.type());
	int height = Xgrad.rows;
	int width = Ygrad.cols;
	for (int row = 0; row < height; row++)
	{
		for (int column = 0; column <width ; column++)
		{
			int xg=Xgrad.at<char>(row, column);
			int yg = Ygrad.at<char>(row, column);
			int xyg = xg + yg;
			imgmix.at<char>(row, column) = saturate_cast<char>(xyg);
		}
	}

	imshow("sobel", imgmix);

	waitKey(0);

//saturate_cast(xyg);将像素值限制在0-255之间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值