[OpenCV学习日记-java]-09-梯度计算和拉普拉斯算子

梯度计算和拉普拉斯算子

计算机图像梯度是很多重要特征提取的关键步骤之一,OpenCV提供了两个非常重要的计算梯度函数Sobel与Scharr

对于图像边缘部分,梯度值会比较大,对于图像的平坦区域梯度值一般比较小

Sobel梯度

Sobel梯度算子可以计算X方向和Y方向Api如下:

Sobel(Mat src, Mat dst, int ddepth, int dx, int dy)
  • src:输入图像

  • dst:输出图像

  • ddepth:输出图像深度
    通常为 CV_32F 或者 CV_32SC
     
    这里需要注意的是 不能让输入如下与输入图像深度相同,当输入图像是8bit时候计算数据会有所溢出,从而导致梯度计算错误

  • dx:表示x方向计算
    1是 2不是

  • dy:表示y方向计算
    1是 2不是

  • int ksize:为进行边缘检测时的模板大小为ksizeksize,取值为1、3、5和7,其中默认值为3。特殊情况:ksize=1时,采用的模板为31或1*3。
    当ksize=3时,Sobel内核可能产生比较明显的误差;

下面通过代码演示

Mat m1 = Imgcodecs.imread("C:\\test\\256_256_t1.png" );

HighGui.imshow("原图",m1);

Imgproc.cvtColor(m1,m1,Imgproc.COLOR_BGR2GRAY);

Mat s1 = new Mat();
Imgproc.Sobel(m1,s1, CvType.CV_32F,1,0);//x方向

//Mat转换成8位,如果不写将不能展示
Core.convertScaleAbs(s1,s1);

Mat s2 = new Mat();
Imgproc.Sobel(m1,s2, CvType.CV_32F,0,1);//y方向
Core.convertScaleAbs(s2,s2);

Mat s3 = new Mat();
Core.add(s1,s2,s3); //图像相加

HighGui.imshow("X方向",s1);
HighGui.imshow("Y方向",s2);
HighGui.imshow("相加后",s3);

这样就把边缘提取出来了

这里需要注意的是下面这一个代码

Core.convertScaleAbs(Mat src, Mat dst);

这个方法就是转换成8位图像

在这里插入图片描述


Scharr梯度

Scharr是Sobel的升级加强版本

Api如下:

Scharr(Mat src, Mat dst, int ddepth, int dx, int dy)

这里和Sobel方法一样 ,所以这里就不一个个解释了

完全可以直接把Sobel直接改成Scharr

Mat m1 = Imgcodecs.imread("C:\\test\\256_256_t1.png" );

HighGui.imshow("原图",m1);

Imgproc.cvtColor(m1,m1,Imgproc.COLOR_BGR2GRAY);

Mat s1 = new Mat();
Imgproc.Scharr(m1,s1, CvType.CV_32F,1,0);//x方向

//Mat转换成8位,如果不写将不能展示
Core.convertScaleAbs(s1,s1);

Mat s2 = new Mat();
Imgproc.Scharr(m1,s2, CvType.CV_32F,0,1);//y方向
Core.convertScaleAbs(s2,s2);

Mat s3 = new Mat();
Core.add(s1,s2,s3); //图像相加

HighGui.imshow("X方向",s1);
HighGui.imshow("Y方向",s2);
HighGui.imshow("相加后",s3);

在这里插入图片描述


拉普拉斯算子

拉普拉斯算子可以用在图片增强,也可以用扎边缘检测,但是会很麻烦

Laplacian(Mat src, Mat dst, int ddepth, int ksize, double scale, double delta) 
  • src:输入图像
  • dst:输出图像
  • ddepth:输出图像深度,常见的是CV_32F
  • ksize:常见的是3x3 ksize = 3
  • scale:是否缩放 默认=1
  • delta:是否调整图像 默认 = 0

下面通过代码演示

Mat m1 = Imgcodecs.imread("C:\\test\\256_256_t1.png" );
 
HighGui.imshow("原图",m1);

Mat s1 = new Mat();
Imgproc.Laplacian(m1,s1, CvType.CV_32F);

Core.convertScaleAbs(s1,s1);

Mat s2 = new Mat();
Imgproc.Laplacian(m1,s2, CvType.CV_32F,3,1,0);//ksize = 3

Core.convertScaleAbs(s2,s2);

HighGui.imshow("默认ksize",s1);
HighGui.imshow("ksize=3",s2);

在这里插入图片描述


上一篇[OpenCV学习日记-java]-08-阈值化和阈值
下一篇[OpenCV学习日记-java]-10-Canny边缘检测
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Timeless小帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值