1. 程式人生 > >OpenCV學習之canny演算法邊緣檢測

OpenCV學習之canny演算法邊緣檢測

#include <iostream>

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/opencv.hpp>

using namespace std;

using namespace cv;

//在OpenCV中使用 using namespace cv 的作用:在使用#include語句包含相應標頭檔案後,使用下面語句即可包含相應的Opencv名稱空間 using namespace cv;如果沒有這個語句,那麼在這個名稱空間的相關資源就需要帶上cv字首,如cv::Mat,表示的是使用名稱空間cv中的Mat;而有了using namespace cv這個語句後,就可以直接寫Mat。std同理

//定義新函式
//IplImage 是OpenCV裡的一個結構;帶兩個星號是指標的指標,一般用來表示二位陣列
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);
    
    //cvGetSize OpenCV提供的一種操作矩陣影象的函式。得到二維的陣列的尺寸,以CvSize返回。CvSize cvGetSize( const CvArr* arr );
//    它與cvGetDims()密切相關,cvGetDims()返回一個數組的大小。主要的不同是cvGetSize()是專為矩陣和影象設計的,這兩種物件的維數總是2。其尺寸可以以CvSize結構的形式返回,例如當建立一個新的大小相同的矩陣或影象時,使用此函式就很方便。OpenCV提供了多種基本資料型別。其中有一種是CvSize型別,它的資料成員是integer型別的width和height。如果希望使用浮點型別,則選用CvSize的變體型別CvSize2D32f。
    
    
//如果我們要建立一個寬為360,高為640的3通道影象(RGB影象),可以採用如下語
//    句:IplImage* img=cvCreateImage( cvSize(360,640), IPL_DEPTH_8U,3 );
//    類似的,如果要初始化一張相同大小的灰度影象,可以採用如下語句:
//    IplImage* img=cvCreateImage( cvSize(360,640), IPL_DEPTH_8U,1 );
    
   cvCanny(image_input,image_output,lowThresh,highThresh,aperture);
//image_input 輸入單通道影象(可以是彩色影象)對於多通道的影象可以用cvCvtColor()修改。image_output 輸出的邊緣影象 ,也是單通道的,但是是黑白的
// lowThresh 第一個閾值  highThresh 第二個閾值   aperture_size Sobel 運算元核心大小
// 函式 cvCanny 採用 Canny 演算法發現輸入影象的邊緣而且在輸出影象中標識這些邊緣。threshold1和threshold2 當中的小閾值用來控制邊緣連線,大的閾值用來    控制強邊緣的初始分割。
    
    return(image_output);
    
}





int main(int argc, char* argv[])

