我正在尝试在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通道图像时,上面的方法效果很好,如下所示:
然后我尝试创建一个函数,在其中我手动遍历原始数据并将其分配给输出图像
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++;
}
但是现在看来颜色通道分配有误:
任何想法如何解决此问题。关键是似乎很容易,但是由于我对C ++和指针的了解非常有限,所以我无法一目了然。
我也在这里(Reading image in matlab in a format acceptable to mex)找到了这个解决方案,但是我不确定如何使用它。老实说,我很困惑。
答案 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
循环。