拆分OpenCV Mat而不复制数据
Split OpenCV Mat without copying the data
我有一个RGB图像,我试图对R通道进行一些修改。所以我做了类似于以下的事情:
Mat img;
vector<Mat> chs;
//....
split(img, chs);
//some modification on chs[2]
imshow("Result", img);
但OpenCV似乎是通过值(而不是通过引用)将数据复制到chs
。因此CCD_ 2矩阵没有改变但由于内存限制,我不喜欢使用merge
函数。
有没有其他选择可以将矩阵拆分到位?
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 <opencv2opencv.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 <opencv2opencv.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审阅答案
相关文章:
- 在 C++ AMP 数组中复制数据多少次?
- 字符串是否在其构造函数中复制数据
- 在不复制数据的情况下,将double数组转换为只有double成员的structs数组
- 有没有一种方法可以在不复制数据的情况下从string_view创建字符串流
- 如何在不复制数据的情况下将 cv::Mat 转换为 2d 标准::矢量
- C++ 在节点内存储对数据对象的引用,而不复制数据
- 是否可以在不分配内存或复制数据的情况下构造对象?
- 如何在不复制数据的情况下在平面数组和多维数组之间进行转换?
- C 2D char阵列有时会在随机位置复制数据
- 在不复制数据的情况下更改 opencv mat 中的列顺序
- 有没有办法将 EGL 绘制到 /dev/fb1 而不是 /dev/fb0,而无需在树莓派上复制数据
- 使用C 和目标C从原始图像中复制数据
- 给定 myvector.start() 和 myvector.end(),我想在不复制数据的情况下创建 myvector
- 复制数据时出现奇怪错误
- 如何在 C/C++ 中从数组末尾开始复制数据
- glTexImage2D 复制数据或仅指定数据
- 如何在C++中从void指针复制数据
- 在不复制数据的情况下将OpenCV Mat发送到MATLAB工作区的方法
- 如何使用 GPU-DMA 从 GPU-CUDA 代码来复制数据
- 在矢量到矢量中复制数据<float> <Mat> (Opencv/C++)