【问题标题】:Access to each separate channel in OpenCV访问 OpenCV 中的每个单独通道
【发布时间】:2011-07-14 20:13:03
【问题描述】:

我有一张具有 3 个通道 (img) 的图像和另一个具有单通道 (ch1) 的图像。

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

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

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    其实,如果你只是想复制其中一个通道或者将彩色图像分割成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];
    

    【讨论】:

      【解决方案2】:

      有一个函数叫做cvMixChannels。你需要在源代码中看到实现,但我敢打赌它已经优化好了。

      【讨论】:

      • 谢谢雅克。看来,我可以使用 mixChannels 完成我的任务
      • 感谢您的回答。我尝试了 split 和 mixChannels。而且,他们抛出错误!你有什么想法,可能是什么原因?
      • 我的类型确实有误。我没有使用 CV_32FC1,而是使用了 CV_64FC1。感谢您的帮助
      • 尽可能使用 C++ API(C API 将很快被弃用):因此它是 cv::mixChannels,而不是 cvMixChannels。 cvSplit 也是如此,请改用 core.hpp 中的 cv::split。
      【解决方案3】:

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

      例如:

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

      【讨论】:

      • 这是一个更好的答案,并通过将互补函数 cv::merge() 也放入其中(尽管可能只是编辑其他答案会更好,但用户缺少代表点?)
      【解决方案4】:

      您可以访问特定频道,它比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;
      

      【讨论】:

        【解决方案5】:

        如果你有一个 3 通道的 RGB,一个更简单的方法是 cvSplit(),如果我没记错的话,你需要配置的东西更少......(我认为它也得到了很好的优化)。

        我会将 cvMixChannel() 用于“更难”的任务...:p(我知道我很懒)。

        here is the documentation for cvSplit()

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-13
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 2018-01-03
          • 2015-08-07
          • 2020-01-10
          • 1970-01-01
          相关资源
          最近更新 更多