OpenCV之sobel算子詳解

原理

sobel算子是一種計算不同方向上梯度的工具。原理是使用卷積覈對圖像進行處理。
如果想計算x方向梯度,我們就需要這樣的一個卷積核
在這裏插入圖片描述
以卷積核的中心爲中心,將卷積核與圖像上像素值一一對應,卷積核上的數字相當於係數。利用如下公式即可計算出卷積核中心的x方向梯度。
在這裏插入圖片描述
同理,如果想要計算y方向的梯度,卷積核應該是這樣的,公式也是同理。

我們求得了某一像素x方向和y方向的梯度,那麼該像素的梯度容易得出:

在這裏插入圖片描述
但是這個公式比較難算,所以我們一般直接把這個公式化作:
在這裏插入圖片描述

Sobel函數

opencv中提供給我們封裝好的Sobel算子函數,不需要我們一一計算。
其構造函數如下:

cv2.Sobel(src,ddepth,dx,dy,ksize)

參數解釋:

  • src:原圖
  • ddepth:處理結果圖像深度,一般我們都填-1,即與原圖深度相同。但在這裏我們需要填寫cv2.CV_64F。簡單來說就是如果填寫-1,我們在計算梯度時產生的負數就會被程序默認爲0,導致有一邊的邊緣出不來。而cv2.CV_64F範圍更大,可以保留負數。
  • dx:計算x方向的梯度
  • dy:計算y方向的梯度
  • ksize:卷積核的尺寸。默認爲3,即3*3的矩陣。

函數在使用時。如果我們想要計算x方向的梯度:

cv2.Sobel(src,ddepth,1,0,ksize)

反之,計算y方向的梯度

cv2.Sobel(src,ddepth,0,1,ksize)

當然,想要計算總梯度直接dx=1,dy=1也是可以的,但是效果十分不好。不建議使用這種方法。
我們通常使用的方法是按權相加法。按權相加x方向梯度和y方向梯度。使用cv2.addWeight()函數,該函數支持五個參數:

  • src1:第一幅圖像
  • weight1:第一幅圖像的權重
  • src2:第二幅圖像
  • weight2:第二幅圖像的權重
  • 修改值

我們還要注意一件事。在我們分別計算完x、y方向的權值時,裏面是有負數的。我們需要對這些負數取絕對值,否則照樣會被歸爲0。
取絕對值的函數是cv2.convertScaleAbs(img)

例程:
import numpy as np
import cv2
img=cv2.imread('D://zopencv//qi.jpg',0)
mask_x=cv2.Sobel(img,cv2.CV_64F,1,0)#計算x方向梯度
mask_y=cv2.Sobel(img,cv2.CV_64F,0,1)
img_x=cv2.convertScaleAbs(mask_x)#取絕對值
img_y=cv2.convertScaleAbs(mask_y)
mask=cv2.addWeighted(img_x,0.5,img_y,0.5,0)#按權相加
#mask=cv2.Sobel(img,cv2.CV_64F,1,1)
Archie=cv2.resize(mask,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)#圖片太大了,縮小圖片
cv2.imshow('Archie',Archie)
cv2.waitKey(0)
cv2.destroyAllWindows()

這是按權相加得到的邊緣圖
在這裏插入圖片描述
這是直接取dx=1,dy=1得到的邊緣圖
在這裏插入圖片描述
差距一目瞭然。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章