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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)

發布時間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、邊緣檢測基礎理論

1、作用:

2、分類

1、基于搜索

?2、基于零穿越

3、算子比較

二、Sobel算子基礎理論

1、作用

2、原理及推導

3、更詳細推導

4、Sobel函數

?二、實戰

1、對x方向微分

2、對y方向微分

3、線性混合

總代碼

其他應用

參考資料


一、邊緣檢測基礎理論

1、作用:

圖像邊緣檢測大幅度地減少了數據量,并且剔除了不相關的信息保留了圖像重要的結構屬性。

????????邊緣檢測是圖像處理和計算機視覺中的基本問題,邊緣檢測的目的標識數字圖像中亮度變化明顯的點。圖像屬性中的顯著變化通常反映了屬性的重要事件和變化。邊緣的表現形式如下圖所示:

縱軸:灰度值 橫軸:位置信息

圖像邊緣檢測大幅度地減少了數據量,并且剔除了不相關的信息保留了圖像重要的結構屬性。有許多方法用于邊緣檢測,它們的絕大部分可以劃分為兩類∶基于搜索基于零穿越。

2、分類

基于搜索:利用一階導數最大值檢測邊緣

基于零穿越:利用二階導數為0檢測邊緣

1、基于搜索

基于搜索:通過尋找圖像一階導數中的最大值檢測邊界,然后利用計算結果估計邊緣的局部方向通常采用梯度的方向,并利用此方向找到局部梯度模的最大值,代表算法是Sobel算子Scharr算子

原理:邊緣附近的像素值會有明顯突變,即變化最大,也就是一階導數最大。那么找到最大的一階導數也就找到了像素變化最大的點,即邊緣點。

?2、基于零穿越

基于零穿越:通過尋找二階導數零穿越尋找邊界,代表算法是Laplace算子。

原理:在一階導數的基礎上再求一次導,那么此時零點就是變化最大的點,即邊緣點。

3、算子比較

其中,Canny算子永遠的神!(最優邊緣檢測)

二、Sobel算子基礎理論

1、作用

Sobel算子:用于邊緣檢測離散微分算子。(一階)(結合了高斯平滑微分

1、邊緣檢測: Gx 用于檢測縱向邊緣, Gy 用于檢測橫向邊緣.

2、計算法線: Gx 用于計算法線的橫向偏移, Gy 用于計算法線的縱向偏移.

????????Sobel邊緣檢測算法比較簡單,實際應用中效率比canny邊緣檢測效率要,但是邊緣不如Canny檢測的準確,但是很多實際應用的場合,sobel邊緣卻是首選Sobel算子是高斯平滑與微分操作的結合體,所以其抗噪聲能力很強,用途較多。尤其是效率要求較高,而對細紋理不太關心的時候。

注:需要x方向圖像就對y求微分,需要y方向圖像就對x求微分,兩者顛倒
對x方向求導,得到的是y方向的邊緣;
對y方向求導,得到的是x方向的邊緣。

2、原理及推導

因為圖像是二維的,所以需要在兩個方向求導

垂直方向的邊緣在水平方向梯度(偏導數)幅值較大

水平方向的邊緣在垂直方向梯度(偏導數)幅值較大

Sobel算子剛好能描述這個圖像變化。

過程:

先分別求x和y方向sobel算子,再取絕對值轉換成uint8),然后線性混合。(如圖)

梯度公式

對于圖像而言,它是離散的,所以h的最小值只能是1了,那么這意味著,圖像中某個像素位置的梯度(以x方向為例)等于它左右兩個像素點的像素之差除以2。

可以看出:后 - 前?

所以:

?

?綜上求出:

例:假設有一行像素是這樣分布的:
123 155 173
那么,像素值為155的像素位置x方向的梯度為(173 - 123)/2 = 25

Schar算子能夠彌補Sobel內核為3時的誤差:(更佳的3*3濾波器Scahrr ()函數)

3、更詳細推導

?Prewitt算子:x方向和y方向卷積核分別為:

? ? ? ? ? ? ? ? ? ? ? ? ?

sobel算子:在此基礎上加了一些權值,結合了高斯平滑微分求導。

Sebel算子x方向和y方向的卷積核分別為:

求出了水平方向和豎直方向的梯度GxGy之后
近似的梯度就可以用下面的方法算出來:?

?

4、Sobel函數

void Sobel (InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT );  

函數參數解釋:

InputArray src:輸入的原圖像,Mat類型

OutputArray dst:輸出的邊緣檢測結果圖像,Mat型,大小與原圖像相同。

int ddepth:輸出圖像的深度,針對不同的輸入圖像,輸出目標圖像有不同的深度,具體組合如下:

- 若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F

- 若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F

- 若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F

- 若src.depth() = CV_64F, 取ddepth = -1/CV_64F

注:ddepth =-1時,代表輸出圖像與輸入圖像相同的深度。

int dx:int類型dx,x 方向上的差分階數,1或0

int dy:int類型dy,y 方向上的差分階數,1或0

