简体   繁体   中英

Opencv: Fill color in a contoured image

thanks for reading this in advance.

I'm doing a credit card OCR related project, one step of which requires filling colors to an already contoured image.

Sample images include:

My goal is to fill the white space black:

Although it seems straightforward, I have failed to find a satisfying solution.

I was trying out the findContours function, but I found it very confusing. After running the following function:

findContours( cvMatImage, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );

Strangely enough, not only the contour points were not correctly extracted, but also, the original input image seemed to have its own color inverted.

Any input regarding how I should complete my goal, or how to correctly use findContours function is greatly appreciated.

Update:

Thanks a lot for your kind input.

In fact, the image included in my question has already been binarized -- and also I have applied an "adaptive thresholding" procedure to the image.

The original image looks like: http://i.stack.imgur.com/DkIKt.png

CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
CGFloat cols = self.size.width;
CGFloat rows = self.size.height;

Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels

CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to  data
                                                cols,                       // Width of bitmap
                                                rows,                       // Height of bitmap
                                                8,                          // Bits per component
                                                cvMat.step[0],              // Bytes per row
                                                colorSpace,                 // Colorspace
                                                kCGImageAlphaNoneSkipLast |
                                                kCGBitmapByteOrderDefault); // Bitmap info flags
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);

Mat cvImage_gray, cvImage_threshold;

cvtColor(cvImageOrg, cvImage_gray, CV_RGB2GRAY); //Binarize

adaptiveThreshold(cvImage_gray, cvImage_threshold, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, neighbor, threshRed); //Adaptive threshold

You should binarise the image. findContours only works well when there is eg only black and white in the image.

So you should look at each pixel in the image and threshold. If it's below a certain value make it black, other wise make it white. To me the provided image looks like there are some grey pixels too.

Also you should know that find contours 'destroys' the provided image. It does not create a copy on it's own. So if you want to keep the original, you should pass in a copy.

After you found the contours you can use that information on the original image and change the color values of the pixels in the found areas.

Edit :

Okay after I read your update I would recommend the following:
Make the background, that is kind of blueish, to black.
For that you need to inspect each pixel and look at the color values.

If it has enough blue in it make it black.
Everything else you make white.

After that your background should be black and your numbers should be white. You could now do findContours, or if you just want the numbers to be black and the background to be white: invert the image or swap black and white in the binarizing process.

Important:
What you did with your image is actually not binarize it. You took the color out. Binarize means only TWO colors. A pixel will EITHER be black OR white. Not gray.
Your threshold is actually not thresholding because the value you took(255) is the maximum(because that is the highest number you can have with 8 bit). Thresholding works differently: for a binary threshold you have a value everything that is below or equal will be one color, everything that is above will be another. For 255 the whole image should turn to one color....
With thresholds you usualy play around a bit until they fit your needs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM