在matx脚本中将matlab图像传递给open3d 3 :: Image

时间:2018-06-28 12:33:55

标签: matlab pointers casting mex

我正在尝试在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 ++和指针的了解非常有限,所以我无法一目了然。

我也在这里(Reading image in matlab in a format acceptable to mex)找到了这个解决方案,但是我不确定如何使用它。老实说,我很困惑。

1 个答案:

答案 0 :(得分:0)

好的,解决方案很简单,就像我排在第一位一样。它只是在正确地使用指针:

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循环。