当前位置:   article > 正文

canny边缘检测算法的python实现

canny边缘检测算法的python实现


前言

Canny边缘检测算子是John F. Canny于1986年开发出来的一个多级边缘检测算法。更为重要的是Canny创立了“边缘检测计算理论”(computational theory of edge detection)解释这项技术如何工作。(摘自百度百科)


一、canny边缘检测算法是什么?

边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。而canny边缘检测算法就是为了解决这个问题提出来的一种解决模式。(摘自百度百科)

二、使用步骤

1.引入库

代码如下:

import cv2
import numpy as np
  • 1
  • 2

2.读入数据并处理数据

代码如下:

# 读取图像
grey = cv2.imread('lena.png')#读图
#进行图像数据处理
grey1 = cv2.cvtColor(grey, cv2.IMREAD_GRAYSCALE)
img =np.array( [[0]*512]*512 )
for k in range(0,512):
    for i in range(0,512):
        img[k][i]=grey1[k][i][0]
img = np.uint8(img)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.高斯滤波

代码如下:

# 高斯滤波
kernel_size = 5   #高斯卷积核函数,老师推荐为3,但3的效果不如5
sigma = 1.4
img_blur = cv2.GaussianBlur(img, (kernel_size, kernel_size), sigma)
  • 1
  • 2
  • 3
  • 4

4.计算梯度和方向

代码如下:

