OpenCV-边缘检测和图像金字塔

1、 Canny边缘检测

  1. 噪声去除
    由于边缘检测很容易受到噪声影响,所以第一步使用5x5的高斯滤波器去除噪音。
  2. 计算图像梯度
    对平滑后的图像使用Sobel算子计算水平方向和竖直方向的一阶导数(图像梯度)(Gx和Gy)。根据得到的两幅梯度图(Gx和Gy)找到边界的梯度和方向。公式如下:
    OpenCV-边缘检测和图像金字塔_第1张图片
  3. 梯度
    梯度的方向一般总是与边界垂直。梯度方向被归为四类:垂直,水平,和两个对角线。
  4. 非极大值抑制
    在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的。最后得到一个包含“窄边界”的二值图像。
  5. 滞后阈值
    现在要确定哪些边界才是真正的边界,这时需要设置两个阈值:minVal和maxVal。当图像的灰度梯度高于maxVal时被认为是真的边界,哪些低于minVal的边界会被抛弃。介于两者之间的,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为是边界,如果不是就抛弃。

2、OpenCV中的Canny边界检测

  1. 在OpenCV中只需要一个函数:cv2.Canny(),就可以完成以上几步。
    参数1:输入的图像 参数2,3:分别是minVal和macVal
    参数4:L2gradient,可以用来设定求梯度大小的方程。如果设为True,就会上面提到的方程式,否则使用Edge-Gradient(G) =|G2 x} + |G2 y| 代替,默认值为 False。
    import cv2  import numpy as np 
    from matplotlib import pyplot as plt 

    img = cv2.imread("./image/test3.jpg", 0) edges = cv2.Canny(img, 100,
    200)

    plt.subplot(121),plt.imshow(img, cmap='gray') plt.title("Original")
    plt.subplot(122),plt.imshow(edges, cmap='gray') plt.title("Edge")
    plt.show()

2、 图像金字塔

  1. 原理
    不知道目标在图像中的尺寸大小。这种情况下,需要创建一组图像,这些图像是具有不同分辨的原始图像。So叫做图像金字塔。有两类图像金字塔:高斯金字塔和拉普拉斯金字塔。
    高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图像中5个像素的高斯加权平均值。这样操作一次一个
    MxN 的图像就变成了一个 M/2xN/2 的图像。所以这幅图像的面积就变为原来图像面积的四分之一。这被称为
    Octave。连续进行这样的操作我们就会得到一个分辨率不断下降的图像金字塔。我们可以使用函数cv2.pyrDown() 和
    cv2.pyrUp() 构建图像金字塔
    函数cv2.pyrDown()从一个高分辨率大尺寸的图像向上构建一个金字塔(尺寸变小,分辨率降低)。 函数 cv2.pyrUp()
    从一个低分辨率小尺寸的图像向下构建一个金子塔(尺寸变大,但分辨率不会增加)。
    一旦使用cv2.pyrDown(),图像的分辨率就会下降,信息就会被丢失。 拉普拉斯金字塔可以有高斯金字塔计算得来,公式如下: Li = Gi – PyrUp(Gi+1) 拉普拉斯金字塔的图像看起来就像边界图,其中很多像素都是0。经常被用来在图像压缩中。
  2. 使用金字塔进行图像融合
    图像金字塔的一个应用是图像融合。 如苹果橘子的融合步骤:
    1. 读入两幅图像,苹果和橘子
    2. 构建苹果和橘子的高斯金字塔(6层)
    3. 根据高斯金字塔计算拉普拉斯金字塔
    4. 在拉普拉斯的每一层进行图像融合(一边一半)
    5. 根据融合后的图像金字塔重新构建原图像
import cv2
import numpy as np 
A = cv2.imread('./image/apple.jpg')
B = cv2.imread('./image/orange.jpg')
G = A.copy()
gpA = [G]
for i in range(6):
    G = cv2.pyrDown(G)
    gpA.append(G)
G = B.copy()
gpB = [G]
for i in range(6):
    G = cv2.pyrDown(G)
    gpB.append(G)
lpA = [gpA[5]]
for i in range(5, 0, -1):
    GE = cv2.pyrUp(gpA[i])
    L = cv2.subtract(gpA[i-1], GE)
    lpA.append(L)
lpB = [gpB[5]]
for i in range(5, 0, -1):
    GE = cv2.pyrUp(gpB[i])
    L = cv2.subtract(gpB[i-1], GE)
    lpB.append(L)
LS = []
for la, lb in zip(lpA, lpB):
    rows, cols, dpt = la.shape
    ls = np.hstack((la[:, 0:cols/2], lb[:, cols/2:]))
    LS.append(ls)
ls_ = LS[0]
for i in range(1, 6):
    ls_ = cv2.pyrUp(ls_)
    ls_ = cv2.add(ls_, LS[i])
real = np.hstack((A[:,:cols/2],B[:,cols/2:]))
cv2.imwrite('Pyramid_blending2.jpg', ls_)
cv2.imwrite('Direct_blending.jpg', real)

本节较为简单,理论知识居多,程序也简单,就没有做出具体的工具使用;在之前的章节所有的工具使用的都是python3.6+PyQt5+matplotlib+openCV3中的知识,如果有什么疑问请留言,如需要源码请联系邮箱:[email protected]

你可能感兴趣的:(python,opencv,matplotlib)