OpenCV отображает 2 изображения рядом в одном окне

Я пытаюсь отобразить 2 изображения, расположенные горизонтально рядом друг с другом в том же окне, используя OpenCV.

Я попытался использовать функцию adjustROI для этого. Ядро 1 имеет ширину 1088 пикселей и высоту 2208 пикселей, а изображение 2 имеет ширину 1280 пикселей и высоту 2208 пикселей. Пожалуйста, представьте, что может быть неправильным в коде ниже. Все, что я получаю, изображение размера Image2 с контентом из Image2.

Mat img_matches=Mat(2208,2368,imgorig.type());//set size as combination of img1 and img2
img_matches.adjustROI(0,0,0,-1280); 
imgorig.copyTo(img_matches);
img_matches.adjustROI(0,0,1088,1280);
imgorig2.copyTo(img_matches);

Ответ 1

РЕДАКТИРОВАТЬ: Вот как я буду делать то, что вы хотите сделать:

Mat left(img_matches, Rect(0, 0, 1088, 2208)); // Copy constructor
imgorig.copyTo(left);
Mat right(img_matches, Rect(1088, 0, 1280, 2208)); // Copy constructor
imgorig2.copyTo(right);

Конструкторы копирования создают копию заголовка Mat, который указывает на ROI, определенный каждым из Rect s.

Полный код:

#include <cv.h>
#include <highgui.h>

using namespace cv;

int
main(int argc, char **argv)
{
    Mat im1 = imread(argv[1]);
    Mat im2 = imread(argv[2]);
    Size sz1 = im1.size();
    Size sz2 = im2.size();
    Mat im3(sz1.height, sz1.width+sz2.width, CV_8UC3);
    Mat left(im3, Rect(0, 0, sz1.width, sz1.height));
    im1.copyTo(left);
    Mat right(im3, Rect(sz1.width, 0, sz2.width, sz2.height));
    im2.copyTo(right);
    imshow("im3", im3);
    waitKey(0);
    return 0;
}

Скомпилируется с помощью

g++ foo.cpp -o foo.out `pkg-config --cflags --libs opencv`

EDIT2:

Вот как это выглядит с помощью adjustROI:

#include <cv.h>
#include <highgui.h>

using namespace cv;

int
main(int argc, char **argv)
{
    Mat im1 = imread(argv[1]);
    Mat im2 = imread(argv[2]);
    Size sz1 = im1.size();
    Size sz2 = im2.size();
    Mat im3(sz1.height, sz1.width+sz2.width, CV_8UC3);
    // Move right boundary to the left.
    im3.adjustROI(0, 0, 0, -sz2.width);
    im1.copyTo(im3);
    // Move the left boundary to the right, right boundary to the right.
    im3.adjustROI(0, 0, -sz1.width, sz2.width);
    im2.copyTo(im3);
    // restore original ROI.
    im3.adjustROI(0, 0, sz1.width, 0);
    imshow("im3", im3);
    waitKey(0);
    return 0;
}

Вы должны отслеживать, что такое текущий ROI, и синтаксис для перемещения ROI вокруг может быть немного неинтуитивным. Результат такой же, как и первый блок кода.

Ответ 2

Поскольку высота (строки Mat) изображений одинакова, функция hconcat может использоваться для горизонтальной конкатенации двух изображений (Mat) и, следовательно, может использоваться для отображения их бок о бок в том же окне. документ OpenCV.
Он работает как с оттенками серого, так и с цветными изображениями.

Mat im1, im2;
// source images im1 and im2

Mat newImage;
hconcat(im1, im2, newImage);

imshow("Display side by side", newImage);
waitKey(0);

Для полноты, vconcat может использоваться для вертикальной конкатенации.

Ответ 3

Здесь решение, вдохновленное ответом @misha.

#include <cv.h>
#include <highgui.h>

using namespace cv;

int
main(int argc, char **argv)
{
    Mat im1 = imread(argv[1]);
    Mat im2 = imread(argv[2]);
    Size sz1 = im1.size();
    Size sz2 = im2.size();
    Mat im3(sz1.height, sz1.width+sz2.width, CV_8UC3);
    im1.copyTo(im3(Rect(0, 0, sz1.width, sz1.height)));
    im2.copyTo(im3(Rect(sz1.width, 0, sz2.width, sz2.height)));
    imshow("im3", im3);
    waitKey(0);
    return 0;
}

Вместо использования конструктора копирования это решение использует Mat:: operator() (const Rect & roi). Хотя оба решения O (1), это решение кажется более чистым.