Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

removing noise in a binary image using openCV

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.

#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;
}
like image 571
sue-ling Avatar asked Feb 17 '12 05:02

sue-ling


2 Answers

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.

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.

like image 92
Tomasz Niedabylski Avatar answered Oct 17 '22 10:10

Tomasz Niedabylski


You might try using a Smooth function with CV_MEDIAN before you do the thresholding.

like image 45
Mark Ransom Avatar answered Oct 17 '22 09:10

Mark Ransom