Chaquopyを使用してAndroid上でのpythonにJavaからバイト配列を渡します

ヤコフダン:

私はAndroidのカメラアプリを実行していると私は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秒かかります。このアップを高速化上の任意のポインタ?

ありがとう!

mhsmith:

あなたの最後の二つの質問が関連しているので、私はそれらを一緒にお答えします。

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

これは参照により渡し:Pythonコードは、受信jarray元の配列にアクセスするオブジェクト。

np.array(o)

np.array必ずコピーを作成し、そして配列はJNIを通じて一度に一つの要素にアクセスする必要があるため、この場合には、低速のコピーとなります。あなたは、Pythonのに変換することによって、これを避けることができますbytesいずれかの言語で行うことができ、第一の目的:

  • Javaでは: PyObject array1 = py.getBuiltins().callAttr("bytes", bytes)
  • またはPythonで: np.array(bytes(o))

これは実際には余分なコピーが作成されることになりますが、すべてのコピーは現在、ダイレクトメモリコピーを行うことができますので、それははるかに高速になります。

b.tobytes()
toJava(byte[].class)

これらの式のどちらもコピーを作成しますが、彼らはまた、ダイレクト・メモリ・コピーになりますので、パフォーマンスが問題になることはありません。

それは間違った答えを返すためとして、私はnumpyのは、そのデフォルトのデータ型を使用しているため、それはおそらくだと思いますfloat64呼び出すときnp.array、あなたは渡すことによって、明示的にデータ型を指定する必要がありますdtype=np.int8dtype=np.uint8(あなたが検索した場合byte[]におけるChaquopyドキュメントあなたはどのように署名/署名のない変換作品の正確な詳細を見つけることができますが、それはただの両方を試してみてください、もう1つは、あなたが期待する答えを与えるかを確認する方が簡単だろうです。)

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=350353&siteId=1