iampat
iampat

Reputation: 1101

Access to each separate channel in OpenCV

I have an image with 3 channels (img) and another one with a single channel (ch1).

    Mat img(5,5,CV_64FC3);
    Mat ch1 (5,5,CV_64FC1);

Is there any efficient way (not using for loop) to copy the first channel of img to ch1?

Upvotes: 34

Views: 84910

Answers (5)

Gralex
Gralex

Reputation: 4485

You can access a specific channel, it works faster than the split operation

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;

Upvotes: 14

techguy18985
techguy18985

Reputation: 474

You can use split function and then put zeros to the channels u want to ignore. This will result dispalying one channels out of three. See below..

For example:

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();

Upvotes: 16

orielfrigo
orielfrigo

Reputation: 571

In fact, if you just want to copy one of the channels or split the color image in 3 different channels, CvSplit() is more appropriate (I mean simple to use).

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];

Upvotes: 57

Jacek
Jacek

Reputation: 1914

There is a function called cvMixChannels. You'll need to see implementation in the source code, but I bet it is well optimized.

Upvotes: 15

jmartel
jmartel

Reputation: 2781

A simpler one if you have a RGB with 3 channels is cvSplit() if i'm not wrong, you have less to configure... (and i think it is also well optimized).

I would use cvMixChannel() for "harder" tasks... :p (i know i am lazy).

here is the documentation for cvSplit()

Upvotes: 2

Related Questions