{
    
  cvNamedWindow("Camera" , CV_WINDOW_AUTOSIZE );
//    cvNamedWindow("Camera" , 0 );
    
    // int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );
//    name 視窗的名字,它被用來區分不同的視窗,並被顯示為視窗標題。
// flags 視窗屬性標誌。可以選擇CV_WINDOW_AUTOSIZE(1)和0兩種值。CV_WINDOW_AUTOSIZE這個標誌被設定後, 如果使用者不能手動改變視窗大小,視窗大小會自動調整以適合被顯示影象(參考cvShowImage)。0表示使用者可以手動調節視窗大小,且顯示的影象尺寸隨之變化。
// 函式cvNamedWindow建立一個可以放置影象和trackbar的視窗。被建立的視窗可以通過它們的名字被引用。 如果已經存在這個名字的視窗,這個函式將不做任何事情。
  CvCapture* capture = cvCreateCameraCapture(CV_CAP_ANY);
// CvCapture* cvCreateCameraCapture( int index );index:要使用的攝像頭索引(見下表[2]  )。如果只有一個攝像機時,引數值取0。當引數被設定為-1時,OpenCV會開啟一個視窗讓使用者選擇需要使用的攝像機。 CV_CAP_ANY就是0.
//CvCapture是一個結構體,用來儲存影象捕獲的資訊,就像一種資料型別(如int,char等)只是存放的內容不一樣,在OpenCv中,它最大的作用就是處理視訊時(程式是按一幀一幀讀取),讓程式讀下一幀的位置,CvCapture結構中,每獲取一幀後,這些資訊都將被更新,獲取下一幀回覆
    
 assert(capture != NULL);
    
//assert巨集的原型定義在<assert.h>中,其作用是如果它的條件返回錯誤,則終止程式執行,原型定義:#include <assert.h> void assert( int expression );
//    assert的作用是現計算表示式 expression ,如果其值為假(即為0),那麼它先向stderr列印一條出錯資訊,然後通過呼叫 abort 來終止程式執行
    
  IplImage *frame = 0;
//建立一個Iplmage格式的指標frame,並對其初始賦值為0(空)
  frame = cvQueryFrame(capture);
    
//函式cvQueryFrame從攝像頭或者檔案中抓取一幀,然後解壓並返回這一幀。這個函式僅僅是函式cvGrabFrame和函式cvRetrieveFrame在一起呼叫的組合。返回的影象不可以被使用者釋放或者修改。抓取後,capture被指向下一幀,可用cvSetCaptureProperty調整capture到合適的幀。注意: cvQueryFrame返回的指標總是指向同一塊記憶體。建議cvQueryFrame後拷貝一份。而且返回的幀需要FLIP後才符合OPENCV的座標系。若返回值為NULL,說明到了視訊的最後一幀。

//IplImage* frame = cvQueryFrame( CvCapture* capture );
//    
// // IplImage* frame0 = 0;
////    IplImage* frame1 = 0;
////    IplImage* frame2 = 0;
//    
////    frame0 = cvQueryFrame( capture );
////    cvSaveImage("frame0.jpg",frame0);
// //   for (i=0;i<10;i++)
////    {
//        frame2=cvQueryFrame(capture);
//    }
//    frame1=cvCloneImage(frame0);
//    cvSaveImage("frame2.jpg",frame2);
//    cvSaveImage("frame1.jpg",frame1);
    
 IplImage *frame_edge = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U,1);
    
    while(1){
        
        frame = cvQueryFrame(capture);
        
        if(!frame) break;
 
        cvConvertImage(frame,frame_edge,0);
    //把frame轉換成frame_edge的格式,現在應該是frame_edge是所需影象
        // cvConvertImage()用於不同影象格式之間的轉換,可垂直翻轉影象或者交換紅藍通道。把一幅影象轉換為另外一幅,並可以選擇同時對其進行垂直翻轉
        
//        void cvConvertImage( const CvArr* src, CvArr* dst, int flags=0 );
//          src 輸入影象。 dst 目標影象。必須為單通道或者3通道8點陣圖像。flags是轉換的模式,可以取0:沒有變化;1:垂直翻轉,即沿x軸翻轉;2:交換紅藍通道;  CV_CVTIMG_FLIP - 垂直翻轉影象。CV_CVTIMG_SWAP_RB - 交換紅藍通道 flags=0應該就是不同時進行任何操作
//單通道圖,俗稱灰度圖,每個畫素點只能有有一個值表示顏色,它的畫素值在0到255之間,0是黑色,255是白色,中間值是一些不同等級的灰色。(也有3通道的灰度圖,3通道灰度圖只有一個通道有值,其他兩個通道的值都是零)。
        
// 三通道圖,每個畫素點都有3個值表示,所以就是3通道。也有4通道的圖。例如RGB圖片即為三通道圖片,RGB色彩模式是工業界的一種顏色標準,是通過對紅(R)、綠(G)、藍(B)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的,RGB即是代表紅、綠、藍三個通道的顏色,這個標準幾乎包括了人類視力所能感知的所有顏色,是目前運用最廣的顏色系統之一。總之,每一個點由三個值表示。
        
        frame = cvCloneImage(frame_edge);
 
        frame_edge = doCanny(frame_edge,70,90,3);
        
//對frame_edge進行canny 提取
        
        cvShowImage("Camera",frame_edge);
        
        char c = cvWaitKey(15);
        
        if(c == 27)  break;
 }
