私は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()
私は、このコードにはいくつかの問題を抱えています。
期待通りには動作しません - 場所33の値が半分ではありません。私はおそらく取り違えバイト値とがありますが、私は正確に何が起こっているのかわかりません。予想通り「tobytes」とPythonのリストを使用してではなく、numpyの配列を含まない同一のコードでは、作業を行います。
パラメータを渡す - いないことを確認ボンネットの下に何が起こりますか。それは、値または参照渡しますか?配列がコピーされているか、単にポインタが周りに渡されますか?
それは遅いです。それは1200万値の上に、この操作を計算するのに約90秒かかります。このアップを高速化上の任意のポインタ?
ありがとう!
あなたの最後の二つの質問が関連しているので、私はそれらを一緒にお答えします。
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.int8
かdtype=np.uint8
。(あなたが検索した場合byte[]
におけるChaquopyドキュメントあなたはどのように署名/署名のない変換作品の正確な詳細を見つけることができますが、それはただの両方を試してみてください、もう1つは、あなたが期待する答えを与えるかを確認する方が簡単だろうです。)