通过从 C++ 导入图像指针来处理 Lua 中的图像流



我正在Lua中处理深度学习任务,我需要将图像流从C++导入Lua。C++脚本正在从共享内存中读取数据,我有指向C++图像的指针。我想在Lua中获取这个指针,并将图像流提供给我的神经网络。
由于Lua不使用指针,就我的研究而言,要走的方法是将此指针包装到userdata中并编写访问器方法。如此用户数据与指针示例中所述。
我的问题是我需要用原始像素数据提供给神经网络,到目前为止,在线可用的材料表明,对数据的处理应该在C++中完成,并且没有办法直接在Lua中获取该对象。
这里应该采取什么正确的方法?如何从 C++ 中的指针获取 Lua 中的对象值?

好吧,你必须以某种方式使Lua可以访问数据。

我可以想到四种一般方法:

  1. 转换数据

    • 编写遍历数据的 C(++) 代码以创建 Lua 数据 由表和基元值(布尔值、数字、 字符串)
    • 将数据转换为交换格式(JSON、CBOR、...或在 图像数据案例: PNM/PAM)为此 你两边都有代码,或者可以简单地编写它

    (我不会在这里多说这些选项。

  2. 将其作为userdata传递并编写访问器函数,因此您可以使用Lua而不是C(++)编写转换代码

  3. (仅适用于无指针数据,图像通常是这样)将原始数据区域作为字符串传递给Lua

  4. (仅限LuaJIT)使用ffi.cdef声明与内存中格式匹配的Cstruct,以便自由访问和转换(int,float,无关紧要 - 也可以使用指针)

(2)基本上只是(1a),大部分代码转移到Lua端。 (3)与免费访问器代码(string.byte( data, i[, j])和其他一堆代码相同,在5.3中新添加:string.unpack(fmt, data[, startpos] ))。

在决定其中一种方法之前,请查看另一方想要的格式。

也许您的数据已经采用该格式,在这种情况下,您只需以某种方式通过指针进行路由。 (也许有一个函数接受Lua表,但也许还有一个函数接受指向原始图像数据的字符串或指针。 如果适用,请使用(浅色)用户数据或字符串进行通信。 (这可能是最快的,如果这种传递数据的方式尚不存在,请考虑向上游询问他们是否可以添加它。

如果做不到这一点,你将不得不实际接触数据。 字符串版本可能是最简单的,但也可能是最慢的。 (如果数据是一个连续的字节块,你可以简单地lua_pushlstring( L, ptr, len_in_bytes )将所有内容都放入Lua,但这会在Lua状态内部创建一个"字符串"的副本,这可能相对较慢。 之后,您可以使用Lua的标准字符串处理功能。

如果您使用的是 LuaJIT,那么使用ffi库可能是一个非常好的主意。 一个非常简短的概述,你可能需要什么(以链表为例):

ffi = require "ffi"
-- sample structure, yours will differ
ffi.cdef [[
typedef struct Node_s { struct Node_s *next; int value; } Node;
]]
-- in your case you will get a pointer from C, which you can then
-- ffi.cast( "Node*", ptr )
-- after that, you can access the fields (ptr.next, ptr.value etc.)
-- we'll just use some dummy sample data here:
do
local p = ffi.new( "Node" )
local q = ffi.new( "Node" )
p.next = q
p.value, p.next.value = 23, 42
ptr = tonumber( tostring( p ):match( ": (0x%x*)" ) )
end
data = ffi.cast( "Node*", ptr )
print( "first value:", data.value )
--> first value:    23
print( "second value:", data.next.value )
--> second value:   42
print( "third value:", data.next.next.value )
--> Segmentation fault   [so be just as careful as you're in C(++)!]

最后,如果您使用的是 vanilla Lua,您可能需要使用(完整)用户数据和手动写入的访问器,以避免数据复制造成的速度损失。 (完整的用户数据是必需的,以便您可以设置元表来获取访问器,但它可以只是指向外部分配数据的指针。 《Lua编程》一书对此有很好的信息(第一版是在线的,直接链接到相关章节。

最新更新