访问OpenCV中的每个单独通道

iam*_*pat 23 c++ opencv

我有一个带有3个通道(img)的图像和另一个带有单个通道(ch1)的图像.

    Mat img(5,5,CV_64FC3);
    Mat ch1 (5,5,CV_64FC1);
Run Code Online (Sandbox Code Playgroud)

是否有任何有效的方法(不使用for循环)将img的第一个通道复制到ch1

小智 50

事实上,如果您只是想复制其中一个通道或将彩色图像分成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];
Run Code Online (Sandbox Code Playgroud)


Jac*_*cek 12

有一个名为cvMixChannels的函数.您需要在源代码中看到实现,但我敢打赌它已经过优化.


tec*_*985 11

您可以使用拆分功能,然后将零添加到您想要忽略的通道.这将导致三个中的一个频道失望.见下文..

例如:

Mat img,chans[3]; 
img = imread(.....);  //make sure its loaded with an image

//split the channels in order to manipulate them
split(img,channel);

//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();
Run Code Online (Sandbox Code Playgroud)

  • 这是一个更好的答案,并通过将补充函数cv :: merge()放入其中来改进最多投票的答案(这不是可接受的答案)(尽管可能只是编辑其他答案会更好,但是用户缺少代表点?) (4认同)

Gra*_*lex 7

您可以访问特定频道,它比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;
Run Code Online (Sandbox Code Playgroud)