J'ai une image avec 3 canaux (img) et une autre avec un seul canal (ch1).
Mat img(5,5,CV_64FC3);
Mat ch1 (5,5,CV_64FC1);
Existe-t-il un moyen efficace (sans utiliser de boucle) de copier le premier canal de img vers ch1?
Il existe une fonction appelée cvMixChannels . Vous aurez besoin de voir l'implémentation dans le code source, mais je parie qu'elle est bien optimisée.
En fait, si vous voulez simplement copier l'un des canaux ou diviser l'image couleur en 3 canaux différents, CvSplit()
est plus approprié (je veux dire simple à utiliser).
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];
Vous pouvez utiliser la fonction de partage, puis mettre des zéros sur les canaux que vous souhaitez ignorer. Il en résultera la diffusion d'un canal sur trois. Voir ci-dessous..
Par exemple:
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();
Un plus simple si vous avez un RVB à 3 canaux est cvSplit () si je ne me trompe pas, vous avez moins à configurer ... (et je pense qu'il est également bien optimisé).
J'utiliserais cvMixChannel () pour des tâches "plus dures" ...: p (je sais que je suis paresseux).
Vous pouvez accéder à un canal spécifique, cela fonctionne plus rapidement que l'opération 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;