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

Process image stream in Lua by importing image pointer from C++

我正在 Lua 中处理深度学习任务,我需要将图像流从 C++ 导入 Lua。 C++ 脚本正在从共享内存读取数据,我有指向 C++ 图像的指针。我想在 Lua 中获取此指针并将图像流提供给我的神经网络。
由于 Lua 不使用指针,就我的研究而言,方法是将此指针包装到用户数据中并编写访问器方法。如本 User Data With Pointer Example.
中所述 我的问题是我需要为神经网络提供原始像素数据,到目前为止 material 在线提供的建议应该在 C++ 中处理数据,并且无法在 [=17= 中获取该对象] 直接地。
这里正确的方法应该是什么?如何从 C++ 中的指针获取 Lua 中的对象值?

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

我可以想到四种通用方法:

  1. 转换数据

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

    (这里就不多说这些选项了。)

  2. 将其作为用户数据传入并编写访问函数,因此您可以在 Lua 而不是 C(++)

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

  5. (仅LuaJIT)使用ffi.cdef声明C structs匹配内存中的格式以进行自由访问和转换(int,float , 没关系——也可以使用指针)

(2) 基本上只是 (1a),大部分代码转移到了 Lua 一侧。 (3) 与免费访问代码相同 (string.byte( data, i[, j]) and a bunch of others, newly added in 5.3: string.unpack(fmt, data[, startpos] ) ).

在决定其中一种方法之前,先看看对方想要什么格式。

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

否则,您将不得不实际接触数据。字符串版本可能是最简单的,但也可能是最慢的。 (如果数据是一个连续的字节块,您可以简单地 lua_pushlstring( L, ptr, len_in_bytes ) to get everything into Lua, but that creates a copy of the "string" internal to the Lua state which might be relatively slow.) After that, you can use the standard string handling functionality of 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,您可能希望使用(完整)用户数据和手动编写的访问器以避免数据复制造成的速度损失。 (需要完整的用户数据,因此您可以设置元 table 来获取访问器,但它可以只是指向外部分配数据的指针。)"Programming in Lua" 一书对此有很好的信息(首先版本已上线,direct link to the relevant chapter.)