Android(安卓)opencv(三) 边缘检测Sobel、Canny
16lz
2022-04-14
Sobel
Sobel是检测边缘的一阶导数,在检测边缘前需要通过滤波(blur)去噪来使图片光滑,一般使用高斯滤波,大小取7x7.
//高斯滤波 public static Mat removeNoiseGaussianBlur(Mat srcMat){ final Mat blurredImage=new Mat(); Size size=new Size(7,7); Imgproc.GaussianBlur(srcMat,blurredImage,size,0,0); return blurredImage; }
之后进行灰度处理
//灰度处理 public static Mat grayImage(Mat srcMat){ Mat grayImg=new Mat(); Imgproc.cvtColor(srcMat,grayImg,Imgproc.COLOR_RGB2GRAY); return grayImg; }
下面是sobel进行过程
//声明x,y的一阶导数 Mat xDervative=new Mat(); Mat yDervative=new Mat(); /*一般输入图片的depth与输出图片的depth值相同,但是当我们一阶导数的时候会出现负数-255—255,使用unsignded 8-bit depth只能包含0-255,因此采用了16-bit */ int ddepth= CvType.CV_16S; //计算x,y的一阶导数,参数1,0来设置x,y轴 Imgproc.Sobel(srcMat,xDervative,ddepth,1,0); Imgproc.Sobel(srcMat,yDervative,ddepth,0,1); Mat absXD=new Mat(); Mat absYD=new Mat(); //Mat转换 Core.convertScaleAbs(xDervative,absXD); Core.convertScaleAbs(yDervative,absYD); //根号(x*x+y*y) Mat edgeImage=new Mat(); Core.addWeighted(absXD,0.5,absYD,0.5,0,edgeImage);
Canny
canny检测仅在灰度图下,同时滤波只能采用高斯滤波,原因如下:
Canny算子在选择滤波器时有两个标准,首先滤波器在频域中应该是有限带宽的,这样才能保证减少由于频率的变化而导致的图像函数的变化;其次,canny经典论文中“Good Localization”标准要求滤波器的响应需要来自于图像中邻近的点。要知道,上述两个标准相互间是矛盾的,频域有限说明时域无限,而高斯分布可以较好的使上述两个标准得到优化,因为高斯函数的离中心超过3倍标准差以外的像素的影响可以忽略不计,同时高斯函数在频域上也是有限带宽的,因此才使用高斯滤波
在Canny边缘检测算法中,将图像中的点归为三类:
被抑制点
灰度梯度值 < 低阈值
弱边缘点
低阈值 <= 灰度梯度值 <= 高阈值
强边缘点
高阈值 < 灰度梯度值
ps:canny边缘检测是通过梯度与夹角进行检测,具体原理参考下面链接,大于最大阈值的线被确认是边缘线条,小于最小阈值的线被抛弃,在最大阈值与最小阈值之间的线条如果线条的边缘有明确的边缘线交点则被认为是在一条线上,从而被保留,否则被抛弃。
https://docs.opencv.org/3.3.1/da/d22/tutorial_py_canny.html
//canny边缘检测 public static Mat cannyEdge(Mat srcMat){ final Mat edgeImage=new Mat(); //100低阈值 200:高阈值 Imgproc.Canny(srcMat,edgeImage,100,200); return edgeImage; }
自适应阈值Canny边缘检测
http://blog.csdn.net/tianzhaixing2013/article/details/53504426
更多相关文章
- Android布局详解
- android布局属性总结备用
- Android控件属性大全[整理]
- RelativeLayout常用属性介绍
- RelativeLayout常用属性介绍
- android坐标
- android 图片灰度处理的处理
- RelativeLayout常用属性介绍
- mt6735平台wifi漫游阈值