передать изображение matlab в open3d three :: изображение в мекс скрипте - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь загрузить изображение в mex-скрипте и привести его к соответствующему формату, который использует библиотека Open3D, т.е. three::Image. Я использую следующий код:

uint8_t* rgb_image = (uint8_t*) mxGetPr(prhs[3]);
int* dims = (int*) mxGetDimensions(prhs[3]);

int height = dims[0];
int width = dims[2];
int channels = dims[4];
int imsize = height * width;

Image image;
image.PrepareImage(height, width, 3, sizeof(uint8_t)); // parameters: height, width, num_of_channels, bytes_per_channel
memcpy(image.data_.data(), rgb_image, image.data_.size());

Вышеуказанное хорошо работает, когда я даю изображение в градациях серого и указываю num_of_channels на 1, но не для 3-канальных изображений, как вы можете заметить ниже:

enter image description here

Затем я попытался создать функцию, в которой я вручную перебираю необработанные данные и присваиваю их выходному изображению

    auto image_ptr = std::make_shared<Image>();
    image_ptr->PrepareImage(height, width, channels, sizeof(uint8_t));


    for (int i = 0; i < height * width; i++) {
        uint8_t *p = (uint8_t *)(image_ptr->data_.data() + i * channels * sizeof(uint8_t));
        *p++ = *rgb_image++;
    }

Но теперь кажется, что цветовые каналы назначены неправильно:

enter image description here

Есть идеи, как решить эту проблему. Дело в том, что это кажется чем-то простым, но поскольку мои знания по C ++ и указателям весьма ограничены, я не могу понять это прямо.

Я нашел это решение и здесь ( Чтение изображения в matlab в формате, приемлемом для mex ), но я не уверен, как именно я могу его использовать. Честно говоря, я в замешательстве.

1 Ответ

0 голосов
/ 06 июля 2018

хорошо, решение было довольно простым, хотя я был на первом месте. Он просто правильно играл с указателями:

std::shared_ptr<Image> CreateRGBImageFromMat(uint8_t *mat_image, int width, int height, int channels)
{
    auto open3d_image = std::make_shared<Image>();
    open3d_image->PrepareImage(height, width, channels, sizeof(uint8_t));

    for (int i = 0; i < height * width; i++) {
        uint8_t *p = (uint8_t *)(open3d_image->data_.data() + i * channels * sizeof(uint8_t));

        *p++ = *(mat_image + i);
        *p++ = *(mat_image + i + height*width);
        *p++ = *(mat_image + i + height*width*2);
    }
    return open3d_image;
}

, поскольку three::Image ожидает данные в непрерывном порядке row x col x channel, тогда как из matlab изображение поступает в блоках rows x cols x channel_1 (после транспонирования изображения, поскольку matlab является главным столбцом). Теперь мой вопрос заключается в том, могу ли я сделать то же самое с memcpy() или std::copy(), где я могу скопировать данные блока в непрерывную форму, чтобы обойти цикл for.

...