1. 程式人生 > >OpenCV 實現canny邊緣檢測

OpenCV 實現canny邊緣檢測

近期,整理了一些之前做過的影象處理內容,算是複習下基礎吧;

涉及canny邊緣檢測的OpenCV實現;

影象邊緣資訊主要集中在高頻段,通常說影象銳化或檢測邊緣,實質就是高頻濾波。Canny是常用的邊緣檢測方法,其特點是試圖將獨立邊的候選畫素拼裝成輪廓。

canny邊緣檢測運算元是一種多級檢測演算法。1986年由John F. Canny提出,同時提出了邊緣檢測的三大準則:

  1. 低錯誤率的邊緣檢測:檢測演算法應該精確地找到影象中的儘可能多的邊緣,儘可能的減少漏檢和誤檢。
  2. 最優定位:檢測的邊緣點應該精確地定位於邊緣的中心。
  3. 影象中的任意邊緣應該只被標記一次,同時影象噪聲不應產生偽邊緣.

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直接呼叫的攝像頭,貼出自己的結果圖。