/*    首先,在cvWaitKey(k)中,k的單位為毫秒,1000毫秒等於1秒,同時,根據資料的說明,在顯示影象的時候,每秒顯示27、28幀的時候,我們看到的視訊是流暢的。同時採取25幀的話,k=1000/25=40。即,沒處理完一幀後,程式會等待40毫秒才會讀取下一幀;
    
    
    
    1.顯示影象,一般要在cvShowImage()函式後加一句cvWaitKey(0),此時程式顯示出影象後將暫停,等待接收一個鍵盤輸入;若沒有這句話,則顯示影象的程式碼很快就執行過去了,所以要用cvWaitKey()來暫停。
    
    
    
    
    
    2.顯示視訊時,一般用cvWaitKey(delay) delay是延時的ms數。表示顯示一幀,然後等delay ms ,再顯示下一幀。如果沒有cvWaitKey的話, 那麼迴圈裡面的每個指令執行時間為0.0000000001s,總之趨近於0.那麼capture可能有10000幀影象, 那麼10000幀影象也之需要0.000001s就播放完了, 結果你還沒看到畫面,就已經黑屏了 ....
    
    若delay=0,則無限期等待,直到按下鍵盤任意按鍵。
    
    
    
    3.
    
    char c = cvWaitKey(200);
    
    
    if (c == 27)
        
         break;
    
    
    
    c :為按鍵的ASCⅡ碼值,常用ASCⅡ碼值:
    
   ESC:ASCⅡ碼27
   回車:ASCⅡ碼13
   換行(Ctrl + Enter):ASCⅡ碼10
 空格:ASCⅡ碼32 */
 
    cvReleaseCapture(&capture);
    
    cvReleaseImage( &frame_edge );
    
    cvReleaseImage( &frame);
    
// 釋放指標所佔空間
    
    
    
    return (int)0;
    
}


部落格裡的程式摘自網路,學習的時候加了許多註釋,若侵權請私信,會刪掉。

相關推薦

OpenCV學習canny演算法邊緣檢測

#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/ope

OpenCV學習Canny邊緣檢測

    影象的邊緣檢測的原理是檢測出影象中所有灰度值變化較大的點,而且這些點連線起來就構成了若干線條,這些線條就可以稱為影象的邊緣。     Canny邊緣檢測運算元是John F. Canny於 1986 年開發出來的一個多級邊緣檢測演算法。Canny 邊緣檢測的數學原理

OpenCV-PythonCanny邊緣檢測

Canny演算法步驟 ①高斯模糊 - GaussianBlur ②灰度轉換 - cvtColor ③計算梯度 – Sobel/Scharr ④非最大訊號抑制 ⑤高低閾值輸出二值影象——高低閾值比值為2:1或3:1最佳 程式碼演示 # Canny運算元 def Canny_de

邊緣檢測Canny演算法_Qt實現(C++)

邊緣檢測之Canny演算法_Qt實現(C++) Canny邊緣檢測演算法的簡單介紹   Canny的目標是找到一個最優的邊緣檢測演算法,最優邊緣檢測的含義是: 好的檢測 - 演算法能夠儘可能多地標識出影象中的實際邊緣。 好的定位 - 標識出的

Opencv學習影象邊緣檢測

該部落格只為記錄點滴所學,若有誤導,還請大家原諒,並不吝賜教。          一直不太明白應用函式求導的方法能求出影象強度變化的邊緣,其實就是影象邊緣檢測。現在終於想通了,解釋如下。比如一張如下的圖片: 圖1 檢測邊緣可以檢測到狗和兔子的輪廓。因為它們的輪廓跟其周

opencv目標檢測canny演算法

canny canny的目標有3個 低錯誤率 檢測出的邊緣都是真正的邊緣 定位良好 邊緣上的畫素點與真正的邊緣上的畫素點距離應該最小 最小響應 邊緣只能標識一次,噪聲不應該標註為邊緣 canny分幾步 濾掉噪聲 比如高斯濾波 計算梯度 比如用索貝爾運算元算出梯度 非極大值抑制 上一步算出來的邊緣可能比較

opencv學習三十八】影象的分水嶺演算法

分水嶺演算法主要根據影象梯度將影象分割成“山”和“谷”;一般影象噪聲經常干擾分水嶺演算法的分割,所以一般採用標記的方法來給分水嶺演算法提供灰度級參考,來更換的分割影象;從效果來說比普通的灰度閾值分割效果要好;演算法的具體原理和實現可參考網上的詳解;原函式及解釋:CV_EXPO

opencv學習四十三】K均值聚類演算法

K均值聚類演算法,在opencv中通過kmeans()函式實現;k均值通俗講:就是從一堆樣本中,隨便挑出幾個,比如3個吧,然後用樣本中的和這挑出來的比較,比較後排序,誰和挑出的那個接近就把他劃到那個類裡,比如樣A和挑1、挑2、挑3中,挑2最接近,則把樣A劃到挑2裡,當然還沒完

