zoukankan      html  css  js  c++  java
  • canny边缘检测

    实现代码:

    import cv2
    import numpy as np
    
    img = cv2.imread('./tu2.jpg', 0)
    print(img.shape)
    height, width = img.shape
    
    # 高斯滤波
    fil = np.array([[ 1, 2, 1],
                    [ 2, 4, 2],
                    [ 1, 2, 1]])
    fil = fil/16
    res = cv2.filter2D(img,-1,fil)
    
    # 梯度
    dx = np.zeros((height, width))
    dy = np.zeros((height, width))
    d = np.zeros((height, width))
    for i in range(1, height-1):
        for j in range(1, width-1):
            dx[i, j] = int(res[i, j+1]) - int(res[i, j])
            dy[i, j] = int(res[i+1, j]) - int(res[i, j])
            d[i, j] = np.sqrt(dx[i, j]**2 + dy[i, j]**2)
    cv2.imshow('d', d)
    
    # 非极大值抑制
    k = d
    for i in range(1, height-1):
        for j in range(1, width-1):
            gradX = dx[i,j]
            gradY = dy[i,j]
            gradTemp = d[i,j]
            if abs(gradY) > abs(gradX):
                weight = abs(gradX)/abs(gradY) if abs(gradY)!=0 else 1
                grad2 = d[i - 1,j]
                grad4 = d[i + 1,j]
                if gradX * gradY > 0:
                    grad1 = d[i - 1,j - 1]
                    grad3 = d[i + 1,j + 1]
                else:
                    grad1 = d[i - 1,j + 1]
                    grad3 = d[i + 1,j - 1]
            else:
                weight = abs(gradY) / abs(gradX) if abs(gradY)!=0 else 1
                grad2 = d[i,j - 1]
                grad4 = d[i,j + 1]
                if gradX * gradY > 0:
                    grad1 = d[i + 1,j + 1]
                    grad3 = d[i - 1,j - 1]
                else:
                    grad1 = d[i - 1,j + 1]
                    grad3 = d[i + 1,j - 1]
            # 利用grad1-grad4对梯度进行插值
            gradTemp1 = weight * grad1 + (1 - weight) * grad2
            gradTemp2 = weight * grad3 + (1 - weight) * grad4
            # 当前像素的梯度是局部的最大值,可能是边缘点
            if gradTemp >= gradTemp1 and gradTemp >= gradTemp2:
                k[i,j] = gradTemp
            else:
                k[i,j] = 0
    cv2.imshow('k', k)
    
    # 定义双阈值
    EP_MIN = 12
    EP_MAX = EP_MIN * 2
    EdgeLarge = np.zeros((height, width))    #记录真边缘
    EdgeBetween = np.zeros((height, width))  #记录可能的边缘点
    for i in range(1, height-1):
        for j in range(1, width-1):
            if k[i,j] >= EP_MAX:
                EdgeLarge[i,j] = k[i,j]
            elif k[i,j] >= EP_MIN:
                EdgeBetween[i,j] = k[i,j]
    cv2.imshow('EdgeLarge', EdgeLarge)
    cv2.imshow('EdgeBetween', EdgeBetween)
    
    # 把EdgeLarge的边缘连成连续的轮廓
    edge = np.zeros((height, width))
    for i in range(1, height-1):
        for j in range(1, width-1):
            if EdgeLarge[i,j] > 0:
                edge[i,j] = EdgeLarge[i,j]
                list_position = [[i-1, j-1], [i, j-1], [i+1, j-1], [i+1, j], 
                                 [i+1, j+1], [i, j+1], [i-1, j+1], [i-1, j]]
                for lis in list_position:
                    x = lis[0]
                    y = lis[1]
                    if EdgeBetween[x, y] > 0:
                        edge[x, y] = EdgeBetween[x, y]
                        EdgeBetween[x, y] = 0#避免重复计算
    cv2.imshow('edge', edge)
    cv2.waitKey()
    cv2.destroyAllWindows()

    实现结果图片:

          

          

  • 相关阅读:
    Move site collections to a new database
    SharePoint 2010 Site Workflow
    Customizing the Server Ribbon
    [转]深入浅出之正则表达式
    asp.net中MD5加密写法代码
    asp.net中过滤非法字符防止SQL注入
    jQuery中ajax的使用方法
    gridview中用NewSelectedIndex获取选中的ID值
    GridView中得到选中的某行的ID值
    用javascript伪装链接地址状态代码
  • 原文地址:https://www.cnblogs.com/czz0508/p/11166406.html
Copyright © 2011-2022 走看看