程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Eight, opencv-python image processing advanced operations (4) - edge detection

編輯:Python

文章目錄

  • 學習目標
    • 了解Sobel算子,Scharr算子和拉普拉斯算子
    • 掌握canny邊緣檢測的原理及應用
  • 一、邊緣檢測的原理
    • 1、基於搜索
    • 2、基於零穿越
  • 二、Sobel檢測算子
    • 1、Principle and method discussed
    • 2、應用
  • 三、Laplacian算子
  • 四、canny邊緣檢測
    • 1、Canny算法的原理
    • 2、應用
  • 總結:
    • 1、邊緣檢測的原理
      • (1)基於搜索
      • (2)基於零穿越
    • 2、Sobel算子【實際應用】
      • (1)基於搜索的方法獲取邊界
      • (2)cv2.Sobel()
      • (3)cv2.convertScaleAbs()
      • (4)cv2.addWeighted()
    • 3、Laplacian算子
      • (1)基於零穿越獲取邊界
      • (2)cv2.Laplacian()
    • 4、Canny算法
      • (1)噪聲去除(高斯濾波)
      • (2)計算圖像梯度(Sobel算子)
      • (3)非極大值抑制:To determine whether a pixel is boundary point
      • (4)滯後阈值:設置兩個阈值,Determine the final borders
    • 5、The comparison between the traditional operator

  • Edge detection often regarded as a master's project or company interview questions,Therefore it is very important,In this chapter, the will of several common edge detection operators are introduce.

學習目標

了解Sobel算子,Scharr算子和拉普拉斯算子

掌握canny邊緣檢測的原理及應用

一、邊緣檢測的原理

Edge detection is a basic problem of image processing and computer vision,Its purpose is to represent Numbers in the image brightness change obvious point.圖像屬性中的顯著變化通常反映了屬性的重要事件和變化.Edge detection of the form as shown in the figure below:

Image edge detection significantly reduces the amount of data,並且剔除了可以認為不相關的信息,保留了圖像重要的結構屬性.有許多方法用於邊緣檢測,Most of them can be divided into two types of:基於搜索、基於零穿越

1、基於搜索

By the first derivative of the image to find the maximum value to detect the boundary,然後利用計算結果估計On the edge of the local direction,通常采用梯度的方向,And use the find local gradient in the direction of the模的最大值,代表算法有Sobel算子和Scharr算子.

(1)A maximum of image first derivative -->
.
(2)On the edge of the local direction(General gradient direction) -->
.
(3)The local gradient modulus maximum

2、基於零穿越

通過尋找圖像二階導數零穿越來尋找邊界,On behalf of the operator islaplacian算子.
Zero is refers to the function andy軸的交點.

二、Sobel檢測算子

Sobel邊緣檢測算法比較簡單,In the practical application efficiency thancanny邊緣檢測效果高.但是邊緣不如canny檢測的准確,But with a lot of practical application of the occasion,SobelOperator is the preferred.
Sobel算子是高斯平滑與微分操作的結合體,所以其Ability to resist noise is very strong,用途較多.尤其是效率要求較高,For detailed textures don't care.

1、Principle and method discussed

對於不連續的函數,一階導數可以寫作:

或者

所以有:

假設要處理的圖像為I,在兩個方向求導

  • 水平變化:將圖像IWith the clauses of the size of the template convolution,結果是Gx,比如,當模板大小為3時,Gx為:
  • 垂直變化:將圖像IWith the technology about the size of template convolution,結果為Gy.比如,當模板大小為3時,Gy為:

    在圖像的每一點,結合以上兩個結果求出:

    統計極大值所在的位置,就是圖像的邊緣.
    **注意:**當內核大小為3時, 以上Sobel內核可能產生比較明顯的誤差, 為解決這一問題,我們使用Scharr函數,但該函數僅作用於大小為3的內核.該函數的運算與Sobel函數一樣快,但結果卻更加精確,其計算方法為:

2、應用

利用OpenCV進行Sobel邊緣檢測的API是:

Sobel_x_or_y =
cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)

參數:

  • src:傳入的圖像
  • ddepth: 圖像的深度
  • dx和dy: 指求導的階數,0表示這個方向上沒有求導,取值為0、1.
  • ksize: 是Sobel算子的大小,即卷積核的大小,必須為奇數1、3、5、7,默認為3.
  • 注意:如果ksize=-1,就演變成為3x3的Scharr算子.
  • scale:縮放導數的比例常數,默認情況為沒有伸縮系數.
  • borderType:圖像邊界的模式,默認值為cv2.BORDER_DEFAULT.

Sobel函數求完導數後會有負值,There will be greater than255的值.而原圖像是uint8,即8為無符號數,所以Sobel建立的圖像位數不夠,會有截斷.因此要使用16位有符號的數據類型,即cv2.CV_16s.處理完圖像後,再使用cv2.convertScaleAbs()函數將其轉回原來的uint8類型,否則圖像無法顯示.

Sobel算子是在兩個方向計算的,最後還需要用cv2.addWeighted()函數將其組合起來

Scale_abs = cv2.convertScaleAbs(x) # 格式轉換函數
result = cv2.addWeighted(src1, alpha, src2, beta) # 圖像混合

