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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV中的Sobel算子

發(fā)布時(shí)間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV中的Sobel算子 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

OpenCV中的Sobel算子

剛開始第一次接觸這個(gè)東西的時(shí)候也是感覺一臉懵逼,這是什么鬼。完全看不懂。今天再次接觸到,感覺理解的透徹了一點(diǎn)。
首先來看一下Sobel算子是個(gè)什么東西:

-101
-202
-101

這個(gè)就是Sobel算子中的一個(gè),就以這個(gè)為例。可以看出來這個(gè)就是之前說的那個(gè)核。用這個(gè)核去和原圖像進(jìn)行卷積操作。那根據(jù)核可以知道,卷積過后得到的輸出圖像中每個(gè)點(diǎn)的像素值,為兩列差的和,回想一下求導(dǎo)的定義式,函數(shù)的差值/自變量的差值。所以這里得到的輸出圖像的每個(gè)點(diǎn)的值,可以看成原圖像在該點(diǎn)的導(dǎo)數(shù)。因?yàn)閳D像的是二維的,所以以上所說都是在X方向。
根據(jù)這個(gè)理論,不難知道,在邊緣處像素值發(fā)生了顯著的變化,表示這一變化一個(gè)方法就是利用導(dǎo)數(shù)。
Y方向的算子:

-1-2-1
000
121

道理和X方向的相同。
下面看一下X方向的導(dǎo)數(shù)的手動實(shí)現(xiàn)吧!

Mat Soble(const Mat src,const Mat_<int> kernel) {Mat dst,temp,s;temp = Mat::zeros(src.size(),src.type());src.copyTo(dst);kernel.copyTo(s);int height = src.rows;int width = src.cols;int size = kernel.rows;int add = (size-1)/2;uchar* pre;uchar* cur;uchar* next;int* ker = s.ptr<int>(0);for(int row = 0;row < height-1;row++){pre = dst.ptr<uchar>(row-1);cur = dst.ptr<uchar>(row);next = dst.ptr<uchar>(row+1);for(int col = 0;col < width - 1;col++){temp.at<uchar>(row,col) = saturate_cast<uchar>(pre[col-1]*ker[0] + pre[col]*ker[1] + pre[col+1]*ker[2]+cur[col-1]*ker[3] + cur[col]*ker[4] + cur[col+1]*ker[5]+next[col-1]*ker[6] + next[col]*ker[7] + next[col+1]*ker[8]);}}imshow("temp",temp);return temp;}

編寫的流程與自定義線性濾波器那塊是一樣的。
同樣的OpenCV為了我們方便,也提供了相應(yīng)的API:

Sobel(輸入圖像,輸出圖像,圖像深度,CV_16S防止外溢x方向的導(dǎo)數(shù)的階數(shù),y方向的導(dǎo)數(shù)的階數(shù),scale,默認(rèn)為1,delta,默認(rèn)為0;BORDER_DEFAULT );

下面是完整的代碼:

#include <ros/ros.h> #include "opencv2/opencv.hpp"using namespace std; using namespace cv;Mat Soble(const Mat src,const Mat_<int> kernel);int main(int argc, char *argv[]) {Mat src,dst;src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/map.png",0);imshow("src",src);GaussianBlur(src,src,Size(3,3),0,0,BORDER_DEFAULT);Mat_<int> kernel = (Mat_<int>(3,3) << -1,0,1,-2,0,2,-1,0,1);Soble(src,kernel);Sobel(src,dst,CV_16S,1,0,3,1,0,BORDER_DEFAULT);imshow("apt",dst);convertScaleAbs(dst,src);imshow("api",src);waitKey(0);return 0; }Mat Soble(const Mat src,const Mat_<int> kernel) {Mat dst,temp,s;temp = Mat::zeros(src.size(),src.type());src.copyTo(dst);kernel.copyTo(s);int height = src.rows;int width = src.cols;int size = kernel.rows;int add = (size-1)/2;uchar* pre;uchar* cur;uchar* next;int* ker = s.ptr<int>(0);for(int row = 0;row < height-1;row++){pre = dst.ptr<uchar>(row-1);cur = dst.ptr<uchar>(row);next = dst.ptr<uchar>(row+1);for(int col = 0;col < width - 1;col++){temp.at<uchar>(row,col) = saturate_cast<uchar>(pre[col-1]*ker[0] + pre[col]*ker[1] + pre[col+1]*ker[2]+cur[col-1]*ker[3] + cur[col]*ker[4] + cur[col+1]*ker[5]+next[col-1]*ker[6] + next[col]*ker[7] + next[col+1]*ker[8]);}}imshow("temp",temp);return temp;}

其中,通常在進(jìn)行Sobel時(shí),要先進(jìn)行高斯模糊,具體原因未知。
其次,求完導(dǎo)數(shù)以后,得到的圖像中部分像素會是負(fù)值,或者超過了255,所以利用convertScaleAbs(src,dst)來將圖像的每個(gè)像素變?yōu)?~255之間。

總結(jié)

以上是生活随笔為你收集整理的OpenCV中的Sobel算子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。