简体   繁体   English

使用 Chaquopy 在 Android 上将字节数组从 java 传递到 python

[英]Passing a byte array from java to python on Android using Chaquopy

I'm running an android camera app and I would like to do the image processing in Python.我正在运行一个 android 相机应用程序,我想用 Python 进行图像处理。 To test this, I want to pass a single image frame to a python function, divide all values by 2 using integer division and return the result.为了测试这一点,我想将单个图像帧传递给 python 函数,使用整数除法将所有值除以 2 并返回结果。

For that end, I have the following code:为此,我有以下代码:

in Java:在 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");

    }

In python, I have the following:在python中,我有以下内容:

import numpy as np

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

I have several issues with this code.我对这段代码有几个问题。

  1. It does not behave as expected - the value at location 33 is not half.它的行为不符合预期 - 位置 33 处的值不是一半。 I probably have a mix-up with the byte values, but I'm not sure what's going on exactly.我可能混淆了字节值,但我不确定到底发生了什么。 The same code without "tobytes" and using a python list rather than a numpy array does work as expected.没有“tobytes”并使用python列表而不是numpy数组的相同代码确实按预期工作。

  2. Passing parameters - not sure what happens under the hood.传递参数 - 不确定引擎盖下会发生什么。 Is it pass by value or by reference?是按值传递还是按引用传递? Is the array being copied, or just a pointer being passed around?是数组被复制,还是只是一个指针被传递?

  3. It is SLOW.它很慢。 it takes about 90 seconds to compute this operation over 12 million values.计算此操作超过 1200 万个值大约需要 90 秒。 Any pointers on speeding this up?关于加快速度的任何指示?

Thanks!谢谢!

Your last two questions are related, so I'll answer them together.你的最后两个问题是相关的,所以我会一起回答。

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

This passes by reference: the Python code receives ajarray object which accesses the original array.这是通过引用传递的:Python 代码接收一个访问原始数组的jarray对象。

np.array(o)

As of Chaquopy 8.x, this is a direct memory copy when o is a Java primitive array, so performance shouldn't be a problem.从 Chaquopy 8.x 开始,当o是 Java 原始数组时,这是直接内存复制,因此性能应该不是问题。 On older versions of Chaquopy, you can avoid a slow element-by-element copy by converting to a Python bytes object first, which can be done in either language:在旧版本的 Chaquopy 上,您可以通过首先转换为 Python bytes对象来避免逐个元素的缓慢复制,这可以用任何一种语言完成:

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

Both of these expressions will also make a copy, but they will also be direct memory copies, so performance shouldn't be a problem.这两个表达式也会进行复制,但它们也将是直接内存复制,因此性能应该不成问题。

As for it returning the wrong answer, I think that's probably because NumPy is using its default data type of float64 .至于它返回错误的答案,我认为这可能是因为 NumPy 使用的是它的默认数据类型float64 When calling np.array , you should specify the data type explicitly by passing dtype=np.int8 or dtype=np.uint8 .调用np.array ,您应该通过传递dtype=np.int8dtype=np.uint8 dtype=np.int8明确指定数据类型。 (If you search for byte[] in the Chaquopy documentation you'll find the exact details of how signed/unsigned conversion works, but it's probably easier just to try both and see which one gives the answer you expect.) (如果您在Chaquopy 文档中搜索byte[] ,您将找到有关有符号/无符号转换如何工作的确切细节,但尝试两者并查看哪一个给出您期望的答案可能更容易。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM