常见问题及解决方案#
推理时如何能够快速传递图像数据?#
visionflow::img::Image
支持直接接受数据指针传递内存中的图像数据,你可以像下面这样直接将
内存中的图像数据指针传递给 visionflow::img::Image
,从而实现零拷贝传递图像数据:
void * data_ptr = get_image_data_ptr(); // 获取数据指针
vflow::img::Image image(data_ptr, // 数据指针
height, //图像高度/行数
width, // 图像宽度/列数
channel, // 图像通道数
flow::img::Image::kDepthU8, // 图像数据类型
0); // 图像行之间间隔的长度,以字节为单位
// 假设已有内存数据byte[],其中存储了图像的数据内容:
byte[] array = new byte[length];
// 你可以获取byte array的数据指针,也可以是其他指向图像数据的指针
// 在C#中这是一个unsafe的行为,因此需要在工程“属性->生成”中勾选“允许不安全代码”。
IntPtr data_ptr = System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
var image2 = new visionflow.img.Image(
data_ptr, // 数据指针
height, //图像高度/行数
width, // 图像宽度/列数
channel, // 图像通道数
visionflow.img.Image.Depth.kDepthU8,
0); // 图像行之间间隔的长度,以字节为单位
值得注意的是,使用上面的方法传递数据,需要注意以下几点:
visionflow::img::Image
不会管理传入数据指针的释放,用户需要自行合理维护构造得到的图像对象和数据指针的生存期关系 确保数据指针晚于构造的图像对象释放,以免发生错误。以及确保数据指针指向的数据不会被外部错误修改导致产生预期外的结果。一般情况下,VisionFlow在推理过程中不会修改样本中的图像数据,但用户需要避免自行将图像传递给可能会修改图像内容的函数 (例如
visionflow::img::draw()
),以免图像数据被错误修改;VisionFlow中图像数据内容是按照 H x W x C 的形式排列的,因此用户需要确保传入的数据内容的排布方式与VisionFlow一致。且数据长与给定 图像的的大小匹配。