Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCV图像垫到1D CHW(RR…R,GG…G,BB…B)向量_C++_Opencv_Cudnn - Fatal编程技术网

C++ OpenCV图像垫到1D CHW(RR…R,GG…G,BB…B)向量

C++ OpenCV图像垫到1D CHW(RR…R,GG…G,BB…B)向量,c++,opencv,cudnn,C++,Opencv,Cudnn,Nvidia的cuDNN for deep learning有一种相当有趣的图像格式,称为CHW。我有一份简历::Mat img;我想把它转换成一维的浮点向量。我遇到的问题是CHW的一维向量的格式是(RR…R,GG..G,BB..B) 因此,我很好奇如何提取每个像素的通道值并按此格式排序。您可以手动迭代图像并将值复制到正确的位置,也可以使用类似于cv::extractChannel的方法逐个复制通道,如下所示: #include <opencv2/opencv.hpp> int m

Nvidia的cuDNN for deep learning有一种相当有趣的图像格式,称为CHW。我有一份简历::Mat img;我想把它转换成一维的浮点向量。我遇到的问题是CHW的一维向量的格式是(RR…R,GG..G,BB..B)


因此,我很好奇如何提取每个像素的通道值并按此格式排序。

您可以手动迭代图像并将值复制到正确的位置,也可以使用类似于
cv::extractChannel
的方法逐个复制通道,如下所示:

#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;
}
#包括
int main()
{
//创建虚拟3通道浮点图像
cv::Mat sourceRGB(cv::Size(100100),cv_32FC3);
自动大小=sourceRGB.size();
对于(int y=0;y
使用

cv::Mat bgr_image=cv::imread(imageFileName);
cv::Mat chw_image=cv::dnn::blobFromImage
(
bgr_图像,1.0,//比例因子
cv::Size(),//输出图像的空间大小
cv::Scalar(),//平均值
true,//swapRB:BGR到RGB
false,//裁剪
CV_32F//输出水滴的深度。选择CV_32F或CV_8U。
);
常量浮点*数据=重新解释强制转换(chw_image.data);
int data_length=1*3*bgr_image.rows*bgr_image.cols;

我遇到了同样的问题,并以这种方式解决了它:

#include <opencv2/opencv.hpp>

cv::Mat hwc2chw(const cv::Mat &image){
    std::vector<cv::Mat> rgb_images;
    cv::split(image, rgb_images);

    // Stretch one-channel images to vector
    cv::Mat m_flat_r = rgb_images[0].reshape(1,1);
    cv::Mat m_flat_g = rgb_images[1].reshape(1,1);
    cv::Mat m_flat_b = rgb_images[2].reshape(1,1);

    // Now we can rearrange channels if need
    cv::Mat matArray[] = { m_flat_r, m_flat_g, m_flat_b};
    
    cv::Mat flat_image;
    // Concatenate three vectors to one
    cv::hconcat( matArray, 3, flat_image );
    return flat_image;
}
#包括
cv::Mat hwc2chw(常数cv::Mat和图像){
std::矢量rgb_图像;
cv::分割(图像、rgb_图像);
//将单通道图像拉伸为矢量
cv::Mat m_flat_r=rgb_图像[0]。重塑(1,1);
cv::Mat m_flat_g=rgb_图像[1]。重塑(1,1);
cv::Mat m_flat_b=rgb_图像[2]。重塑(1,1);
//现在,如果需要,我们可以重新安排频道
matArray[]={m_flat_r,m_flat_g,m_flat_b};
cv::Mat flat_图像;
//将三个向量连接为一个向量
cv::hconcat(matArray,3,平面图像);
返回平面图像;
}

注意:如果输入图像不是RGB格式,您可以在matArray创建行中更改通道顺序。

使用cv::split并将单个通道复制到单个内存空间是否可行?但可能有一个更简单的方法