Ask Your Question
1

Reconstruct stitched image

asked 2015-10-20 01:00:02 -0600

alexandra gravatar image

updated 2015-10-20 04:26:46 -0600

berak gravatar image

Hello,

I used OpencCV stitching class to stitch these images, but the result contain black area. I don't want to crop the image to remove the black area because some image details will be missed. Is there any way ( function or algorithm) to reconstruct the image so that the black area will be filled with appropriate pixels ??

image description

Regards,

edit retag flag offensive close merge delete

Comments

inpaint() might be helpful

berak gravatar imageberak ( 2015-10-20 01:41:23 -0600 )edit

Thanks, i will try it.

alexandra gravatar imagealexandra ( 2015-10-20 02:49:00 -0600 )edit

how can i paint just the black area around my image??

alexandra gravatar imagealexandra ( 2015-10-20 03:42:45 -0600 )edit

You do a mask of the black area (I suppose that everything is 0 there); see threshold, or maybe floodfill with seeds from the 4 corners of the stitched image

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-20 03:56:26 -0600 )edit

you mean the mask ?

Mat gray; cvtColor(img, gray, COLOR_BGR2GRAY);
// find black region:
Mat mask = (gray == 0); // mask is 'on', where gray is black
berak gravatar imageberak ( 2015-10-20 04:05:33 -0600 )edit

I test this example link text its work fine but i want it to paint the black area without using the white painting ??

alexandra gravatar imagealexandra ( 2015-10-20 04:29:14 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2015-10-20 04:22:59 -0600

berak gravatar image

updated 2015-10-20 04:26:29 -0600

i would try to use inpaint

( not on the whole image, but only the border regions ):

void doInpaint(Mat &img)
{
    // find black region:
    Mat gray; cvtColor(img,gray,COLOR_BGR2GRAY);
    Mat mask = gray == 0;

    // pre-fill  black areas with mean color,
    // for easier interpolation
    Scalar m,s;
    cv::meanStdDev(img, m, s, ~mask); // inverted mask !
    img.setTo(m, mask);

    inpaint(img,mask,img,30,INPAINT_TELEA);
}

void main()
{
    int S = 30;
    Mat img = imread("stich_inp.png");
    // top
    doInpaint(img(Rect(0,0,img.cols,S)));
    // bottom
    doInpaint(img(Rect(0,img.rows-S,img.cols,S)));
    // left
    doInpaint(img(Rect(0,0,S,img.rows)));
    // right
    doInpaint(img(Rect(img.cols-S,0,S,img.rows)));
    //
    imshow("final", img);
    imwrite("final.png", img);
    waitKey();
}

image description

edit flag offensive delete link more

Comments

@berak You can also create the mask based on the channel 0, no? But the result is ugly... isn't it better to cut the black part so you'll have a little smaller image?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-20 05:06:39 -0600 )edit

@thdrksdfthmn ,

  • "You can also create the mask based on the channel 0" - that would only give you "not blue" , imho better from grayscale.

  • "isn't it better to cut the black part so you'll have a little smaller image" - that would have been my 1st idea, too, but she kinda wanted to avoid that explicitly, no ?

berak gravatar imageberak ( 2015-10-20 05:18:38 -0600 )edit

@berak thank you so much, but when i tested on another image the result is not good, there is a big different in color and its not the same as the example in the link i mentioned above. Why you are using s=30 ??

alexandra gravatar imagealexandra ( 2015-10-20 05:50:23 -0600 )edit
1
  • "Why you are using s=30 " S=30 -> size of the border strip to process (you don't want to inpaint the whole image, just the top/bottom/left/right strip)

  • "i tested on another image the result is not good," - ah, shame. maybe add that to your question ?

berak gravatar imageberak ( 2015-10-20 06:08:47 -0600 )edit

mask is 1-channel 8-bit, while src is 1 or 3 channels, so I suppose it is doing the inpainting on all the channels...

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-10-20 06:16:37 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-10-20 01:00:02 -0600

Seen: 1,147 times

Last updated: Oct 20 '15