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;
}
謝謝 to @sturkmen審查答案
'split'拷貝數據,因爲它正在創建新的矩陣。我沒有看到你的記憶如何分裂而不是合併。但是,您可以直接在R通道上工作而不會分裂。這真的取決於你想要做什麼。 – Miki