OpenCV学习过程(4)

目录

1.图像梯度-sobel算子

2.边缘检测

1.高斯滤波器 

2.梯度和方向

3.非极大值抑制

4.双阈值检测


1.图像梯度-sobel算子

计算图像梯度:

  1. 首先分成水平梯度和垂直梯度
  2. 水平梯度就是右减左,垂直梯度就是下减上
  3. 水平梯度表示Gx,垂直梯度表示Gy,分别与图像进行内积。就相当于卷积的过程。

G_{x}=\begin{bmatrix} -1 & 0&+1 \\ -2 & 0&+2 \\ -1 & 0&+1 \end{bmatrix}*A                  G_{y}=\begin{bmatrix} -1 & -2&-1 \\ 0 & 0&0 \\ +1 & +2&+1 \end{bmatrix}*A

首先读取一张灰度图像:

import cv2 
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline 
img = cv2.imread('image/pie.png',cv2.IMREAD_GRAYSCALE)
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()  
cv_show(img,'original')   

sobel梯度函数:

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

  • ddepth:图像的深度,默认值为-1
  • dx和dy分别表示水平和竖直方向
  • ksize是Sobel算子的大小

计算dx梯度:

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)  #dx=1就算dx

cv_show(sobelx,'sobelx')

 

由图像可以看到为什么它只显示左边的梯度,而右边的梯度不显示呢?

那是因为计算dx时,是右减左,所以计算右边半圆梯度的时候,计算结果为负数。在OpenCV中,它会自动把负数进行截断,变成0,所以右半圆就变成了黑色,只能显示左半圆。

下面取绝对值看一下:

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')

现在它就全部显示啦!

计算dy梯度:(和dx梯度一样,这里我就直接计算绝对值了)

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)  
cv_show(sobely,'sobely')

最后计算总梯度:

sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

2.图像梯度-scharr算子和laplacian算子

scharr算子:

G_{x}=\begin{bmatrix} -3 & 0&3 \\ 10 & 0&10 \\ -3 & 0&+3 \end{bmatrix}*A                  G_{y}=\begin{bmatrix} -3 & -10&-3 \\ 0 & 0&0 \\ +3 & 10&+3 \end{bmatrix}*A

laplacian算子:

G_{}=\begin{bmatrix} 0& 1&0 \\ 1 & -4&1 \\ 0 & 1&0 \end{bmatrix}*A

img = cv2.imread('image/lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)   
sobely = cv2.convertScaleAbs(sobely)  
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  #sobel算子

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)   
scharry = cv2.convertScaleAbs(scharry)  
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)  #scharr算子

laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)   #laplacian算子

res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')

原图展示:

 

这样我们就可以看到三个算子之间不同的差异,可以看到scharr算子更加的详细。

2.边缘检测

  1. 使用高斯滤波器,以平滑图像,滤除噪声。
  2. 计算图像中每个像素点的梯度强度和方向。
  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  5. 通过抑制孤立的弱边缘最终完成边缘检测。

1.高斯滤波器 

2.梯度和方向

3.非极大值抑制

4.双阈值检测

在这里我取了一个偏大的双阈值和一个偏小的双阈值

img=cv2.imread("image/lena.jpg",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)

res = np.hstack((v1,v2))
cv_show(res,'res')

可以看到阈值为(50, 100)比(80, 150)更加详细。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值