2012-02-17 134 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