【发布时间】:2011-07-14 20:13:03
【问题描述】:
我有一张具有 3 个通道 (img) 的图像和另一个具有单通道 (ch1) 的图像。
Mat img(5,5,CV_64FC3);
Mat ch1 (5,5,CV_64FC1);
有没有有效的方法(不使用for循环)将img的第一个通道复制到ch1?
【问题讨论】:
我有一张具有 3 个通道 (img) 的图像和另一个具有单通道 (ch1) 的图像。
Mat img(5,5,CV_64FC3);
Mat ch1 (5,5,CV_64FC1);
有没有有效的方法(不使用for循环)将img的第一个通道复制到ch1?
【问题讨论】:
其实,如果你只是想复制其中一个通道或者将彩色图像分割成3个不同的通道,CvSplit() 更合适(我的意思是简单易用)。
Mat img(5,5,CV_64FC3);
Mat ch1, ch2, ch3;
// "channels" is a vector of 3 Mat arrays:
vector<Mat> channels(3);
// split img:
split(img, channels);
// get the channels (dont forget they follow BGR order in OpenCV)
ch1 = channels[0];
ch2 = channels[1];
ch3 = channels[2];
【讨论】:
有一个函数叫做cvMixChannels。你需要在源代码中看到实现,但我敢打赌它已经优化好了。
【讨论】:
您可以使用拆分功能,然后将零添加到您要忽略的通道。这将导致显示三个频道中的一个。见下文..
例如:
Mat img, chans[3];
img = imread(.....); //make sure its loaded with an image
//split the channels in order to manipulate them
split(img, chans);
//by default opencv put channels in BGR order , so in your situation you want to copy the first channel which is blue. Set green and red channels elements to zero.
chans[1]=Mat::zeros(img.rows, img.cols, CV_8UC1); // green channel is set to 0
chans[2]=Mat::zeros(img.rows, img.cols, CV_8UC1);// red channel is set to 0
//then merge them back
merge(chans, 3, img);
//display
imshow("BLUE CHAN", img);
cvWaitKey();
【讨论】:
您可以访问特定频道,它比split操作更快
Mat img(5,5,CV_64FC3);
Mat ch1;
int channelIdx = 0;
extractChannel(img, ch1, channelIdx); // extract specific channel
// or extract them all
vector<Mat> channels(3);
split(img, channels);
cout << channels[0].size() << endl;
【讨论】:
如果你有一个 3 通道的 RGB,一个更简单的方法是 cvSplit(),如果我没记错的话,你需要配置的东西更少......(我认为它也得到了很好的优化)。
我会将 cvMixChannel() 用于“更难”的任务...:p(我知道我很懒)。
【讨论】: