Ask Your Question
2

Add padding to object in 4-channel image

asked 2016-03-16 13:10:54 -0600

Finfa811 gravatar image

updated 2016-04-06 05:13:19 -0600

Hi all,

I have a 4-channel image (.png, .tif) like this one:

image description

And I would like to add padding of type BORDER_REFLECT around the flower. copyMakeBorder is not useful, since it adds padding to the edges of the image.

I can add certain padding if I split the image in bgr + alpha and apply dilate with BORDER_REFLECT option on the bgr image, but that solution spoils all the pixels of the flower.

Is there any way to perform a selective BORDER_REFLECT padding addition on a ROI defined by a binary mask?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
5

answered 2016-03-16 17:42:34 -0600

Tetragramm gravatar image

updated 2016-04-08 15:31:52 -0600

The closest I think you can do is the inpainting algorithms. They are in two places, photo and xphoto.

You would need to set the mask with non-zero pixels where it needs to be in-painted. I would suggest a width of twice what you need padded so when the white is inpainted too.

Alternatively, try doing the dilate again, but copy the original ROI into the dialated image. The copyTo function allows a mask parameter, so that's easy. The only changes would be where the dilation expanded outward.

Edit: So, out of curiosity, if this isn't what you wanted, then what is? Can you describe what's wrong? This is the dilate with copy on a 30x30 kernel.

image description

Edit2: I had an idea. How to actually accomplish this. Here's the picture:

image description

And here's the code:

Mat flower = imread("flower.png",-1);
Mat border, borderTemp;
Mat largeMask, largeFlower, largeBorder;
int padding = 30;

Mat mask;

linearPolar(flower, largeFlower, Point2f(flower.cols / 2.0, flower.rows / 2.0), 200, INTER_CUBIC);

//Handle the fuzzy alpha boundary.
extractChannel(largeFlower, largeMask, 3);
erode(largeMask, largeMask, Mat());
insertChannel(largeMask, largeFlower, 3);

for (int r = 0; r < largeFlower.rows; ++r)
{
    Rect petal;
    petal.y = r;
    petal.height = 1;
    petal.width = padding;
    for (int c = 0; c < largeFlower.cols; ++c)
    {
        if (largeFlower.at<Vec<uchar, 4> >(r, c)(3) == 0)
        {
            petal.x = c - padding-1;
            if (petal.x < 0)
            {
                int diff = 0 - petal.x;
                petal.x = 0;
                petal.width -= diff;
            }
            break;
        }
    }
    largeFlower(petal).copyTo(borderTemp);
    copyMakeBorder(borderTemp, border, 0, 0, 0, padding, BORDER_REFLECT);
    petal.width = border.cols;
    border.copyTo(largeFlower(petal));
}
linearPolar(largeFlower, border, Point2f(flower.cols / 2.0, flower.rows / 2.0), 200.0, INTER_CUBIC + WARP_INVERSE_MAP);

imshow("flower", flower);
imshow("border", border);
imshow("Polar", largeFlower);
imwrite("border_mirror.png", border);
waitKey();
edit flag offensive delete link more

Comments

First solution is the one that I've been using so far. Not the expected result but better than nothing...

Second solution looks tricky but it may work. I'll give it a try asap and let you know.

Thanks for your answer.

Finfa811 gravatar imageFinfa811 ( 2016-03-16 18:21:22 -0600 )edit

None of them work as expected, however, it'll do the work. Thanks

Finfa811 gravatar imageFinfa811 ( 2016-03-31 06:52:54 -0600 )edit

Edit: That result is the one that I was working with. The problem is since dilate is causing bright regions to grow, the padding contains higher rgb values than expected. The thing is appending a padding coposed by mirrored pixels from the flower, but this I guess it's not possible at all...

Finfa811 gravatar imageFinfa811 ( 2016-04-06 11:25:59 -0600 )edit

Edit2: Wow, that's exactly what I want! If we could just make smoother the transition between flower and padding, (removing the sharp white edge) that would be perfect. I guess that is due to the copyTo step. Maybe a blurring could help... Anyway I'm going to try your code and let's see how it behaves. Thanks

Finfa811 gravatar imageFinfa811 ( 2016-04-07 01:33:55 -0600 )edit

I think it's actually the alpha channel. Maybe try dilating it before doing anything else..

Tetragramm gravatar imageTetragramm ( 2016-04-07 06:54:02 -0600 )edit

I fixed the edge issue, however, the final image is a bit distorted due to the mapping between spaces. Do you know how to fix it?

Finfa811 gravatar imageFinfa811 ( 2016-04-08 02:26:21 -0600 )edit

A copyTo of flower onto border is the solution that I'm using, but then the sharp edge is coming back...

Finfa811 gravatar imageFinfa811 ( 2016-04-08 02:45:47 -0600 )edit

Try doing a threshold on whatever mask you're using for the final copy, and maybe eroding it by one or two pixels.

Tetragramm gravatar imageTetragramm ( 2016-04-08 06:50:52 -0600 )edit

Eroding the original mask of the flower with a standard 3x3 kernel provides a good result. It would be very nice (when you have time) if you could update the answer, I can't do it due to low karma :(. It was kind of challenging, but that idea of mapping to polar space and adding pixels in horizontal direction using the alpha channel was very clever. Thank you very much for your help.

Finfa811 gravatar imageFinfa811 ( 2016-04-08 07:27:07 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-03-16 13:10:54 -0600

Seen: 2,969 times

Last updated: Apr 08 '16