Opencv 入门(三)上

简介: 笔记

图像梯度


Sobel算子

dst= cv2.Sobel(src, ddepth, dx, dy, ksize)


ddepth:图像深度,都是默认-1,表示输入输出深度一样

dx,dy:分别表示水平和竖直方向, 置1表示计算该方向

ksize:是Sobel算子的大小,表示核的大小

第二个参数,使用 -1 表示输出与输入图像的数据类型一致。如果原图是uint8型,那么在sobel算子计算后,得到的图像可能会有负值,负值会被截断为0或者255。

两种方式:


改变输出图像的数据类型(第二个参数:cv2.CV_64F)

改变原始图像的数据类型,那么第二个参数可以是 -1

如果ksize=-1,默认3x3 的Scharr 滤波器,效果优于 3x3 的Sobel 滤波器


x, y方向的卷积核:


右边 - 左边,差异值作为水平方向

下面 - 上面,差异值作为垂直方向

1.jpg

由于只采用了2个方向的模板,只能检测水平和垂直方向的边缘,因此这种算法对于纹理较为复杂的图像,其边缘检测效果就不是很理想。该算法认为:凡灰度新值大于或等于阈值的像素点时都是边缘点。这会造成边缘点的误判,因为许多噪声点的灰度值也很大。

sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize=3)
sobelx = cv.convertScaleAbs(sobelx) # 绝对值转换, 负值取绝对值
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize=3)
sobely = cv.convertScaleAbs(sobely)
# 建议的做法,是利用 addWeighted 加权 x,y方向的图像,dx=1 && dy=1 效果较差
sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
res = np.hstack((sobelx, sobely, sobelxy))
show("res", res)

2.png

灰图读入,同上用法展示:

3.png

Scharr 算子

dst = cv2.Scharr(src,ddepth,dx,dy,scale,delta,borderType)


src: 原图像

ddepth: 输出图像的深度,该值与函数cv2.Sobel()中的参数ddepth的含义相同

dx: x方向上的求导阶数

dy: y方向上的求导阶数

scale: 计算导数时采用的缩放因子,默认为1,是没有缩放的

delta: 加在目标图像dst上的值,默认为0

borderType: 边界样式,默认值为cv2.BORDER_DEFAULT

scharr算子与Sobel的不同点是在平滑部分,这里所用的平滑算子是1/16∗[3,10,3],相比于1/4∗[1,2,1],中心元素占的权重更重,这可能是相对于图像这种随机性较强的信号,邻域相关性不大,所以邻域平滑应该使用相对较小的标准差的高斯函数,也就是更瘦高的模板。对一些细线,更敏感,更能描绘出。


4.png

Sobel算子与Scharr算子比较:

Sobel算子的缺点是,当结构较小时,精确度不高,Scharr算子具有更高的精度。


Laplacian算子

dst = cv2.Laplacian(src,ddepth,ksize,scale,delta,borderType)


src: 原图像

ddepth: 输出图像的深度。

ksize: 计算二阶导数的核尺寸大小,必须为正的奇数。

scale: 计算导数时采用的缩放因子,默认为1,是没有缩放的

delta: 加在目标图像dst上的值,默认为0

borderType: 边界样式,默认值为cv2.BORDER_DEFAULT

Laplacian算子是一种二阶导数算子,具有旋转不变性,可以满足不同方向的边缘检测要求。通常其算子的系数之和需要为0。

5.png

Canny边缘检测


使用高斯滤波器,以平滑图像,滤除噪声

计算图像中每个像素点的梯度强度和方向

应用非极大值抑制(Non-Maximun Suppression, NMS),以消除边缘检测带来的杂散响应

应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘

通过抑制孤立的弱边缘最终完成边缘检测

高斯滤波


大小为*(2k + 1) x (2k + 1)*的高斯滤波器核的生成方程式由下式给出:


6.png

一般选用 5 × 5 的核,(注意需要归一化)

7.png

  1. 计算梯度强度和方向
  • 梯度的方向与边缘的方向总是垂直的,通常取八个不同的方向计算梯度。
  • 再用边缘检测算子(Sobel)计算图像的水平,垂直,对角梯度,得到水平Gx和垂直Gy方向的一阶导数值,由此便可以确定像素点的梯度G的大小θ。

