如何将图像存储顺序从channel-height-width转换为height-width-channel?

时间:2018-12-29 23:37:16

标签: c++ image opencv vector computer-vision

我想知道如何在C ++中将以1D std::vector<float>格式存储的图像从CHW格式(通道,高度,宽度)转换为HWC格式(高度,宽度,通道)。由于神经网络的要求,需要更改格式。

我使用OpenCV读取并显示以下图像:

cv::namedWindow("Screenshot", cv::WINDOW_AUTOSIZE );
cv::imshow("Screenshot", rgbImage);

然后我将cv::Mat rgbImage转换为CHW格式的一维std::vector<float>

size_t channels = 3;
std::vector<float> data(channels*ROS_IMAGE_HEIGHT*ROS_IMAGE_WIDTH);
for(size_t j=0; j<ROS_IMAGE_HEIGHT; j++){
    for(size_t k=0; k<ROS_IMAGE_WIDTH; k++){
        cv::Vec3b intensity = rgbImage.at<cv::Vec3b>(j, k);
        for(size_t i=0; i<channels; i++){
            data[i*ROS_IMAGE_HEIGHT*ROS_IMAGE_WIDTH + j*ROS_IMAGE_HEIGHT + k] = (float) intensity[i];
        }
    }
}

现在,我想将std::vector<float>数据的格式转换为HWC。我该怎么办?

1 个答案:

答案 0 :(得分:1)

我发现了对“ CHW”和“ HWC”格式here的一些描述。

如果存储顺序为HWC,则表示

  

每个样本都存储为(height, width) float[numChannels]的列主矩阵(r00, g00, b00, r10, g10, b10, r01, g01, b01, r11, g11, b11)

因此使用可以找到像素(x, y, c)

xStride = channels;
yStride = channels * width;
cStride = 1;

data[x*xStride + y*yStride + c*cStride]

如果存储顺序为CHW,则意味着每个通道都是一个不同的平面。使用

找到了像素(x, y, c)
xStride = 1;
yStride = width;
cStride = width * height;

data[x*xStride + y*yStride + c*cStride]

请注意,在问题代码中,data[i*ROS_IMAGE_HEIGHT*ROS_IMAGE_WIDTH + j*ROS_IMAGE_HEIGHT + k]不正确,j是y坐标,应乘以ROS_IMAGE_WIDTH

通过将最内层循环中的行替换为:

,可以修改问题中的代码以产生HWC格式的std::vector
data[i + j*ROS_IMAGE_WIDTH*channels + k*channels] = (float) intensity[i];