【问题标题】:OpenCV displaying 2 images adjacently in the same windowOpenCV 在同一窗口中相邻显示 2 个图像
【发布时间】:2012-10-30 05:16:56
【问题描述】:

我正在尝试使用 OpenCV 在同一窗口中显示 2 个水平相邻的图像。

我已经尝试为此使用 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);

【问题讨论】:

    标签: image-processing opencv roi


    【解决方案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 标头的副本,该标头指向每个Rects 定义的ROI。

    完整代码:

    #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 的语法可能有点不直观。结果和第一段代码一样。

    【讨论】:

    • 这也不起作用。我认为前两个参数在两种情况下都需要为零,因为两个图像的高度(几乎)相同,我只需要将它们并排放置。
    • 我刚刚意识到 adjustROI 的行为与我习惯的行为略有不同(旧的 C cvSetImageROI)。查看我的更新答案。
    • 我尝试过类似的方法。复制构造函数给出了原始矩阵的副本,所以当我尝试打印“img_matches”时,它仍然是空白的。分别打印“左”和“右”给出那些图像
    • 构造函数复制矩阵的头部,而不是底层数据。基础数据仍与原始图像共享。因此,当您向左/向右复制时,您实际上是在复制到原始图像。我刚刚尝试过——它有效。有关完整代码,请参阅我的更新答案。
    • 我很无聊,尝试使用adjustROI。看着你的问题,你非常接近自己找到解决方案。您唯一做错的事情就是忘记重置 ROI。
    【解决方案2】:

    由于图像的高度(Mat 的行)相同,函数hconcat 可用于水平连接两个图像(Mat),因此可用于在同一窗口中并排显示它们。 OpenCV doc.
    它适用于灰度和彩色图像。源矩阵中的颜色通道数必须相同。

    Mat im1, im2; // source images im1 and im2
    
    Mat newImage;
    hconcat(im1, im2, newImage);  // <---- place image side by side
    
    imshow("Display side by side", newImage);
    waitKey(0);
    

    为了完整起见,vconcat 可以类似地用于垂直串联。

    【讨论】:

    • 使用 hconcat 的垫子需要具有相同的尺寸
    • @BossShell 通过尺寸,如果您指的是颜色通道(不是矩阵的尺寸),那么是的,它们需要相同(将更新答案)。明确地说:对于hconcat,源垫的列可以不同。
    【解决方案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),但这个解决方案看起来更干净。

    【讨论】:

      猜你喜欢
      • 2011-07-02
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      相关资源
      最近更新 更多