OpenCV 實現canny邊緣檢測
阿新 • • 發佈:2019-01-29
近期,整理了一些之前做過的影象處理內容,算是複習下基礎吧;
涉及canny邊緣檢測的OpenCV實現;
影象邊緣資訊主要集中在高頻段,通常說影象銳化或檢測邊緣,實質就是高頻濾波。Canny是常用的邊緣檢測方法,其特點是試圖將獨立邊的候選畫素拼裝成輪廓。
canny邊緣檢測運算元是一種多級檢測演算法。1986年由John F. Canny提出,同時提出了邊緣檢測的三大準則:
- 低錯誤率的邊緣檢測:檢測演算法應該精確地找到影象中的儘可能多的邊緣,儘可能的減少漏檢和誤檢。
- 最優定位:檢測的邊緣點應該精確地定位於邊緣的中心。
- 影象中的任意邊緣應該只被標記一次,同時影象噪聲不應產生偽邊緣.
Canny運算元求邊緣點具體演算法步驟如下:
1. 用高斯濾波器平滑影象.
2. 用一階偏導有限差分計算梯度幅值和方向.
3. 對梯度幅值進行非極大值抑制 .
4. 用雙閾值演算法檢測和連線邊緣
對新手來說,OpenCV的開發環境配置是第一步,建議按照mac平臺下Opencv開發環境設定進行配置,對新手很友好;
不多說;上程式碼。
//
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
IplImage* doCanny(IplImage* image_input, double lowThresh, double highThresh, double aperture)
{
if(image_input->nChannels != 1)
return(0);
IplImage* image_output = cvCreateImage(cvGetSize(image_input), image_input->depth, image_input->nChannels);
cvCanny(image_input, image_output, lowThresh, highThresh, aperture);//canny邊緣檢測,aperture為所用sobel運算元核心大小
return(image_output);
}
int main(int argc, const char * argv[]) {
// insert code here...
cvNamedWindow("macCamera",CV_WINDOW_AUTOSIZE);
CvCapture *capture = cvCreateCameraCapture(CV_CAP_ANY);//建立CvCapture結構的指標,作為cvQueryFrame的輸入
assert(capture != NULL);//assert的作用是現計算表示式 expression ,如果其值為假(即為0),那麼它先列印一條出錯資訊,然後通過呼叫 abort 來終止程式執行
IplImage *frame =0; //初始化指向IplImage結構的指標 frame
frame = cvQueryFrame(capture); //從攝像頭讀取每一幀
IplImage *frame_edge =cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);//定義的邊緣檢測後的frame_edge,8位無符號整數灰度圖
while(1)
{
frame = cvQueryFrame(capture);
if(!frame) break;
// cvShowImage("macCamera", frame);
cvConvertImage(frame, frame_edge,0);
frame =cvCloneImage(frame_edge);
frame_edge = doCanny(frame_edge, 50, 110, 3);
cvShowImage("macCamera", frame_edge);
std::cout << "Canny success!\n";
char c =cvWaitKey(30);
if(c == 27) break;
}
cvReleaseCapture(&capture);
cvReleaseImage(&frame_edge);
cvReleaseImage(&frame);
return (int)0;
}
OpenCV直接呼叫的攝像頭,貼出自己的結果圖。