c++opencvcudnn

OpenCV Image Mat to 1D CHW(RR...R, GG..G, BB..B) vector


Nvidia's cuDNN for deep learning has a rather interesting format for images called CHW. I have a cv::Mat img; that I want to convert to a one-dimensional vector of floats. The problem that I'm having is that the format of the 1D vector for CHW is (RR...R, GG..G,BB..B).

So I'm curious as to how I can extract the channel values for each pixel and order them for this format.


Solution

  • You can either iterate over the image manually and copy the values into the right place, or you can use something like cv::extractChannel to copy the channels one by one like so:

    #include <opencv2/opencv.hpp>
    
    int main()
    {
        //create dummy 3 channel float image
        cv::Mat sourceRGB(cv::Size(100,100),CV_32FC3);
        auto size = sourceRGB.size();
        for (int y = 0; y < size.height; ++y)
        {
            for (int x = 0; x < size.width; ++x)
            {
                float* pxl = sourceRGB.ptr<float>(x, y);
                *pxl = x / 100.0f;
                *(pxl+1) = y / 100.0f;
                *(pxl + 2) = (y / 100.0f) * (x / 100.0f);
            }
        }
    
        cv::imshow("test", sourceRGB);
        cv::waitKey(0);
    
        //create single image with all 3 channels one after the other
        cv::Size newsize(size.width,size.height*3);
        cv::Mat destination(newsize,CV_32FC1);
    
        //copy the channels from the source image to the destination
        for (int i = 0; i < sourceRGB.channels(); ++i)
        {
            cv::extractChannel(
                sourceRGB,
                cv::Mat(
                    size.height,
                    size.width,
                    CV_32FC1,
                    &(destination.at<float>(size.height*size.width*i))),
                i);
        }
    
        cv::imshow("test", destination);
        cv::waitKey(0);
        return 0;
    }