8.png

角度一般是近似到8个方向上


非极大值抑制(NMS)

非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。非极大值抑制可以将局部最大值之外的所有梯度值抑制为0。

对梯度图像中每个像素进行非极大值抑制的算法是:


将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。

如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。

经过上述处理后,对于同一个方向的若干边缘点,基本上只保留了一个,因此实现了边缘细化的目的。

如下图,A , B , C 三点中,梯度方向上A点的局部梯度值最大,所以保留A点,其余两点被抑制。


9.png

用双阈值算法检测和连接边缘

经过上述步骤后,图像内的强边缘已经在当前获取的边缘内,但是,一些虚边缘也在内。


设置两个阈值,高阈值maxVal、低阈值minVal。

根据边缘梯度值和阈值关系,判断边缘的属性:


梯度值 ≥ maxVal, 强边缘


minVal < 梯度值 < maxVal, 虚边缘


虚边缘与强边缘相连时,则保留。

梯度值 ≤ minVal, 抑制当前边缘


实际中maxVal:minVal = 2:1的比例效果比较好


抑制孤立低阈值点

到目前为止,被划分为强边缘的像素点已经被确定为边缘,因为它们是从图像中的真实边缘中提取出来的。然而,对于弱边缘像素,将会有一些争论,因为这些像素可以从真实边缘提取也可以是因噪声或颜色变化引起的。为了获得准确的结果,应该抑制由后者引起的弱边缘。通常,由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。


抑制孤立边缘点的伪代码描述如下:


10.png

Canny


cv2.Canny(image,threshold1,threshold2,apertureSize,L2gradient)


image :输入图像,必须为8位图像

threshold1: 第一个阈值

threshold2:第二个阈值

apertureSize: Sobel算子的大小

L2gradient: 计算图像梯度幅度的表示。默认值为False,使用L1范数计算;如果为True,则使用更精确的L2范数计算。


11.png

# 灰图读入
img = cv.imread(name + '_3.2.jpg', cv.IMREAD_GRAYSCALE)
# 高斯去噪
img = cv.GaussianBlur(img, (3, 3), 0)
# Canny检测
canny1 = cv.Canny(img, 128, 200)
canny2 = cv.Canny(img, 32, 128)
show('origin', img)
show('canny1', canny1)
show('canny2', canny2)
相关文章
|
7月前
|
计算机视觉 C++
11.【openCV计算机视觉入门基础】
11.【openCV计算机视觉入门基础】
46 0
|
3月前
|
存储 算法 C语言
OpenCV 即时入门(全)
OpenCV 即时入门(全)
83 0
|
4月前
|
机器学习/深度学习 算法 计算机视觉
python入门(六) opencv的安装,图片操作,绘制文字图形,视频操作
python入门(六) opencv的安装,图片操作,绘制文字图形,视频操作
|
4月前
|
存储 XML 计算机视觉
OpenCV 入门之旅
OpenCV 入门之旅
|
4月前
|
计算机视觉 索引 Python
分析”圣诞帽“代码,入门OpenCV
分析”圣诞帽“代码,入门OpenCV
分析”圣诞帽“代码,入门OpenCV
|
8月前
|
存储 Linux 计算机视觉
openCV之图像处理入门
openCV之图像处理入门
|
9月前
|
存储 计算机视觉 C++
【OpenCv】c++ 入门认识 Mat 类,单通道 Mat 的基本操作
【OpenCv】c++ 入门认识 Mat 类,单通道 Mat 的基本操作
186 0
|
10月前
|
计算机视觉 C++ Python
OpenCV入门(C++/Python)- 使用OpenCV进行图像旋转和转换(五)
OpenCV入门(C++/Python)- 使用OpenCV进行图像旋转和转换(五)
195 0
|
10月前
|
存储 C++ 计算机视觉
OpenCV入门(C++/Python)-使用OpenCV裁剪图像(四)
OpenCV入门(C++/Python)-使用OpenCV裁剪图像(四)
321 0
|
10月前
|
机器学习/深度学习 消息中间件 数据可视化
OpenCV入门(C++/Python)- 使用OpenCV调整尺寸大小(三)
OpenCV入门(C++/Python)- 使用OpenCV调整尺寸大小(三)
215 1