OpenCV中的Sobel算子
生活随笔
收集整理的這篇文章主要介紹了
OpenCV中的Sobel算子
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
OpenCV中的Sobel算子
剛開始第一次接觸這個東西的時候也是感覺一臉懵逼,這是什么鬼。完全看不懂。今天再次接觸到,感覺理解的透徹了一點。
首先來看一下Sobel算子是個什么東西:
| -2 | 0 | 2 |
| -1 | 0 | 1 |
這個就是Sobel算子中的一個,就以這個為例。可以看出來這個就是之前說的那個核。用這個核去和原圖像進行卷積操作。那根據核可以知道,卷積過后得到的輸出圖像中每個點的像素值,為兩列差的和,回想一下求導的定義式,函數的差值/自變量的差值。所以這里得到的輸出圖像的每個點的值,可以看成原圖像在該點的導數。因為圖像的是二維的,所以以上所說都是在X方向。
根據這個理論,不難知道,在邊緣處像素值發生了顯著的變化,表示這一變化一個方法就是利用導數。
Y方向的算子:
| 0 | 0 | 0 |
| 1 | 2 | 1 |
道理和X方向的相同。
下面看一下X方向的導數的手動實現吧!
編寫的流程與自定義線性濾波器那塊是一樣的。
同樣的OpenCV為了我們方便,也提供了相應的API:
下面是完整的代碼:
#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;}其中,通常在進行Sobel時,要先進行高斯模糊,具體原因未知。
其次,求完導數以后,得到的圖像中部分像素會是負值,或者超過了255,所以利用convertScaleAbs(src,dst)來將圖像的每個像素變為0~255之間。
總結
以上是生活随笔為你收集整理的OpenCV中的Sobel算子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux脚本编程(shell)浅介
- 下一篇: 用C语言Linux下打印带颜色的字符串