9.1 算子及函数使用


Sobel 算子、Scharr 算子、Laplacian 算子都可以用作边缘检测


1. 参数ddepth

在 OpenCV 中,使用函数 cv2.convertScaleAbs()对参数取绝对值,该函数的语法格式为:
dst = cv2.convertScaleAbs( src [, alpha[, beta]] )
上式中:

  • dst 代表处理结果。
  • src 代表原始图像。
  • alpha 代表调节系数,该值是可选值,默认为 1。
  • beta 代表调节亮度值,该值是默认值,默认为 0。

这里,该函数的作用是将原始图像 src 转换为 256 色位图,其可以表示为:
dst=saturate(src*alpha+beta)

  • saturate()表示计算结果的最大值是饱和值,例如当“src*alpha+beta”的值超过 255 时, 其取值为 255。

【例 9.1】使用函数 cv2.convertScaleAbs()对一个随机数组取绝对值。

import cv2
import numpy as np

img = np.random.randint(-256,256,size=[4,5],dtype=np.int16)
rst = cv2.convertScaleAbs(img)

print("img=\n",img)
print("rst=\n",rst)

2. 方向

在函数 cv2.Sobel()中,参数 dx 表示 x 轴方向的求导阶数,参数 dy 表示 y 轴方向的求导阶 数。参数 dx 和 dy 通常的值为 0 或者 1,最大值为 2。如果是 0,表示在该方向上没有求导。当 然,参数 dx 和参数 dy 的值不能同时为 0。
参数 dx 和参数 dy 可以有多种形式的组合,主要包含:

  • 计算 x 方向边缘(梯度):dx=1, dy=0。
  • 计算 y 方向边缘(梯度):dx=0, dy=1。
  • 参数 dx 与参数 dy 的值均为 1:dx=1, dy=1。
  • 计算 x 方向和 y 方向的边缘叠加:通过组合方式实现。

2.1 计算x方向边缘(梯度):dx=1,dy=0

如果想只计算 x 方向(水平方向)的边缘,需要将函数 cv2.Sobel()的参数 dx 和 dy 的值设 置为“dx=1, dy=0”。当然,也可以设置为“dx=2, dy=0”。此时,会仅仅获取水平方向的边缘信 息,此时的语法格式为:
dst = cv2.Sobel( src , ddepth , 1 , 0 )

【例 9.2】使用函数 cv2.Sobel()获取图像水平方向的边缘信息。

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter9/sobel4.bmp")
sobelx = cv2.Sobel(img,-1,1,0)

cv2.imshow("original",img)
cv2.imshow("sobelx",sobelx)

cv2.waitKey()
cv2.destroyAllWindows()

从程序可以看出,当参数 ddepth 的值为-1 时,只得到了图中黑色框的右边界。这是因为, 左边界在运算时得到了负值,其在显示时被调整为 0,所以没有显示出来。要想获取左边界的 值(将其显示出来),必须将参数 ddepth 的值设置为更大范围的数据结构类型,并将其映射到 8 位图像内。

【例 9.3】使用函数 cv2.Sobel()获取图像水平方向的完整边缘信息。

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter9/sobel4.bmp")
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0)
sobelx = cv2.convertScaleAbs(sobelx)

cv2.imshow("original",img)
cv2.imshow("sobelx",sobelx)

cv2.waitKey()
cv2.destroyAllWindows()

2.2 计算y方向边缘(梯度):dx=0,dy=1

如果想只计算 y 方向(垂直方向)的边缘,需要将函数 cv2.Sobel()的参数 dx 和 dy 的值设 置为“dx=0, dy=1”。当然,也可以设置为“dx=0, dy=2”。此时,会仅仅获取垂直方向的边缘信 息,此时的语法格式为:
dst = cv2.Sobel( src , ddepth , 0 , 1 )

【例 9.4】使用函数 cv2.Sobel()获取图像垂直方向的边缘信息。

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter9/sobel4.bmp")
sobelx = cv2.Sobel(img,cv2.CV_64F,0,1)
sobelx = cv2.convertScaleAbs(sobelx)

cv2.imshow("original",img)
cv2.imshow("sobelx",sobelx)

cv2.waitKey()
cv2.destroyAllWindows()

2.3 参数dx与参数dy的值均为 1:dx=1,dy=1

可以将函数cv2.Sobel()的参数dx和dy的值设置为“dx=1, dy=1”,也可以设置为“dx=2, dy=2”,或者两个参数都不为零的其他情况。此时,会获取两个方向的边缘信息,此时的语法 格式为:
dst = cv2.Sobel( src , ddepth , 1 , 1 )

【例 9.5】当参数 dx 和 dy 的值为“dx=1, dy=1”时,查看函数 cv2.Sobel()的执行效果。

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter9/sobel4.bmp")
sobelx = cv2.Sobel(img,cv2.CV_64F,1,1)
sobelx = cv2.convertScaleAbs(sobelx)

cv2.imshow("original",img)
cv2.imshow("sobelx",sobelx)

cv2.waitKey()
cv2.destroyAllWindows()

2.4 4. 计算x方向和y方向的边缘叠加

如果想获取 x 方向和 y 方向的边缘叠加,需要分别获取水平方向、垂直方向两个方向的边 缘图,然后将二者相加。此时的语法格式为:
dx= cv2.Sobel( src , ddepth , 1 , 0 )
dy= cv2.Sobel( src , ddepth , 0 , 1 )
dst=cv2.addWeighted( src1 , alpha , src2 , beta , gamma )

【例 9.6】计算函数 cv2.Sobel()在水平、垂直两个方向叠加的边缘信息。

img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter9/sobel4.bmp")
dx = cv2.Sobel(img,cv2.CV_64F,1,0)
dx = cv2.convertScaleAbs(dx)
dy = cv2.Sobel(img,cv2.CV_64F,0,1)
dy = cv2.convertScaleAbs(dy)
dst = cv2.addWeighted(dx,0.5,dy,0.5,0)

cv2.imshow("original",img)
cv2.imshow("dst",dst)

cv2.waitKey()
cv2.destroyAllWindows()

从程序可以看出,本例中首先分别计算 x 方向的边缘、y 方向的边缘,接下来使用函数 cv2.addWeighted()对两个方向的边缘进行叠加。在最终的叠加边缘结果中,同时显示两个方向 的边缘信息。

【例 9.7】使用不同方式处理图像在两个方向的边缘信息。

在本例中,分别使用两种不同的方式获取边缘信息。

  • 方式 1:分别使用“dx=1, dy=0”和“dx=0, dy=1”计算图像在水平方向和垂直方向的边 缘信息,然后将二者相加,构成两个方向的边缘信息。
  • 方式 2:将参数 dx 和 dy 的值设为“dx=1, dy=1”,获取图像在两个方向的梯度。
img = cv2.imread("/Users/zhaofeier/Desktop/源代码及图像/chapter9/lena.bmp")

dx = cv2.Sobel(img,cv2.CV_64F,1,0)
dx = cv2.convertScaleAbs(dx)
dy = cv2.Sobel(img,cv2.CV_64F,0,1)
dy = cv2.convertScaleAbs(dy)
dst = cv2.addWeighted(dx,0.5,dy,0.5,0)

cv2.imshow("original",img)
cv2.imshow("dst",dst)

sobel = cv2.Sobel(img,cv2.CV_64F,1,1)
sobel = cv2.convertScaleAbs(sobel)

cv2.imshow("sobel",sobel)

cv2.waitKey()
cv2.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

暮棂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值