其中,dx=1,dy=0,表示計算X方向的導數,檢測出的是垂直方向上的邊緣;dx=0,dy=1,表示計算Y方向的導數,檢測出的是水平方向上的邊緣。

int ksize:為進行邊緣檢測時的模板大小為ksize*ksize,取值為1、3、5和7,其中默認值為3。特殊情況:ksize=1時,采用的模板為3*1或1*3。

當ksize=3時,Sobel內核可能產生比較明顯的誤差,此時,可以使用 Scharr 函數,該函數僅作用于大小為3的內核。具有跟sobel一樣的速度,但結果更精確,其內核為:

C++:

Sobel(gray, grad_x, CV_16S, 1,                0,           3);//                      x方向差分階數    y方向差分階數   核大小

?python:

x = cv.Sobel(img, cv.CV_16S, 1,     0)
y = cv.Sobel(img, cv.CV_16S, 0,     1)
#                 深度      x方向階數 y方向階數

?二、實戰

首先欣賞下原圖及灰度圖:

src = imread("Resource/test12.jpg");imshow("原圖", src);cvtColor(src, gray, COLOR_RGB2GRAY);   //轉變為灰度圖imshow("灰度圖", src);

1、對x方向微分

對x方向微分,得到的是y方向的邊緣。?

//對x方向微分Sobel(gray, grad_x, CV_16S, 1,                      0,                      3);   //                          x方向差分階數           y方向差分階數           核大小convertScaleAbs(grad_x, abs_grad_x);     //可將任意類型的數據轉化為CV_8UC1imshow("【邊緣圖x】", abs_grad_x); //邊緣與梯度方向垂直,所以輸出的邊緣是和我們所計算的某一方向的梯度是垂直的

2、對y方向微分

對y方向微分,得到的是x方向的邊緣。??

//對y方向微分Sobel(gray, grad_y, CV_16S, 0,                      1,                      3);//                         x方向差分階數           y方向差分階數           核大小convertScaleAbs(grad_y, abs_grad_y);     //可將任意類型的數據轉化為CV_8UC1imshow("邊緣圖y", abs_grad_y);

3、線性混合

//圖像的線性混合addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);imshow("線性混合", dst);

總代碼

C++:

//Sobel算子(微分)
#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;int main()
{Mat src, dst, gray, grad_x, grad_y, abs_grad_x, abs_grad_y;src = imread("Resource/test12.jpg");imshow("原圖", src);cvtColor(src, gray, COLOR_RGB2GRAY);   //轉變為灰度圖imshow("灰度圖", gray);//對x方向微分Sobel(gray, grad_x, CV_16S, 1,                      0,                      3);   //                                          x方向差分階數   y方向差分階數   核大小convertScaleAbs(grad_x, abs_grad_x);     //可將任意類型的數據轉化為CV_8UC1imshow("邊緣圖x", abs_grad_x); //邊緣與梯度方向垂直,所以輸出的邊緣是和我們所計算的某一方向的梯度是垂直的//對y方向微分Sobel(gray, grad_y, CV_16S, 0,                      1,                      3);//                                          x方向差分階數   y方向差分階數   核大小convertScaleAbs(grad_y, abs_grad_y);     //可將任意類型的數據轉化為CV_8UC1imshow("邊緣圖y", abs_grad_y);//圖像的線性混合addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);imshow("線性混合", dst);waitKey(0);
}

python:

# 邊緣檢測(Sobel、Laplace、Canny)
import cv2 as cv# Sobel一階微分算子
def Sobel():# 1、對X和Y方向求微分x = cv.Sobel(img, cv.CV_16S, 1,     0)y = cv.Sobel(img, cv.CV_16S, 0,     1)#                 深度      x方向階數 y方向階數# 2、取絕對值absX = cv.convertScaleAbs(x)  # 轉回uint8absY = cv.convertScaleAbs(y)# 3、線性混合dst = cv.addWeighted(absX, 0.5, absY, 0.5, 0)#                          比例       比例  常數# 4、顯示cv.imshow("absX", absX)cv.imshow("absY", absY)cv.imshow("dst", dst)if __name__ == '__main__':# 讀取圖片img = cv.imread("Resource/test5.jpg")cv.imshow("img", img)Sobel()         #Sobel一階微分算子cv.waitKey(0)

其他應用

x方向梯度使豎直的黑條特征變得明顯):

?

參考資料

https://blog.csdn.net/weixin_44586473/article/details/93229385?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162895010516780271586263%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162895010516780271586263&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-93229385.ecpm_v1_rank_v29&utm_term=sobel&spm=1018.2226.3001.4187

https://www.baidu.com/link?url=14oBZycvBio7eVQbSDl-XWg_eyg92lbbpOCNxZu5g-rxq39fby3yvmI-_OYGULcmmQ0SuvMyGJU0dBPCZBeEYKHPi_pldWGT23zLbLry6DG&wd=&eqid=efae8130000106120000000561187322

https://www.bilibili.com/video/BV1Fo4y1d7JL?p=34&spm_id_from=pageDriver

總結

以上是生活随笔為你收集整理的OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)的全部內容,希望文章能夠幫你解決所遇到的問題。

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