1

我正在运行一个安卓相机应用程序,我想用 Python 进行图像处理。为了测试这一点,我想将单个图像帧传递给 python 函数,使用整数除法将所有值除以 2 并返回结果。

为此,我有以下代码:

在 Java 中:

public void onCapturedImage(Image image)
    {

        Image.Plane[] tmp = image.getPlanes();
        byte[] bytes = null;
        ByteBuffer buffer = tmp[0].getBuffer();
        buffer.rewind();
        bytes = new byte[buffer.remaining()];
        buffer.get(bytes, 0, buffer.remaining());
        buffer.rewind();

        Log.d(TAG, "start python section");

        // assume python.start() is elsewhere

        Python py = Python.getInstance();
        PyObject array1 = PyObject.fromJava(bytes);
        Log.d(TAG, "get python module");
        PyObject py_module = py.getModule("mymod");
        Log.d(TAG, "call pic func");

        byte [] result  = py_module.callAttr("pic_func", array1).toJava(byte[].class);
        // compare the values at some random location to see make sure result is as expected
        Log.d(TAG, "Compare: "+Byte.toString(bytes[33]) + " and " + Byte.toString(result[33]));
        Log.d(TAG,"DONE");

    }

在python中,我有以下内容:

import numpy as np

def pic_func(o):
    a = np.array(o)
    b = a//2
    return b.tobytes()

我对这段代码有几个问题。

  1. 它的行为不像预期的那样 - 位置 33 的值不是一半。我可能混淆了字节值,但我不确定到底发生了什么。没有“tobytes”并使用 python 列表而不是 numpy 数组的相同代码确实可以按预期工作。

  2. 传递参数 - 不确定幕后会发生什么。它是按值传递还是按引用传递?是数组被复制,还是只是一个指针被传递?

  3. 它很慢。计算超过 1200 万个值的操作大约需要 90 秒。关于加快速度的任何指示?

谢谢!

4

1 回答 1

2

你的最后两个问题是相关的,所以我会一起回答。

PyObject array1 = PyObject.fromJava(bytes)
py_module.callAttr("pic_func", array1)

这通过引用传递:Python 代码接收jarray访问原始数组的对象。

np.array(o)

从 Chaquopy 8.x 开始,当o它是 Java 原始数组时,这是一个直接内存副本,因此性能应该不是问题。在旧版本的 Chaquopy 上,您可以通过首先转换为 Python 对象来避免缓慢的逐个元素复制bytes,这可以用任何一种语言完成:

  • 在 Java 中:PyObject array1 = py.getBuiltins().callAttr("bytes", bytes)
  • 或者在 Python 中:np.array(bytes(o))
b.tobytes()
toJava(byte[].class)

这两个表达式也会进行复制,但它们也将是直接内存复制,因此性能应该不是问题。

至于它返回错误的答案,我认为这可能是因为 NumPy 使用其默认数据类型float64. 调用时,应通过传递或np.array明确指定数据类型。(如果您在Chaquopy 文档中搜索,您会找到有关签名/未签名转换如何工作的确切详细信息,但尝试两者并查看哪一个给出您期望的答案可能更容易。)dtype=np.int8dtype=np.uint8byte[]

于 2020-03-23T10:38:18.777 回答