需要将一个图像复制到另一个图像ROI

时间:2015-09-20 13:53:54

标签: c++ opencv image-processing

我正在尝试将一个图像层复制到另一个图像ROI。我的代码如下。

Mat4b src= imread("path");
Mat3b dest = imread("path");
Rect roi = Rect(179,539,src.cols,src.rows); //src.cols = 1186 and src.rows= 1134 after scaling.
Mat destinationROI = dest(roi);
src.copyTo(destinationROI);
imwrite("destinationROI.png", destinationROI);

输入src为enter image description here 输入目标为enter image description here

但输出得到的是相同的目标图像。 然后我试图保存目标ROI befre复制。我得到的输出是enter image description here这是正确的。复制src也有效。但它对dest图像没有任何影响。

2 个答案:

答案 0 :(得分:5)

这是为了确认@ypnos 有根据的猜测是对的(很好的电话,顺便说一句)。

查看此代码,执行与您相同的操作:

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;


int main()
{
    Mat4b m4b(50, 50, Vec4b(0, 255, 0, 255));   // blue image, 4 channels
    Mat3b m3b(100, 100, Vec3b(255, 0, 0));      // green image, 3 channels

    cout << "After init:" << endl;
    cout << "m4b channels: " << m4b.channels() << endl;
    cout << "m3b channels: " << m3b.channels() << endl << endl;

    Rect roi(0, 0, 50, 50); // roi

    // Create a new header for the data inside the roi in m3b
    // No data copied, just a new header.
    // So destRoi has same number of channels of m3b
    Mat destRoi = m3b(roi); 


    cout << "After roi:" << endl;
    cout << "m4b channels    : " << m4b.channels() << endl;
    cout << "m3b channels    : " << m3b.channels() << endl;
    cout << "destRoi channels: " << destRoi.channels() << endl << endl;

    // destination type != source type
    // destRoi is newly created with the destination type
    // destRoi doesn't point anymore to the data in m3b and has 4 channels now
    m4b.copyTo(destRoi);

    cout << "After copyTo:" << endl;
    cout << "m4b channels    : " << m4b.channels() << endl;
    cout << "m3b channels    : " << m3b.channels() << endl;
    cout << "destRoi channels: " << destRoi.channels() << endl << endl;

    return 0;
}

输出:

After init:
m4b channels: 4
m3b channels: 3

After roi:
m4b channels    : 4
m3b channels    : 3
destRoi channels: 3

After copyTo:
m4b channels    : 4
m3b channels    : 3
destRoi channels: 4

<强>解决方案

使用具有相同通道数的两个矩阵,可以通过:

  1. 将两个图像加载为3个通道矩阵CV_8UC3实际上,您发布的图片均为3个频道

  2. 在执行漫游和复制操作之前,使用cvtColor转换为相同数量的频道。

答案 1 :(得分:3)

您的矩阵类型不匹配。一个有四个通道,另一个有三个通道。 显然,将4通道矩阵的内容复制到3通道矩阵中是行不通的。

不幸的是,在某些情况下,当OpenCV无法在旧内存上运行时,它会无声地回退到创建一个新矩阵。最有可能的是,这就是这种情况。执行复制后,destinationROI开始指向新内存。

请注意,您可以通过将destinationROI声明为Mat3b来阻止此行为。但是,为了使您的代码正常工作,源和目标都需要携带相同数量的通道。

我在这里做出的两个假设都只是有根据的猜测,但我没有测试有问题的代码。