canny边缘检测

import cv2
import numpy as np

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):
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:
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:
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()

posted @ 2019-07-10 20:50  车路历程  阅读(276)  评论(0编辑  收藏  举报