代碼示例:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 讀取圖像
img = cv.imread('./image/horse.jpg',0)
# 2 計算Sobel卷積結果
x = cv.Sobel(img, cv.CV_16S, 1, 0)
y = cv.Sobel(img, cv.CV_16S, 0, 1)
# 3 將數據進行轉換
Scale_absX = cv.convertScaleAbs(x) # convert 轉換 scale 縮放
Scale_absY = cv.convertScaleAbs(y)
# 4 結果合成
result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
# 5 圖像顯示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原圖')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result,cmap = plt.cm.gray),plt.title('Sobel濾波後結果')
plt.xticks([]), plt.yticks([])
plt.show()


將上述代碼中計算SobelOperator partksize設為-1,就是利用scharr進行邊緣檢測.

x = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize=-1)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1, ksize=-1)

可以看出,使用Scharr算子,Detection effect thanSobelOperator is a little better.

三、Laplacian算子

LaplacianEdge detection method by using second derivative to detect.因為圖像是“2維”,So we need in two direction derivative,如下式所示:

Then the discrete second derivative is:

Then using convolution kernels is:

API:

laplacian = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

參數:

  • Src:圖像
  • Ddepth:圖像深度,-1Said the original image is the same depth,目標圖像的深度必須大於等於原圖像的深度;
  • ksize:算子的大小,即卷積核的大小,必須是1,3,5,7

代碼示例:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 讀取圖像
img = cv.imread('./image/horse.jpg',0)
# 2 laplacian轉換
result = cv.Laplacian(img,cv.CV_16S)
Scale_abs = cv.convertScaleAbs(result)
# 3 圖像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原圖')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(Scale_abs,cmap = plt.cm.gray),plt.title('Laplacian檢測後結果')
plt.xticks([]), plt.yticks([])
plt.show()

四、canny邊緣檢測

canny邊緣檢測算法是一種非常流行的邊緣檢測算法,是John F.Canny與1986年提出的,Edge detection algorithm is considered to be the best.

1、Canny算法的原理

CannyEdge detection algorithm by the4步構成,分別介紹如下:

  • 噪聲去除

Due to the edge detection is susceptible to noise interference,Therefore the first to use gaussian filter to remove noise.(Gaussian filter mentioned in the image smooth,You can go through)

  • 計算圖像梯度

對平滑後的圖像使用Sobel算子計算水平方向和垂直方向的一階導數(Gx和Gy).根據得到的這兩幅梯度圖(Gx和Gy)找到邊界的梯度和方向,公式如下:

如果某個像素點是邊緣,It always and edge direction vertical gradient direction.梯度方向被歸為四類:垂直、水平,和兩個對角線方向.

  • 非極大值抑制

After get the gradient direction and size,對整幅圖像進行掃描,去除那些非邊界上的點.Inspection on each pixel,看這個點的梯度是不是周圍具有相同梯度方向的點中最大的.如下圖所示:

A點位於圖像的邊緣,在其梯度變化方向,選擇像素點B和C,用來檢驗A點的梯度是否為極大值,若為極大值,則進行保留,否則A點被抑制,最終的結果是具有“細邊”的二進制圖像.

  • 滯後阈值

現在要確定真正的邊界. 我們設置兩個阈值: minVal 和 maxVal. 當圖像的灰度梯度高於 maxVal 時被認為是真的邊界, 低於 minVal 的邊界會被拋棄.如果介於兩者之間的話,就要看這個點是否與某個被確定為真正的邊界點相連,如果是就認為它也是邊界點,如果不是就拋棄.如下圖:

如上圖所示,A 高於阈值 maxVal 所以是真正的邊界點,C 雖然低於 maxVal 但高於 minVal 並且與 A 相連,所以也被認為是真正的邊界點.而 B 就會被拋棄,因為低於 maxVal 而且不與真正的邊界點相連.所以選擇合適的 maxVal 和 minVal 對於能否得到好的結果非常重要.

2、應用

在opencvTraditional Chinese medicine (TCM) implementationcanny檢測使用的API:

canny = cv2.Canny(image, threshold1, threshold2)

參數:

  • image:灰度圖,
  • threshold1: minval,較小的阈值將間斷的邊緣連接起來
  • threshold2: maxval,較大的阈值檢測圖像中明顯的邊緣
    代碼示例:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 圖像讀取
img = cv.imread('./image/horse.jpg',0)
# 2 Canny邊緣檢測
lowThreshold = 0
max_lowThreshold = 100
canny = cv.Canny(img, lowThreshold, max_lowThreshold)
# 3 圖像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原圖')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(canny,cmap = plt.cm.gray),plt.title('Canny檢測後結果')
plt.xticks([]), plt.yticks([])
plt.show()

總結:

1、邊緣檢測的原理

(1)基於搜索

(2)基於零穿越

2、Sobel算子【實際應用】

(1)基於搜索的方法獲取邊界

(2)cv2.Sobel()

(3)cv2.convertScaleAbs()

(4)cv2.addWeighted()

3、Laplacian算子

(1)基於零穿越獲取邊界

(2)cv2.Laplacian()

4、Canny算法

(1)噪聲去除(高斯濾波)

(2)計算圖像梯度(Sobel算子)

(3)非極大值抑制:To determine whether a pixel is boundary point

(4)滯後阈值:設置兩個阈值,Determine the final borders

5、The comparison between the traditional operator

  • Strengthen a long road,加油加油!!!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved