本小节代码在配套资料“iTOP-3568 开发板\03_【iTOP-RK3568 开发板】指南教程
\04_OpenCV 开发配套资料\32”目录下,如下图所示:
Sobel (索贝尔)算子是计算机视觉领域的一种重要处理方法。主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。
索贝尔算子把图像中每个像素的上下左右四领域的灰度值加权差,在边缘处达到极值从而检测边缘。在技术上,它是一离散性差分算子,用来运算图像亮度函数的梯度之近似值。在图像
的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。
索贝尔算子不但能产生较好的检测效果,而且对噪声有着平滑抑制作用,是最为常用的边缘检测算子,但是得到的边缘较粗,可能出现伪边缘。
cv2.Sobel 函数功能:
使用 Sobel 算子进行边缘检测。
函数原型:
dst = cv2.Sobel( src, ddepth, dx, dy[,ksize[, scale[, delta[, borderType]]]] )
参数定义:
dst 代表目标图像。
src 代表原始图像。
ddepth 代表输出图像的深度。
dx 代表 x 方向上的求导阶数。
dy 代表 y 方向上的求导阶数。
ksize 代表 Sobel 核的大小。该值为-1 时,则会使用 Scharr 算子进行运算。
scale 代表计算导数值时所采用的缩放因子,默认情况下该值是 1,是没有缩放的。
delta 代表加在目标图像 dst 上的值,该值是可选的,默认为 0。
borderType 代表边界样式。
而在实际操作中,计算梯度值可能会出现负数。通常处理的图像是 8 位图类型,如果结果也是该类型,那么所有负数会自动截断为 0,发生信息丢失。所以,为了避免信息丢失,在
计算时使用更高的数据类型 cv2.CV_64F,再通过取绝对值将其映射为 cv2.CV_8U(8 位图)类型。故此还需要调用 convertScaleAbs()函数计算绝对值,并将图像转换为 8 位图进行显示。其算法原型如下:
dst = convertScaleAbs(src[, dst[, alpha[, beta]]])
参数定义:
dst 代表处理结果。
src 代表原始图像。
alpha 代表调节系数,该值是可选值,默认为 1。
beta 代表调节亮度值,该值是默认值,默认为 0。
实验:
实验要求:
使用 cv2.Sobel 函数,分别对 x 轴和 y 轴进行边缘检测,随后使用 cv2.addWeighted 函数以0.5:0.5 的比例将两个图像进行融合,最后使用 cv2.imshow()函数对原图和边缘检测的三个图
像进行展示。
实验步骤:
首先进入到 ubuntu 的终端界面将“iTOP-3568 开发板\03_【iTOP-RK3568 开发板】指南教程\04_OpenCV 开发配套资料\32”路径下的 number.png 拷贝到 ubuntu 虚拟机上,拷贝完成如
下图所示:
然后来到 ubuntu 虚拟机的终端界面,输入以下命令来创建 demo32_Sobel.py 文件,如下图所示:
vim demo32_Sobel.py
然后向该文件中添加以下内容:
1 import cv2 #opencv 的缩写为 cv2,导入 opencv
2 img = cv2.imread('number.png',1) #flags 参数为 1,返回彩色图像
3 cv2.imshow('原图',img)#通过 cv2.imshow()函数展示原图
4 sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)# 使用 Sobel 算子进行边缘检测,数据类型设置为 cv2.CV_64F,
5 只算 x 方向梯度,Sobel 核大小设置为 3
6 sobelx = cv2.convertScaleAbs(sobelx) # 计算绝对值
7 cv2.imshow('sobelx',sobelx)#通过 cv2.imshow()函数展示 x 方向梯度边缘检测计算之后的图像
8 sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) #使用 Sobel 算子进行边缘检测,数据类型设置为 cv2.CV_64F,
9 只算 x 方向梯度,Sobel 核大小设置为 3
10 sobely = cv2.convertScaleAbs(sobely) #计算绝对值
11 cv2.imshow('sobely',sobely)#通过 cv2.imshow()函数展示 y 方向梯度边缘检测计算之后的图像
12 sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) # 图像融合的系数比为 0.5:0.5,0 表示偏置项
13 cv2.imshow('sobelxy',sobelxy)#通过 cv2.imshow()函数展示融合之后的图像
14 cv2.waitKey(0)#等待下一次按键按下
第 1 行导入了 opencv 库;
第 2 行使用了 imread()函数对 number.png 图片进行读取;
第 3 行使用了 imshow()函数对原图像进行展示;
第 4 行使用 Sobel 算子进行边缘检测计算,数据类型设置为 cv2.CV_64F,只算 x 方向梯
度,Sobel 核大小设置为 3;
第 8 行使用 Sobel 算子进行边缘检测计算,数据类型设置为 cv2.CV_64F,只算 y 方向梯度,Sobel 核大小设置为 3;
第 6 行和第 10 行使用了 convertScaleAbs()函数获取绝对值,并将图像转换为 8 位;
第 7 行和第 11 行使用了 imshow()函数对两个方向梯度进行边缘检测计算之后的图像进行展示;
第 12 行使用了 addWeighted()函数进行图像融合,两个图像的融合系数比为 0.5:0.5;
第 13 行使用了 imshow()函数对融合之后的图像进行展示;
第 14 行使用了 waitKey()函数,持续显示展示照片直到按键的按下。
保存退出之后,在终端界面中输入以下命令进行 python 代码的运行,运行结果如下图所示:
python demo32_Sobel.py
第 1 张图为原图,一个数独图像被显示了出来,第 2 张图像为 x 轴方向梯度经过边缘检测计算的图像,可以看到纵向的线条被很好的区分了出来,第 3 张图像为 y 轴方向梯度经过边缘
检测计算的图像,可以看到横向的线条被很好的区分了出来,第 4 张图像为两张边缘计算图像的融合,可以看到图像的边缘特点被很好的展现了出来,至此 Sobel 算子边缘计算相关的实验
就结束了。