removing noise in a binary image using openCV
Asked Answered
M

2

8

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;
}
Marotta answered 17/2, 2012 at 5:31 Comment(0)
S
10

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.

Sacculate answered 17/2, 2012 at 10:32 Comment(4)
I'm sorry for not providing the images but thank you so much for your help. I used the cvErode function which removed some of the holes in the image, but I will try median blur as well. When you mentioned using opening and closing, do I have to use them together or either do the CV_MOP_OPEN or CV_MOP_CLOSE?Marotta
You can still provide them :) You can use one of them or both, one after another, it depends on what you are trying to ahieve. Just check the results and experiment.Sacculate
I checked the results and decided that better results were obtained with both the Erode and Dilate functions so I'll use them, one after the other. In any case, I don't know how to provide the images as I am new to stackoverflow:/ I'm very sorry. I am currently working on an image processing project which involves C++ and openCV. It is based on motion recognition so if I post any more questions, I would greatly appreciate it if you could provide some assistance as you have been very helpful already. Thank you:)Marotta
Would you be able to up-vote my question so I can get more than a 10 reputation? I want to post images for this question #9373187 but that requires more than a 10 rep which is where I am currently at. It would be great if you can give some assistance with the question too :)Marotta
P
1

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

Pachalic answered 17/2, 2012 at 5:40 Comment(8)
Would that achieve the same result as the erode and dilate functions? Are you familiar with the use of those functions?Marotta
you can use opening and closing (erosion + dilation and vice versa), clearly you need to tune the kernel sizeHip
I can either use the opening or closing functions or do I have to use them together?Marotta
@user1204698, no it's not the same as the erode and dilate functions - it's another way of reducing noise that you can apply before the thresholding. It would be complimentary to erode and dilate, no reason you couldn't combine the approaches if that works best.Pachalic
@MarkRansom thanks so much for the help. I tried both the erode and dilate together and got a better result so I might stick to that approach then.Marotta
@Hip also, would you be able to help me out here? #9373187Marotta
well in my allpications I used both the operation, firt an opening followed by a closing. the kernel of the two function is the same. in this way you can eliminate (or strongly reduce) both the salt and pepper noise and the holes that are bigger than salt and pepper. as I said the size of the kenrel depends on the size of the noise blobs and the size of the object you are trackingHip
have a look to homepages.inf.ed.ac.uk/rbf/HIPR2/close.htm homepages.inf.ed.ac.uk/rbf/HIPR2/open.htmHip

© 2022 - 2024 — McMap. All rights reserved.