C++ 使用 openCV 去除二值图像中的噪声

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9323384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:40:19  来源:igfitidea点击:

removing noise in a binary image using openCV

c++opencvcomputer-visionnoise-reduction

提问by sue-ling

I had read in a video into Visual Studio using openCV and converted it to grayscale then used the function CV_THRESH_BINARY to convert it into a binary image. However, there are holes and noise in the frames. What is a simple way to remove noise or the holes? I have read up on the Erode and Dilate functions in openCV but I am not too clear on how to use them. this is my code so far. If anyone can show me how to incorporate the noise removal into my code, it would be greatly appreciated.

我使用 openCV 将视频读入 Visual Studio 并将其转换为灰度,然后使用函数 CV_THRESH_BINARY 将其转换为二进制图像。但是,框架中有孔洞和噪音。去除噪音或孔洞的简单方法是什么?我已经阅读了 openCV 中的 Erode 和 Dilate 函数,但我不太清楚如何使用它们。到目前为止,这是我的代码。如果有人可以向我展示如何将噪声消除合并到我的代码中,我将不胜感激。

#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;
}

回答by Tomasz Niedabylski

DISCLAIMER: It is hard to give a good answer, because you provided very little info. If you posted your image before and after binarization, it would be much easier. However, I will try to give some hints.

免责声明:很难给出一个好的答案,因为你提供的信息很少。如果你在二值化之前和之后发布你的图像,它会容易得多。但是,我会尝试给出一些提示。

If the holes are rather big, then probably threshold value is wrong, try increasing or decreasing it and check the result. You can try

如果洞比较大,那么可能是阈值不对,尝试增加或减少它并检查结果。你可以试试

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

This will calculate threshold value automatically. If you cannot find a good thresholding value, then try some adaptive thresholding algorithms, opencv has adaptiveThreshold() function, but it's not so good.

这将自动计算阈值。如果你找不到合适的阈值,那么尝试一些自适应阈值算法,opencv有adaptiveThreshold()函数,但效果不是很好。

If the holes and noise are rather small (few pixels each), you can try some of the following:

如果孔洞和噪声很小(每个像素很少),您可以尝试以下一些方法:

  • Using opening (erosion, next dilatation) to remove white noise and closing(dilatation, next erosion) to small black noise. But remember, that opening, while removing white noise, will also strengthen black noise and vice versa.

  • Median blur AFTER you do thresholding. It may remove small noise, both black and white, while preserving colors (image will stil be binary) and, with posssible small errors, shapes. Applying median blur BEFORE binarization may also help reduce small noise.

  • 使用开(腐蚀,下一次膨胀)去除白噪声,使用闭(膨胀,下一次腐蚀)去除小黑噪声。但请记住,该开口在去除白噪声的同时也会增强黑噪声,反之亦然。

  • 进行阈值处理后的中值模糊。它可以去除黑色和白色的小噪声,同时保留颜色(图像仍然是二进制的),并且可能存在小的错误,形状。在二值化之前应用中值模糊也可能有助于减少小噪音。

回答by Mark Ransom

You might try using a Smoothfunction with CV_MEDIANbefore you do the thresholding.

在进行阈值处理之前,您可以尝试使用Smooth函数CV_MEDIAN