數(shù)字圖像處理:邊緣檢測
序言
在之前的文章中,我介紹了傅里葉變換,這次我將介紹另一種圖像處理方法,邊緣檢測。在openCV中,有很多函數(shù)可以讓我們找到圖像的邊緣,在這篇文章中,我將挑選出比較有代表性的Sobal算子和Laplacian算子進行介紹。
邊緣檢測
既然我們要檢測邊緣,首先我們需要了解邊緣是什么。
最簡單的邊緣
以上圖為例,我們可以看到黑白的分界線就是我們要找的邊緣,也就是像素之間的急劇變化。
拉普拉斯算子
原則拉普拉斯算子使用對圖像進行微分的方法來提取邊緣。具體推導方法如下。
以與正面相似的圖片為例,取其中一條橫線,加以區(qū)分。
可以看出,在邊緣的交界處,經過微分后,會出現(xiàn)一個明顯的峰值。我們可以設置一個閾值,這樣如果微分后的圖像超過這個閾值,就會判斷為邊緣,進行后續(xù)處理。
但是這種方法不夠嚴謹,所以也可以對圖像進行兩次微分。而二階導數(shù)結果中的Z點,也就是“過零”,就是我們要找的邊。
在了解了基本原理之后,我們需要從數(shù)學上推導出 Laplacian 所需的掩碼應該是什么樣子。從上面的介紹可以看出,最重要的部分就是對圖像進行區(qū)分,但其實這在圖像中并不難,只要從下一個網格的像素中減去上一個網格的像素,即可以得到斜率,它是一階導數(shù)。
數(shù)學表達式
在知道如何推導一階微分之后,同樣可以推導出二階微分。在這里,我們將跳過推導過程,直接查看結果。
二階微分的數(shù)學公式
至此,我們得到了我們需要的拉普拉斯掩碼。
拉普拉斯算子掩碼
實施
我們可以使用 openCV 中提供的拉普拉斯運算函數(shù):
dst = cv2.Laplacian(src, ddepth, ksize)
src :要處理的圖像。
dst :輸出圖像。
ddepth :圖像的深度。有許多標志可以使用。最常用的是cv2.CV_8U和cv2.CV_16S。
ksize :掩碼的大小。
import cv2
def main():
# read image
gray_img = cv2.imread("./lenna.jpg", 0)
cv2.imshow("img",gray_img)
# Try masks of different sizes
for n in range(1, 4):
# 使用拉普拉斯算子
kernel_size = 1+(n*2)
gray_lap = cv2.Laplacian(gray_img, cv2.CV_16S, ksizekernel_size)
# Convert image format to uint8
abs_lap = cv2.convertScaleAbs(gray_lap)
# display image
cv2.imshow(f"{1+n*2}_lap_img",abs_lap)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save image
cv2.imwrite(f"./result/Laplacian/Laplacian_{1+n*2}.png",abs_lap)
if __name__ == "__main__":
main()
結果
Sobal 算子
原則
下圖是 Sobal 算子使用的掩碼。左邊是水平方向的邊緣檢測,右邊是垂直方向的邊緣檢測。
然后使用這個掩碼對圖像進行卷積得到邊緣圖像。
實施
就像拉普拉斯算子一樣,openCV 也提供了書面的 Sobal 函數(shù)。
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
src :要處理的圖像。
dst :輸出圖像。
ddepth :圖像的深度。有許多標志可以使用。最常用的是cv2.CV_8U和cv2.CV_16S。
dx, dy :選擇要在水平或垂直方向進行的操作,選擇1, 0/0, 1。
ksize :掩碼的大小。
在Sobal操作之后,convertScaleAbs通常會執(zhí)行一個操作,將圖像轉換回可以正常顯示的格式。
dst = cv2.convertScaleAbs(src)
示例程序
import cv2
def main():
# read image
gray_img = cv2.imread("./lenna.jpg", 0)
cv2.imshow("img",gray_img)
# Try masks of different sizes
for n in range(1, 4):
# 使用 sobel 算子
kernel_size = 1+(n*2)
x = cv2.Sobel(gray_img, cv2.CV_16S, 1, 0, ksize=kernel_size)
y = cv2.Sobel(gray_img, cv2.CV_16S, 0, 1, ksize=kernel_size)
# Convert image format to uint8
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
# Add the results from both directions to form a complete contour
dst = cv2.addWeighted(absX, 0.5, absY,0.5,0)
# display image
cv2.imshow(f"{1+n*2}_x",absX)
cv2.imshow(f"{1+n*2}_y",absY)
cv2.imshow(f"{1+n*2}_x+y",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save image
cv2.imwrite(f"./result/Sobal/Sobal_{1+n*2}_x.png",absX)
cv2.imwrite(f"./result/Sobal/Sobal_{1+n*2}_y.png",absY)
cv2.imwrite(f"./result/Sobal/Sobal_{1+n*2}_x+y.png",dst)
if __name__ == "__main__":
main()
輸入
結果(內核大小 = 3)
結果(內核大小 = 5)
結果(內核大小 = 7)
參考
原文標題 : 數(shù)字圖像處理:邊緣檢測

請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
推薦專題
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀”爆發(fā)至今,五類新物種登上歷史舞臺
- 5 國產智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計算迎來商業(yè)化突破,但落地仍需時間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 地平線自動駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關稅,能否乘機器人東風翻身?