2012-02-17 76 views
7

我已經使用openCV將視頻讀入Visual Studio並將其轉換爲灰度,然後使用函數CV_THRESH_BINARY將其轉換爲二進制圖像。但是,在框架中有孔和噪音。什麼是消除噪音或孔的簡單方法?我已經閱讀了openCV中的Erode和Dilate函數,但我不太清楚如何使用它們。這是我的代碼到目前爲止。如果任何人都可以告訴我如何將噪音消除納入我的代碼,將不勝感激。使用openCV去除二進制圖像中的噪聲

#include "cv.h" 
#include "highgui.h" 

int main(int argc, char* argv) { 

CvCapture *capture = NULL; 
capture = cvCaptureFromAVI("C:\\walking\\lady walking.avi"); 
if(!capture){ 
    return -1; 
} 

IplImage* color_frame = NULL; 
IplImage* gray_frame = NULL ; 
int thresh_frame = 70; 

int frameCount=0;//Counts every 5 frames 
cvNamedWindow("Binary video", CV_WINDOW_AUTOSIZE); 

while(1) { 
    color_frame = cvQueryFrame(capture);//Grabs the frame from a file 
    if(!color_frame) break; 
    gray_frame = cvCreateImage(cvSize(color_frame->width, color_frame->height),  color_frame->depth, 1); 
    if(!color_frame) break;// If the frame does not exist, quit the loop 

    frameCount++; 
    if(frameCount==5) 
    { 
     cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY); 
     cvThreshold(gray_frame, gray_frame, thresh_frame, 255, CV_THRESH_BINARY); 
     cvShowImage("Binary video", gray_frame); 
     frameCount=0; 
    } 
    char c = cvWaitKey(33); 
    if(c == 27) break; 
} 

cvReleaseImage(&color_frame); 
cvReleaseImage(&gray_frame); 
cvReleaseCapture(&capture); 
cvDestroyWindow("Grayscale video"); 

return 0; 
} 

回答

9

免責聲明:很難給出一個好的答案,因爲你提供的信息很少。如果你在二值化之前和之後發佈你的圖片,它會容易得多。不過,我會試着給出一些提示。

如果孔比較大,那麼閾值可能是錯誤的,嘗試增加或減少它並檢查結果。您可以嘗試

cv::threshold(gray_frame, gray_frame, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); 

這將自動計算閾值。 如果你找不到一個好的閾值,然後嘗試一些自適應閾值算法,opencv有adaptiveThreshold()函數,但它不太好。

如果孔和噪音相當小(每幾個像素),你可以嘗試以下一些:

  • 使用開口(糜爛,未來擴張)去除白噪聲和關閉(擴張,下一個侵蝕)到小的黑色噪音。但請記住,在打開白色噪音的同時,也會加強黑色噪音,反之亦然。

  • 在進行閾值處理後,模糊中位數。它可以去除小的噪點,包括黑色和白色,同時保留顏色(圖像將是二進制),以及可能出現的小錯誤,形狀。在二值化之前應用中值模糊也可能有助於減少小噪聲。

+0

我很抱歉沒有提供圖像,但非常感謝您的幫助。我用cvErode函數刪除了圖像中的一些孔,但我也會嘗試中值模糊。當你提到使用打開和關閉時,是否必須一起使用它們,或者執行CV_MOP_OPEN或CV_MOP_CLOSE? – 2012-02-17 18:17:30

+0

你仍然可以提供他們:)你可以使用其中一個或兩個,一個接一個,這取決於你想要什麼。只需檢查結果和實驗。 – 2012-02-17 20:09:35

+0

我檢查了結果,並決定使用Erode和Dilate函數獲得更好的結果,因此我將一個接一個地使用它們。無論如何,我不知道如何提供圖像,因爲我是新的stackoverflow:/我很抱歉。我目前正在開發一個涉及C++和openCV的圖像處理項目。它基於動作識別,所以如果我發佈任何更多的問題,我將不勝感激,如果您可以提供一些幫助,因爲您已經非常有幫助。謝謝:) – 2012-02-19 01:48:40

1

你可以嘗試這樣做的閾值之前使用Smooth函數CV_MEDIAN

+0

這會達到與侵蝕和擴張功能相同的結果嗎?您是否熟悉這些功能的使用? – 2012-02-17 06:05:10

+0

你可以使用打開和關閉(侵蝕+擴張,反之亦然),顯然你需要調整內核大小 – andrea 2012-02-17 07:59:56

+0

我可以使用打開或關閉功能,或者我必須一起使用它們嗎? – 2012-02-17 17:46:05