Hi all,

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

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 close merge delete

Sort by » oldest newest most voted

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.

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

And here's the code:

Mat flower = imread("flower.png",-1);
Mat border, borderTemp;

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

//Handle the fuzzy alpha boundary.

for (int r = 0; r < largeFlower.rows; ++r)
{
Rect petal;
petal.y = r;
petal.height = 1;
for (int c = 0; c < largeFlower.cols; ++c)
{
if (largeFlower.at<Vec<uchar, 4> >(r, c)(3) == 0)
{
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();

more

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.

( 2016-03-16 18:21:22 -0500 )edit

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

( 2016-03-31 06:52:54 -0500 )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...

( 2016-04-06 11:25:59 -0500 )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

( 2016-04-07 01:33:55 -0500 )edit

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

( 2016-04-07 06:54:02 -0500 )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?

( 2016-04-08 02:26:21 -0500 )edit

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

( 2016-04-08 02:45:47 -0500 )edit

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

( 2016-04-08 06:50:52 -0500 )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.

( 2016-04-08 07:27:07 -0500 )edit