【问题标题】:Split OpenCV Mat without copying the data在不复制数据的情况下拆分 OpenCV Mat
【发布时间】:2017-11-08 16:13:41
【问题描述】:

我有一个 RGB 图像,我尝试对 R 通道进行一些修改。所以我做了类似的事情:

Mat img;
vector<Mat> chs;
//.... 
split(img, chs);
//some modification on chs[2]
imshow("Result", img);

但似乎 OpenCV 通过值(而不是通过引用)将数据复制到 chs。因此,img 矩阵没有改变。 但由于内存限制,我不喜欢使用merge 函数。

有没有其他方法可以就地拆分矩阵?

【问题讨论】:

  • split 复制数据,因为它正在创建新矩阵。我看不出你的记忆可以分裂但不能合并。但是,您可以直接在 R 通道上工作而无需拆分。这真的取决于你想做什么。

标签: c++ opencv


【解决方案1】:

split 将始终复制数据,因为它正在创建新矩阵。

处理红色通道的最简单方法是使用split 和merge:

Mat3b img(10,10,Vec3b(1,2,3));

vector<Mat1b> planes;
split(img, planes);

// Work on red plane
planes[2](2,3) = 5;

merge(planes, img);

请注意,merge 不会分配任何新内存,因此如果您对 split 没问题,那么没有任何理由不调用 merge。


您始终可以直接在 R 通道上工作:

Mat3b img(10,10,Vec3b(1,2,3));

// Work on red channel, [2]
img(2,3)[2] = 5;

如果要节省split使用的内存,可以直接在红色通道上工作,但是比较麻烦:

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

int main()
{
    Mat3b img(10,10,Vec3b(1,2,3));

    // Create a column matrix header with red plane unwound
    // No copies here
    Mat1b R = img.reshape(1, img.rows*img.cols).colRange(2, 3);

    // Work on red plane
    int r = 2;
    int c = 3;

    // You need to access by index, not by (row, col).
    // This will also modify img
    R(img.rows * r + c) = 5;

    return 0;
}

您可以通过仅将红色通道复制到新矩阵中来找到一个很好的折衷方案(避免也为其他通道分配空间),然后将结果复制回原始图像:

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

int main()
{
    Mat3b img(10,10,Vec3b(1,2,3));

    // Allocate space only for red channel
    Mat1b R(img.rows, img.cols);
    for (int r=0; r<img.rows; ++r)
        for(int c=0; c<img.cols; ++c)
            R(r, c) = img(r, c)[2];

    // Work on red plane
    R(2,3) = 5;

    // Copy back into img
    for (int r = 0; r<img.rows; ++r)
        for (int c = 0; c<img.cols; ++c)
            img(r, c)[2] = R(r,c);


    return 0;
}

感谢@sturkmen 审核答案

【讨论】:

  • 亲爱的@Miki,请根据“B G R order 中存储的频道”修改您的答案
  • @Miki,谢谢。我会按照您建议的解决方案工作。
  • @ma.mehralian 很高兴它有帮助。如果您发现此答案有用,请点赞,如果此答案回答了您的问题,请最终标记为答案。否则,请告诉我为什么这不能回答问题,以便我寻找更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2020-02-11
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多