Opencv3.0-python的那些事儿:(七)、Opencv中Canny边缘检测算法使用

# coding: utf-8

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

'''
19章 Canny边缘检测
步骤:
1噪声去除
使用5*5的高斯滤波器
2计算图像梯度
对平滑后的图像使用Sobel算子计算水平方向和竖直方向的一阶导数(图像梯度)
(Gx和Gy)。根据得到的这两幅梯度图(Gx和Gy)找到边界的梯度和方向,公式如下
Edge_Gradient(G)=sqrt( Gx*Gx + Gy*Gy )

Angle(θ)= tan −1( Gx/Gy)
梯度方向一般总是与边界垂直(?),梯度方向被归为四类:垂直,水平,和两个对角线

3非极大值抑制
获得梯度方向和大小后,对整幅图像做扫描,去除非边界上的点。
对每一个像素检查,看这个点的梯度是不是周围具有相同梯度方向的
点中最大的

4滞后阈值
现在要确定那些边界才是真正的边界。这时我们需要设置两个阈值:
minVal 和 maxVal。当图像的灰度梯度高于 maxVal 时被认为是真的边界,
那些低于 minVal 的边界会被抛弃。如果介于两者之间的话,就要看这个点是
否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是
就抛弃
'''

def Canny_test():
    img = cv2.imread("roi.jpg" , 0)
    '''
    cv2.Canny(image,threshold1 , threshold2[,edges])
    作用:根据Canny算法检测边界
    threshold1:minVal,threshold2:maxVal
    edges:设置卷积核的大小,L2gradient:默认使用近似值来代替所求的梯度
    '''
    edges = cv2.Canny(img , 100 , 200)
    plt.subplot(1,2,1) , plt.imshow(img , cmap="gray")
    plt.title("Original") , plt.xticks([]) , plt.yticks([])
    plt.subplot(1,2,2), plt.imshow(edges , cmap="gray")
    plt.title("Cannt") , plt.xticks([])  ,plt.yticks([])
    plt.show()

if __name__ == "__main__":
    Canny_test()


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是使用Python编写的Canny边缘检测算法,不使用OpenCV库: ```python import numpy as np from scipy import ndimage def gaussian_kernel(size, sigma=1): x, y = np.mgrid[-size:size+1, -size:size+1] g = np.exp(-(x**2+y**2)/(2*sigma**2)) return g/g.sum() def sobel_filters(image): kernel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) kernel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]) G_x = ndimage.convolve(image, kernel_x) G_y = ndimage.convolve(image, kernel_y) G = np.sqrt(G_x**2 + G_y**2) theta = np.arctan2(G_y, G_x) return G, theta def non_maximum_suppression(image, theta): M, N = image.shape Z = np.zeros((M,N), dtype=np.int32) angle = theta * 180. / np.pi angle[angle < 0] += 180 for i in range(1, M-1): for j in range(1, N-1): q = 255 r = 255 if (0 <= angle[i,j] < 22.5) or (157.5 <= angle[i,j] <= 180): q = image[i, j+1] r = image[i, j-1] elif (22.5 <= angle[i,j] < 67.5): q = image[i+1, j-1] r = image[i-1, j+1] elif (67.5 <= angle[i,j] < 112.5): q = image[i+1, j] r = image[i-1, j] elif (112.5 <= angle[i,j] < 157.5): q = image[i-1, j-1] r = image[i+1, j+1] if (image[i,j] >= q) and (image[i,j] >= r): Z[i,j] = image[i,j] else: Z[i,j] = 0 return Z def hysteresis_threshold(image, low_threshold, high_threshold): M, N = image.shape res = np.zeros((M,N), dtype=np.int32) weak = np.int32(25) strong = np.int32(255) strong_i, strong_j = np.where(image >= high_threshold) zeros_i, zeros_j = np.where(image < low_threshold) weak_i, weak_j = np.where((image <= high_threshold) & (image >= low_threshold)) res[strong_i, strong_j] = strong res[weak_i, weak_j] = weak for i in range(1, M-1): for j in range(1, N-1): if (res[i,j] == weak): if ((res[i+1, j-1] == strong) or (res[i+1, j] == strong) or (res[i+1, j+1] == strong) or (res[i, j-1] == strong) or (res[i, j+1] == strong) or (res[i-1, j-1] == strong) or (res[i-1, j] == strong) or (res[i-1, j+1] == strong)): res[i,j] = strong else: res[i,j] = 0 return res def canny_edge_detection(image, sigma=1, low_threshold=20, high_threshold=50): image = image.astype(np.float32) kernel = gaussian_kernel(5, sigma) image_smoothed = ndimage.convolve(image, kernel) G, theta = sobel_filters(image_smoothed) G_suppressed = non_maximum_suppression(G, theta) G_thresholded = hysteresis_threshold(G_suppressed, low_threshold, high_threshold) return G_thresholded ``` 请注意,这只是一个简单的实现,可能不如OpenCV的实现效果好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值