当前位置:   article > 正文

opencv-python图像处理:Canny边缘检测算法,模板匹配,直方图均衡化,傅里叶变换_python cv2 边缘匹配

python cv2 边缘匹配

1 Canny边缘检测流程

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

1.高斯滤波器
在这里插入图片描述
2.梯度和方向
在这里插入图片描述
3.非极大值抑制
在这里插入图片描述
4.双阈值检测
在这里插入图片描述

import cv2
import numpy as np


def cv_show(im, name):
    cv2.imshow(name, im)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread('data/test2.jpg', cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (400, 400))

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

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

结论:区间值越大,检测的边界越少;区间值越少,检测的边界越多。
在这里插入图片描述
在这里插入图片描述

2 图像金字塔

高斯金字塔
拉普拉斯金字塔
在这里插入图片描述
高斯金字塔:向下采样方法(缩小)
在这里插入图片描述
高斯金字塔:向上采样方法(放大)
在这里插入图片描述

import cv2
import numpy as np


def cv_show(im, name):
    cv2.imshow(name, im)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread('data/dog.jpg')
img = cv2.resize(img, (400, 400))

up = cv2.pyrUp(img)
cv_show(up, 'up')

down = cv2.pyrDown(img)
cv_show(down, 'down')

reset = cv2.pyrUp(down)
res = np.hstack([img, reset])
cv_show(res, 'res')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

上采样的结果
在这里插入图片描述
下采样的结果
在这里插入图片描述
原图和先上采样再下采样的图
在这里插入图片描述
拉普拉斯金字塔
在这里插入图片描述

import cv2
import numpy as np


def cv_show(im, name):
    cv2.imshow(name, im)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img = cv2.imread('data/dog.jpg')
img = cv2.resize(img, (400, 400))

up = cv2.pyrUp(img)
down = cv2.pyrDown(img)

reset = cv2.pyrUp(down)
res = np.hstack([img, reset, img - reset])
cv_show(res, 'res')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述

3 轮廓检测方法

cv2.findContours(img, mode, method)
mode:轮廓检索模式

  • RETR_EXTERNAL:只检索最外面的轮廓
  • RETR_LIST:检索所有的轮廓,并将其保存在列表中
  • RETER_CCOMP:检索所有的轮廓,并将它们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界
  • RETER_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次

method:轮廓逼近方法

  • CHAIN_APPROX_NONE:以Freema链码的方式输出轮廓,所有其他地方输出多边形(顶点序列)。
  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜外的部分,也就是,函数只是保留它们的终点部分。

4 模板匹配

模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv中有六种,将每次计算的结果放入一个矩阵里,作为结果输出。假如原图像是AxB大小,而模板是axb大小,则输出的结果矩阵是(A-a+1)x(B-b+1)
在这里插入图片描述

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
template = cv2.imread('data/face.png', cv2.IMREAD_GRAYSCALE)
w, h = template.shape[0], template.shape[1]
methods = ['cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_SQDIFF',
           'cv2.TM_SQDIFF_NORMED']
for meth in methods:
    img2 = img.copy()
    method = eval(meth)
    print(method)
    res = cv2.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED取最小值
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    # 画矩形
    cv2.rectangle(img2, top_left, bottom_right, 255, 2)

    plt.subplot(121), plt.imshow(res, cmap='gray')
    plt.xticks([]), plt.yticks([])
    plt.subplot(122), plt.imshow(img2, cmap='gray')
    plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5 图像直方图

在这里插入图片描述

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
res = cv2.calcHist(images=[img], channels=[0], mask=None, histSize=[256], ranges=[0, 256])
print(res.shape)  # (256, 1)
plt.hist(img.ravel(), 256)
plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('data/lena.png')
color = ('b', 'g', 'r')
for i, col in enumerate(color):
    histr = cv2.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(histr, color=col)
    plt.xlim([0, 256])
plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

6 傅里叶变换

傅里叶变换的作用

  • 高频:变化剧烈的灰度分量,例如边界
  • 低频:变化缓慢的灰度分量,例如一片大海

滤波

  • 低通滤波器:只保留低频,使得图像模糊
  • 高通滤波器:只保留高频,使得图像细节增强
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 得到灰度图能表示的形式
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('magnitude spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述

低通滤波器

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)

rows, cols = img.shape
c_row, c_col = int(rows / 2), int(cols / 2)  # 中心位置

# 低通滤波器
mask = np.zeros((rows, cols, 2), np.uint8)
mask[c_row - 30:c_row + 30, c_col - 30:c_col + 30] = 1

# IDFT
f_shift = dft_shift * mask
f_ishift = np.fft.ifftshift(f_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])

plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])

plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述

高通滤波器

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)

rows, cols = img.shape
c_row, c_col = int(rows / 2), int(cols / 2)  # 中心位置

# 高通滤波器
mask = np.ones((rows, cols, 2), np.uint8)
mask[c_row - 30:c_row + 30, c_col - 30:c_col + 30] = 0

# IDFT
f_shift = dft_shift * mask
f_ishift = np.fft.ifftshift(f_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])

plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])

plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/173429
推荐阅读
相关标签
  

闽ICP备14008679号