opencv學習四十二】簡單運動檢測

視訊運動檢測基本思想是進行每一幀對比,檢測不同然後得出是否運動,一般分為兩種,背景法和差幀法;背景法是:將一幅圖作為背景,讓後和每一幀對比;缺點是一開始存入的背景可能隨光照變法而造成錯誤,但是可以用在光照環境穩定的地方,優點是可以檢測之前背景沒有的景象;差幀法是:將前一幀和後

opencv學習(三)-LBP演算法的研究及其實現

一,原始LBP演算法 LBP的基本思想是對影象的畫素和它區域性周圍畫素進行對比後的結果進行求和。把這個畫素作為中心,對相鄰畫素進行閾值比較。如果中心畫素的亮度大於等於他的相鄰畫素,把他標記為1,否則標記為0。你會用二進位制數字來表示每個畫素,比如11001111。因此,由於

Opencv影象識別從零到精通(21)-----canny運算元邊緣檢測

          最後來看看canny運算元,這個是被成為最好的運算元,因為過程多,有準測,後面會列出來,也是邊緣檢測的最後一個,所以這裡作為結尾,來看看各個邊緣檢測的效果。 邊緣檢測結果比較

Opencv中的幾種邊緣檢測演算法

1、Sobel導數 Sobel運算元結合了高斯平滑和微分求導。可以用來計算影象灰度函式的近似梯度。計算時是將原影象分別與水平方向和豎直方向的奇數大小的核心進行卷積,然後再影象的每一點上進行計算(求根號

OpenCV學習路——車牌識別車牌定位

pla sim srand oval 模糊 fault .html swa ide 去年七月份因為學校項目需要開始接觸圖像處理,但那時候只是到網上找車牌識別代碼,然後加入到自己的項目中,不清楚細節原理。 現在自己重新一步步實現車牌識別。 高斯模糊: 1 Mat Ga

OpenCV學習代碼記錄——人臉檢測

puts tro 按鍵 img IE source cpu cpp gray 很久之前學習過一段時間的OpenCV,當時沒有做什麽筆記,但是代碼都還在,這裏把它貼出來做個記錄。 代碼放在碼雲上,地址在這裏https://gitee.com/solym/OpenCVTest/

機器學習Apriori演算法和FP-growth演算法

1 關聯分析 無監督機器學習方法中的關聯分析問題。關聯分析可以用於回答"哪些商品經常被同時購買?"之類的問題。 2 Apriori演算法   頻繁項集即出現次數多的資料集   支援度就是幾個關聯的資料在資料集中出現的次數佔總資料集的比重。或者說幾個資料關聯出現的概率。   置信度體現了一個數據出現後,另

[六]機器學習EM演算法

6.1 實驗概要 通過EM演算法解決部分觀測資料的引數估計問題,使用sklearn提供的EM模組和高斯混合模型資料集,實驗EM演算法的實際效果 6.2 實驗輸入描述 本次實驗使用模擬資料集,該資料集有300條資料構成,每個樣本為3維。假定該資料由兩個高斯分佈混合得到。 &nbs

【ML1】機器學習EM演算法(含演算法詳細推導過程)

        寫在前面的話:對於EM演算法(Expectation Maximization Algorithm, 最大期望演算法), 大家如果僅僅是為了使用,則熟悉演算法流程即可。此處的演算法推導過程,僅提供給大家進階 之用。對於其應用,

Opencv 學習路(一)

前面很長一段時間一直在用opencv庫但是一直沒有去系統的學習,都是遇到問題直接百度,連庫內大多數函式都不認識。最近閒下來了打算系統將opencv學習下 1、開啟圖片 2、讀取視訊 3、開啟攝像頭拍照 4、對攝像頭捕獲的畫面進行處理 開啟圖片 #includ

Opencv 學習路(四)

                                        影象處理函式大集合 1、感興趣區域:ROI Mat imageROI = image(Rect(500,250,logo.cols,logo.rows) ); 引數解釋: image

分散式學習raft演算法

0、背景介紹 一、為什麼要學習分散式系統以及raft演算法 二、我的分散式系統學習方法 三、總結 參考連結: raft經典場景分析 一致性演算法允許多臺機器作為一個叢集協同工作,並且在其中的某幾臺機器出故障時叢集仍然能正常工作。  正因為如此