canny 边缘检测(小作业)

canny 边缘检测(小作业),第1张

作业需要 ,要的自取

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

img=cv2.imread("cat.jpg")

#灰度图
gray_img= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#1. 高斯滤波
#(5, 5)表示高斯矩阵的长与宽都是5,标准差取1
gray_img=cv2.GaussianBlur(gray_img,(5,5),1)
gaussian=np.uint8(np.copy(gray_img))

#展示一下高斯后结果
plt.imshow(gaussian)
plt.show()

 

#2.sobel 计算梯度幅值
W,H=gray_img.shape[:2]  #应该就是0-2 省略了0 然后分别赋值
#w==x h==y

dx=np.zeros((W,H),dtype=np.float)
dy=np.zeros((W,H),dtype=np.float)
d=np.zeros((W,H),dtype=np.float)
angle=np.zeros((W,H),dtype=np.float)

Xsobel=np.array([[1,2,1],
                 [0,0,0],
                 [-1,-2,-1]])
Ysobel=np.array([[1,0,-1],
                [2,0,-2],
                [1,0,-1]])

#需要最外边一圈为0填充
for i in range(1,W-1):
    for j in range(1,H-1):
        dx[i,j]=np.sum(Xsobel*gray_img[i-1:i+2,j-1:j+2])
        dy[i,j]=np.sum(Ysobel*gray_img[i-1:i+2,j-1:j+2])
        d[i,j]=np.sqrt(np.square( dx[i,j])+np.square( dy[i,j]))
        angle[i,j]=math.degrees(math.atan2(dy[i,j],dx[i,j]))   #math.atan2 弧度值  math.degrees 弧度转角度
        if angle[i,j]<0:
            angle[i,j]+=360

tidu=np.uint8(np.copy(d))
plt.imshow(tidu)
plt.show()

 

#3.非极大值抑制

NMS=np.zeros((W,H),dtype=np.float)

for i in range(1,W-1):
    for j in range(1,H-1):
        if tidu[i,j]==0:
            NMS[i,j]=0
        else:
            g1=None
            g2=None
            #不同角度 就近原则 找到g1 g2
            if angle[i,j]<=22.5 or angle[i,j]>=337.5:
                g1=tidu[i,j-1]
                g2=tidu[i,j+1]
            elif (angle[i,j]<=67.5 and angle[i,j]>22.5) or (angle[i,j]<=337.5 and angle[i,j]>292.5):
                g1=tidu[i-1,j+1]
                g2=tidu[i+1,j-1]
            elif (angle[i,j]<=112.5 and angle[i,j]>67.5) or (angle[i,j]<=292.5 and angle[i,j]>247.5):
                g1=tidu[i-1,j]
                g2=tidu[i+1,j]
            elif (angle[i,j]<=157.5 and angle[i,j]>112.5) or (angle[i,j]<=247.5 and angle[i,j]>202.5):
                g1=tidu[i-1,j-1]
                g2=tidu[i+1,j+1]
            else:
                g1=tidu[i,j-1]
                g2=tidu[i,j+1]
            #若中心像素为最大值,则保留,否则中心置0
#             if tidu[i,j]>g1 and tidu[i,j]>g2:
#                 NMS[i,j]=tidu[i,j]
#             else :
#                 NMS[i,j]=0
            if tidu[i,j]<g1 or tidu[i,j]<g2:
                NMS[i,j]=0
            else:
                NMS[i,j]=tidu[i,j]

NMS=np.uint8(np.copy(NMS))
plt.imshow(NMS)
plt.show()

 

shuang=np.zeros((W,H),dtype=np.float)
TL=50
TH=100


for i in range(1,W-1):
    for j in range(1,H-1):
        if NMS[i, j] < TL:
            shuang[i, j] = 0
        elif NMS[i, j] > TH:
            shuang[i, j] = 255
        # 将小于高阈值,大于低阈值的点使用8连通区域确定(即:只有与TH像素连接时才会被接受,成为边缘点,赋255)

        elif ((NMS[i + 1, j] > TH) or (NMS[i - 1, j] > TH) or (NMS[i, j + 1] > TH) or
              (NMS[i, j - 1] > TH) or (NMS[i - 1, j - 1] > TH) or (NMS[i - 1, j + 1] > TH) or
              (NMS[i + 1, j + 1] > TH) or (NMS[i + 1, j - 1] > TH)):
            shuang[i, j] = 255

shuang_2=np.uint8(np.copy(shuang))
plt.imshow(shuang_2)
plt.show()

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/943477.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存