日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

图像处理:python实现canny算子

發布時間:2025/3/21 python 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像处理:python实现canny算子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Canny邊緣提取步驟

文中用python實現canny算子,Canny算子的步驟為:

  • 1)圖像灰度預處理
  • 2)對每個像素求梯度
  • 3)求每個點處最大梯度的編碼
  • 4)非極大值抑制,保證梯度編碼的唯一性。
  • 5)通過閾值,將邊緣像素抽取出來;

二、高斯平滑算子代碼

? ? ? 在jupyter-notebook下,通過下列代碼學習,可以了解canny算子全過程;并按自己的理解進行修改學習:?

import numpy as np import math import matplotlib as mpl import matplotlib.pyplot as plt import seaborn as sns import cv2img = plt.imread('d:/images/mchine.jpg')%matplotlib inline sigma1 = sigma2 = 1 sum = 0 gaussian = np.zeros([5, 5]) for i in range(5):for j in range(5):gaussian[i, j] = math.exp(-1 / 2 * (np.square(i - 2) / np.square(sigma1) # 生成二維高斯分布矩陣+ (np.square(j - 2) / np.square(sigma2)))) / (2 * math.pi * sigma1 * sigma2)sum = sum + gaussian[i, j]gaussian = gaussian / sum sns.heatmap( gaussian )plt.show()

顯示高斯平滑算子的熱圖。?

三、三通道圖轉換成灰度圖

def rgb2gray(rgb):return np.dot(rgb[..., :3], [0.299, 0.587, 0.114]) gray = rgb2gray(img) W, H = gray.shape sns.heatmap( gray )

灰度變換后,圖像的熱圖:

?

四、生成梯度圖

new_gray = cv2.GaussianBlur(gray, (5, 5), 0) # step2.增強 通過求梯度幅值 W1, H1 = new_gray.shape dx = np.zeros([W1 - 1, H1 - 1]) dy = np.zeros([W1 - 1, H1 - 1]) d = np.zeros([W1 - 1, H1 - 1]) for i in range(W1 - 1):for j in range(H1 - 1):dx[i, j] = new_gray[i, j + 1] - new_gray[i, j]dy[i, j] = new_gray[i + 1, j] - new_gray[i, j]d[i, j] = np.sqrt(np.square(dx[i, j]) + np.square(dy[i, j])) # 圖像梯度幅值作為圖像強度值 sns.heatmap( d)

梯度圖:?

?

五、非極大值抑制

5.1 canny算子的雙閾值原理

1) canny算子設定有兩個閾值,低閾值高閾值

2) canny算子使每個像素點位置上能夠算出一個梯度值,稱為“實際梯度”

3)當 “實際梯度 > 高閾值” 該點被錄取為“邊緣點”

4)當 “實際梯度 <?低閾值” 該點被錄取為“非邊緣點(也叫背景點)”

5)當? ? “低閾值< 實際梯度低< 高閾值 ”? 情況復雜了,需要判別

? ? ? ? ? ? 如果周圍相鄰的點都沒有大于低閾值,該點被錄取為背景點(非邊緣點)。

? ? ? ? ? ??如果周圍相鄰的點都有大于低閾值的,就比較那個相鄰點和該點梯度,凡梯度大者被錄取為邊緣點。

( 不知以上敘述是否清楚?下圖,因為所有梯度都取絕對值,因此,梯度最小為0 )

?程序如下:

W2, H2 = d.shape NMS = np.copy(d) NMS[0, :] = NMS[W2 - 1, :] = NMS[:, 0] = NMS[:, H2 - 1] = 0 for i in range(1, W2 - 1):for j in range(1, H2 - 1):if d[i, j] == 0:NMS[i, j] = 0else:gradX = dx[i, j]gradY = dy[i, j]gradTemp = d[i, j]# 如果Y方向幅度值較大if np.abs(gradY) > np.abs(gradX):weight = np.abs(gradX) / np.abs(gradY)grad2 = d[i - 1, j]grad4 = d[i + 1, j]# 如果x,y方向梯度符號相同if gradX * gradY > 0:grad1 = d[i - 1, j - 1]grad3 = d[i + 1, j + 1]# 如果x,y方向梯度符號相反else:grad1 = d[i - 1, j + 1]grad3 = d[i + 1, j - 1]# 如果X方向幅度值較大else:weight = np.abs(gradY) / np.abs(gradX)grad2 = d[i, j - 1]grad4 = d[i, j + 1]# 如果x,y方向梯度符號相同if gradX * gradY > 0:grad1 = d[i + 1, j - 1]grad3 = d[i - 1, j + 1]# 如果x,y方向梯度符號相反else:grad1 = d[i - 1, j - 1]grad3 = d[i + 1, j + 1]gradTemp1 = weight * grad1 + (1 - weight) * grad2gradTemp2 = weight * grad3 + (1 - weight) * grad4if gradTemp >= gradTemp1 and gradTemp >= gradTemp2:NMS[i, j] = gradTempelse:NMS[i, j] = 0# plt.imshow(NMS, cmap = "gray")# step4. 雙閾值算法檢測、連接邊緣 W3, H3 = NMS.shape DT = np.zeros([W3, H3]) # 定義高低閾值 TL = 0.31 * np.max(NMS) TH = 0.4 * np.max(NMS)for i in range(1, W3 - 1):for j in range(1, H3 - 1):if (NMS[i, j] < TL):DT[i, j] = 0elif (NMS[i, j] > TH):DT[i, j] = 255elif ((NMS[i - 1, j - 1:j + 1] < TH).any() or (NMS[i + 1, j - 1:j + 1]).any()or (NMS[i, [j - 1, j + 1]] < TH).any()):DT[i, j] = 255 # newDT = DT.astype(np.uint8)cv2.imshow( "gray",DT) cv2.waitKey(0) cv2.destroyAllWindows() cv2.imwrite("parts4.jpg",DT)

三、結果展示?

總結

以上是生活随笔為你收集整理的图像处理:python实现canny算子的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。