Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

placing two images side by side, opencv 2.3, c++

Tags:

opencv

I #m reading two images and want to get third one which is just combination of two. img_object and img_scene don't have same size.

    int main( int argc, char** argv )
        Mat combine;

        Mat img_object = imread( object_filename, CV_LOAD_IMAGE_GRAYSCALE );
        Mat img_scene = imread(  scene_filename , CV_LOAD_IMAGE_GRAYSCALE );
    if( !img_object.data || !img_scene.data )
      { std::cout<< " --(!) Error reading images " << std::endl; return -1; }


       namedWindow( "Display window oject", 0 );// Create a window for display.


       namedWindow( "Display window scene ", 0 );


       namedWindow( "Display window combine ", 0 );

       imshow( "Display window oject", img_object );
       imshow( "Display window scene", img_scene );   
       imshow( "Display window scene", combine );   
 waitKey(0);
  return 0;
  }
like image 930
Shahgee Avatar asked Aug 04 '13 15:08

Shahgee


3 Answers

There is a very simple way of displaying two images side by side. The following function can be used which is provided by opencv.

Mat image1, image2;
hconcat(image1,image2,image1);//Syntax-> hconcat(source1,source2,destination);

This function can also be used to copy a set of columns from an image to another image.

Mat image;
Mat columns=image.colRange(20,30);
hconcat(image,columns,image);
like image 161
Raj Kumar Mishra Avatar answered Sep 30 '22 02:09

Raj Kumar Mishra


// --------------------------------------------------------------
// Function to draw several images to one image.
// Small images draws into cells of size cellSize.
// If image larger than size of cell ot will be trimmed.
// If image smaller than cellSize there will be gap between cells.
// --------------------------------------------------------------
char showImages(string title, vector<Mat>& imgs, Size cellSize) 
{
char k=0;
    namedWindow(title);
    float nImgs=imgs.size();
    int   imgsInRow=ceil(sqrt(nImgs));     // You can set this explicitly
    int   imgsInCol=ceil(nImgs/imgsInRow); // You can set this explicitly

    int resultImgW=cellSize.width*imgsInRow;
    int resultImgH=cellSize.height*imgsInCol;

    Mat resultImg=Mat::zeros(resultImgH,resultImgW,CV_8UC3);
    int ind=0;
    Mat tmp;
    for(int i=0;i<imgsInCol;i++)
    {
        for(int j=0;j<imgsInRow;j++)
        {
            if(ind<imgs.size())
            {
            int cell_row=i*cellSize.height;
            int cell_col=j*cellSize.width;
            imgs[ind].copyTo(resultImg(Range(cell_row,cell_row+tmp.rows),Range(cell_col,cell_col+tmp.cols)));
            }
            ind++;
        }
    }
    imshow(title,resultImg);
    k=waitKey(10);
    return k;
}
like image 30
Andrey Smorodov Avatar answered Sep 30 '22 02:09

Andrey Smorodov


If the images are not the same size, combine's width will be equal to the sum of the widths, but the height must be the bigger of the heights of the two images.

Define the combination image like this:

Mat combine(max(img_object.size().height, img_scene.size().height), img_object.size().width + img_scene.size().width, CV_8UC3);

Note that we're just creating a new Mat object with height equal to the maximum height and width equal to the combined width of the pictures (if you need a small margin between the pictures, you need to account for that here).

Then, you can define regions of interest for each side inside combine (using a convenient Matconstructor), and finally copy each image to the corresponding side (here I assume the object goes on the left and the scene goes on the right):

Mat left_roi(combine, Rect(0, 0, img_object.size().width, img_object.size().height));
img_object.copyTo(left_roi);
Mat right_roi(combine, Rect(img_object.size().width, 0, img_scene.size().width, img_scene.size().height));
img_scene.copyTo(right_roi);

Edit: Fixed the typo that TimZaman pointed out.

like image 43
Daniel Martín Avatar answered Sep 30 '22 04:09

Daniel Martín