2

Let me start by saying that I'm still a beginner using OpenCV. Some things might seem obvious and once I learn them hopefully they also become obvious to me.

My goal is to use the floodFill feature to generate a separate image containing only the filled area. I have looked into this post but I'm a bit lost on how to convert the filled mask into an actual BGRA image with the filled color. Besides that I also need to crop the newly filled image to contain only the filled area. I'm guessing OpenCV has some magical function that could do the trick.

Here is what I'm trying to achieve:
Original image:
enter image description here

Filled image:
enter image description here

Filled area only:
enter image description here

UPDATE 07/07/13
Was able to do a fill on a separate image using the following code. However, I still need to figure out the best approach to get only the filled area. Also, my floodfill solution has an issue with filling an image that contains alpha values...

static int floodFillImage (cv::Mat &image, int premultiplied, int x, int y, int color)
{
    cv::Mat out;

    // un-multiply color
    unmultiplyRGBA2BGRA(image);

    // convert to no alpha
    cv::cvtColor(image, out, CV_BGRA2BGR);

    // create our mask
    cv::Mat mask = cv::Mat::zeros(image.rows + 2, image.cols + 2, CV_8U);

    // floodfill the mask
    cv::floodFill(
            out,
            mask,
            cv::Point(x,y),
            255,
            0,
            cv::Scalar(),
            cv::Scalar(),
            + (255 << 8) + cv::FLOODFILL_MASK_ONLY);

    // set new image color
    cv::Mat newImage(image.size(), image.type());
    cv::Mat maskedImage(image.size(), image.type());

    // set the solid color we will mask out of
    newImage = cv::Scalar(ARGB_BLUE(color), ARGB_GREEN(color), ARGB_RED(color), ARGB_ALPHA(color));

    // crop the 2 extra pixels w and h that were given before
    cv::Mat maskROI = mask(cv::Rect(1,1,image.cols,image.rows));

    // mask the solid color we want into new image
    newImage.copyTo(maskedImage, maskROI);

    // pre multiply the colors
    premultiplyBGRA2RGBA(maskedImage, image);

    return 0;
}
Community
  • 1
  • 1
Jona
  • 13,325
  • 15
  • 86
  • 129
  • 1
    I am not sure what you are asking, that link sticks it into a cv::mat which will be the RGB values. Do you know how image matrices are constructed? [This link](http://stackoverflow.com/questions/8006706/opencv-resizing-and-cropping-image-according-to-pixel-value) shows how to crop for a particular pixel value e.g. a certain colour – GPPK Jul 05 '13 at 17:02
  • Thanks for your post. I have updated the question. I was so tired when I wrote it :/ too bad for the down votes... :( Anyways I'll look in that post and see what they are using. – Jona Jul 06 '13 at 03:34

1 Answers1

0

you can get the difference of those two images to get the different pixels.

pixels with no difference will be zero and other are positive value.

cv::Mat A, B, C;
A = getImageA();
B = getImageB();

C = A - B;

handle negative values in the case.(i presume not in your case)

morteza kavakebi
  • 1,640
  • 3
  • 18
  • 39