Как преобразовать порядок хранения изображений из channel-height-width в height-width-channel? - PullRequest
0 голосов
/ 30 декабря 2018

Я хотел бы знать, как преобразовать изображение, сохраненное в формате 1D std::vector<float>, из формата CHW (канал, высота, ширина) в формат HWC (высота, ширина, канал) в C ++.Изменение формата необходимо из-за требований нейронной сети.

Я использовал OpenCV для чтения и показа изображения, как показано ниже:

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

Затем я преобразовал cv::Mat rgbImageв 1D std::vector<float> в формате CHW:

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 голосов
/ 30 декабря 2018

Я нашел некоторое описание форматов "CHW" и "HWC" здесь .

Если порядок хранения 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.

Код в вопросе можно изменить, чтобы получить std::vector в формате HWC, заменив строку в самом внутреннем цикле:

data[i + j*ROS_IMAGE_WIDTH*channels + k*channels] = (float) intensity[i];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...