目录
import cv2
img = cv2.imread('pie.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
# 显示图像函数
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
4.1Sobel算子
颜色差别越大,梯度越高
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth:图像的深度
- dx和dy分别表示水平和竖直方向
- ksize是Sobel算子的大小
4.1.1负数——0
# Sobel算子——x轴
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) # 计算水平的
cv_show(sobel_x, 'sobel_x')
左边白,右边黑的原因:
梯度计算都是右边-左边
(白-黑)>0------白
(黑-白)<0------黑
4.1.2负数——绝对值
白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值
1.左右相减
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x) # 取绝对值
cv_show(sobel_x, 'sobel_x')
2.上下相减
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y) # 取绝对值
cv_show(sobel_y, 'sobel_y')
区别在于:sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
3.求和
建议:分别计算x,y之后再求和
或者
sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0) # 按权重计算
cv_show(sobel_xy, 'sobel_xy')
有一点点白线
不建议:直接计算
sobel_xy = cv2.Sobel(img, cv2.CV_64F, 1, 1, ksize=3)
sobel_xy = cv2.convertScaleAbs(sobel_xy)
cv_show(sobel_xy, 'sobel_xy')
有重影,模糊
4.1.3lean图片进行比较
1.分别进行计算
sobel_x = cv2.Sobel(img2, cv2.CV_64F, 1, 0, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
sobel_y = cv2.Sobel(img2, cv2.CV_64F, 0, 1, ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y)
sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)
cv_show(sobel_xy, 'sobel_xy')
2.一起计算
sobel_xy=cv2.Sobel(img2,cv2.CV_64F,1,1,ksize=3)
sobel_y=cv2.convertScaleAbs(sobel_xy)
cv_show(sobel_xy,'sobel_xy')
一起计算不清楚,模糊
4.2Scharr和Laplacian算子
4.2.1Scharr算子
更敏感
4.2.2Laplacian算子
对噪音点更敏感
4.2.3对比
import cv2
import numpy as np
# 不同算子的差异
img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
sobel_y = cv2.convertScaleAbs(sobel_y)
sobel_xy = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)
scharr_x = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharr_y = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharr_x = cv2.convertScaleAbs(scharr_x)
scharr_y = cv2.convertScaleAbs(scharr_y)
scharr_xy = cv2.addWeighted(scharr_x, 0.5, scharr_y, 0.5, 0)
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((img,sobel_xy, scharr_xy, laplacian))
# 显示图像函数
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
cv_show(res, 'res')
scharr算子描绘更加细致
Laplacian最好不要单独用,和其它算子共同使用
4.3边缘检测
Canny边缘检测
-
1) 使用高斯滤波器,以平滑图像,滤除噪声。
-
2) 计算图像中每个像素点的梯度强度和方向。
-
3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
-
4) 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
-
5) 通过抑制孤立的弱边缘最终完成边缘检测。
4.3.1高斯滤波器
4.3.2梯度和方向
4.3.3非极大值抑制
求得A点与周围两点C,B梯度的幅值大小,最大——保存,不是最大——抑制掉
4.3.4双阈值检测
A——边界
B,C要讨论
C与A(边界)有连接——保留
B无连接——舍去
import cv2
import numpy as np
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
v1 = cv2.Canny(img, 80, 150) # 设置双阈值 最小和最大
v2 = cv2.Canny(img, 50, 100)
res = np.hstack((v1, v2))
# 显示图像函数
def cv_show(img, name):
cv2.imshow(name, img)
cv2.waitKey()
cv2.destroyAllWindows()
cv_show(res, 'res')
v1 = cv2.Canny(img, 80, 150) # 设置双阈值 最小和最大
maxVal——值越高,标准越高
minVal——值越高,标准越高
差值更大:
img2 = cv2.imread('car.png', cv2.IMREAD_GRAYSCALE)
v1 = cv2.Canny(img2, 120, 250)
v2 = cv2.Canny(img2, 50, 100)
res_2 = np.hstack((v1, v2))
res_2=cv2.resize(res_2, None, fx=0.5, fy=0.5)
cv_show(res_2, 'res')
右边可以检测的信息更全一点