# 计算梯度和方向
sobel_x = cv2.Sobel(img_blur, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(img_blur, cv2.CV_64F, 0, 1, ksize=3)
grad_mag = np.sqrt(sobel_x ** 2 + sobel_y ** 2)
grad_dir = np.arctan2(sobel_y, sobel_x)
  • 1
  • 2
  • 3
  • 4
  • 5

5.非极大值抑制

代码如下:

# 非极大值抑制
grad_mag_max = np.zeros(grad_mag.shape)
for i in range(1, grad_mag.shape[0] - 1):
    for j in range(1, grad_mag.shape[1] - 1):
        #如果角度小于0,使其加上一个pi,量化至四个方向
        if grad_dir[i, j] < 0:
            grad_dir[i, j] += np.pi
        if np.pi / 8 <= grad_dir[i, j] < 3 * np.pi / 8:
            if grad_mag[i, j] > grad_mag[i - 1, j - 1] and grad_mag[i, j] > grad_mag[i + 1, j + 1]:
                grad_mag_max[i, j] = grad_mag[i, j]
        elif 3 * np.pi / 8 <= grad_dir[i, j] < 5 * np.pi / 8:
            if grad_mag[i, j] > grad_mag[i - 1, j] and grad_mag[i, j] > grad_mag[i + 1, j]:
                grad_mag_max[i, j] = grad_mag[i, j]
        elif 5 * np.pi / 8 <= grad_dir[i, j] < 7 * np.pi / 8:
            if grad_mag[i, j] > grad_mag[i - 1, j + 1] and grad_mag[i, j] > grad_mag[i + 1, j - 1]:
                grad_mag_max[i, j] = grad_mag[i, j]
        else:
            if grad_mag[i, j] > grad_mag[i, j - 1] and grad_mag[i, j] > grad_mag[i, j + 1]:
                grad_mag_max[i, j] = grad_mag[i, j]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

6.双阈值处理

代码如下:

# 双阈值处理,不是简单的循环,而是递归
low_threshold = 10
high_threshold = 30
edges = np.zeros(grad_mag_max.shape)
strong_edges = (grad_mag_max > high_threshold)
weak_edges = (grad_mag_max >= low_threshold) & (grad_mag_max <= high_threshold)
edges[strong_edges] = 1
while np.sum(weak_edges) > 0:
    i, j = np.unravel_index(weak_edges.argmax(), weak_edges.shape)   #.argmax()返回第一个参数   .shanpe返回矩阵各维数量(512*512)  np.unravel_index求索引值
    weak_edges[i, j] = 0
    if strong_edges[i - 1:i + 2, j - 1:j + 2].any():            #.any() 判断迭代参数是否全是false
        edges[i, j] = 1
        strong_edges[i, j] = 1
    else:
        edges[i, j] = 0
out = edges
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

7.显示结果

代码如下:

# 显示结果
cv2.imshow('output',out)
cv2.waitKey(0)
  • 1
  • 2
  • 3

8.完整代码

如下:

import cv2
import numpy as np
# 读取图像
grey = cv2.imread('lena.png')#读图
#进行图像数据处理
grey1 = cv2.cvtColor(grey, cv2.IMREAD_GRAYSCALE)
img =np.array( [[0]*512]*512 )
for k in range(0,512):
    for i in range(0,512):
        img[k][i]=grey1[k][i][0]
img = np.uint8(img)
# 高斯滤波
kernel_size = 5   #高斯卷积核函数,老师推荐为3,但3的效果不如5
sigma = 1.4
img_blur = cv2.GaussianBlur(img, (kernel_size, kernel_size), sigma)

# 计算梯度和方向
sobel_x = cv2.Sobel(img_blur, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(img_blur, cv2.CV_64F, 0, 1, ksize=3)
grad_mag = np.sqrt(sobel_x ** 2 + sobel_y ** 2)
grad_dir = np.arctan2(sobel_y, sobel_x)

# 非极大值抑制
grad_mag_max = np.zeros(grad_mag.shape)
for i in range(1, grad_mag.shape[0] - 1):
    for j in range(1, grad_mag.shape[1] - 1):
        #如果角度小于0,使其加上一个pi,量化至四个方向
        if grad_dir[i, j] < 0:
            grad_dir[i, j] += np.pi
        if np.pi / 8 <= grad_dir[i, j] < 3 * np.pi / 8:
            if grad_mag[i, j] > grad_mag[i - 1, j - 1] and grad_mag[i, j] > grad_mag[i + 1, j + 1]:
                grad_mag_max[i, j] = grad_mag[i, j]
        elif 3 * np.pi / 8 <= grad_dir[i, j] < 5 * np.pi / 8:
            if grad_mag[i, j] > grad_mag[i - 1, j] and grad_mag[i, j] > grad_mag[i + 1, j]:
                grad_mag_max[i, j] = grad_mag[i, j]
        elif 5 * np.pi / 8 <= grad_dir[i, j] < 7 * np.pi / 8:
            if grad_mag[i, j] > grad_mag[i - 1, j + 1] and grad_mag[i, j] > grad_mag[i + 1, j - 1]:
                grad_mag_max[i, j] = grad_mag[i, j]
        else:
            if grad_mag[i, j] > grad_mag[i, j - 1] and grad_mag[i, j] > grad_mag[i, j + 1]:
                grad_mag_max[i, j] = grad_mag[i, j]

# 双阈值处理,注意:双阈值二值化是一种递归而不是简单的循环
low_threshold = 10
high_threshold = 30
edges = np.zeros(grad_mag_max.shape)
strong_edges = (grad_mag_max > high_threshold)
weak_edges = (grad_mag_max >= low_threshold) & (grad_mag_max <= high_threshold)
edges[strong_edges] = 1
while np.sum(weak_edges) > 0:
    i, j = np.unravel_index(weak_edges.argmax(), weak_edges.shape)   #.argmax()返回第一个参数   .shanpe返回矩阵各维数量(512*512)  np.unravel_index求索引值
    weak_edges[i, j] = 0
    if strong_edges[i - 1:i + 2, j - 1:j + 2].any():            #.any() 判断迭代参数是否全是false
        edges[i, j] = 1
        strong_edges[i, j] = 1
    else:
        edges[i, j] = 0
out = edges
# 显示结果
cv2.imshow('output',out)
cv2.waitKey(0)
  • 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
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

原图像
原图像

canny边缘检测的图像
canny算法图像

不使用高斯滤波的canny算法边缘检测图像
不使用高斯滤波的canny算法图像

总结

以上就是今天要讲的内容,本文仅仅简单介绍了canny边缘检测算法的使用,而canny边缘检测算法在日产生活中给我们带来了大量的便利。
(欢迎各位老师同学批评指正)

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号