Ask Your Question

cmaster11's profile - activity

2016-08-04 17:18:59 -0500 commented answer OpenCV4Android 3.1 Mat to Allocation Renderscript

Honestly, I'm not fond of this kind of topics, but I found this page: https://docs.rainmeter.net/tips/colormatrix-guide/

2016-08-04 16:30:37 -0500 commented answer OpenCV4Android 3.1 Mat to Allocation Renderscript

Isn't the matrix the following one?

0.393f, 0.349f, 0.272f, 0f, 
0.769f, 0.686f, 0.534f, 0f, 
0.189f, 0.168f, 0.131f, 0f, 
0.000f, 0.000f, 0.000f, 1f
2016-08-04 12:26:05 -0500 received badge  Supporter (source)
2016-08-04 12:24:21 -0500 received badge  Editor (source)
2016-08-04 09:22:38 -0500 answered a question OpenCV4Android 3.1 Mat to Allocation Renderscript

Hi!

This is a crazy one, but possible to achieve.

Note: a feature like this one has to be treated as experimental. It is a proof of concept, based upon non-official ways of "doing things with RenderScript".

I created this example just for this case: https://bitbucket.org/cmaster11/rsbookexamples/src/tip/OpenCVInteropExample/

Main file, for reference: MainActivity.java

The concept of this example is based upon the RenderScript (RS) ability to instantiate an Allocation using a user-provided data pointer.

Short explanation: inside RenderScript source code, you can see one method declaration:

long nAllocationCreateTyped(long type, int mip, int usage, long pointer)

The last argument, pointer, can be used to tell RenderScript that it should create a new Allocation, pointing at a certain memory address. Binding this behavior with OpenCV, where you can invoke the Mat.dataAddr() method to get a Mat data pointer, lets you create a RenderScript allocation that completely overlaps the OpenCV mat.


What the sample project does is:

  1. Loads a custom drawable file, bundled together with the app, inside a Bitmap.
  2. Creates an OpenCV mat from the Bitmap.
  3. Instantiates a RenderScript allocation, which points to the OpenCV mat data pointer.
  4. Instantiates another RS allocation, which points to another OpenCV mat, to be used as output.
  5. Executes a kernel over the input allocation.
  6. Converts the OpenCV output allocation to a Bitmap. Note: the output allocation is DIRECTLY bound to the output OpenCV allocation because they share the same memory address.

Note: please, refer to the README.md, which comes together with the example, to have it work correctly. It requires you to download the OpenCV SDK.


The ability to support a user-provided data pointer is dependent upon the RS device-specific driver. When tested on a Galaxy Note 3 (Android 5.1), it didn't work. There is a high chance that later versions of Android provide good support for this functionality.

This functionality works by enabling the RS support library at the cost of using a non-performant RS driver.

The process of binding a RS allocation to a user-provided pointer can be achieved by directly calling the native RS function RenderScript.nAllocationCreateTyped and passing it, as last argument, the pointer address to the user data (in this case, the OpenCV mat data pointer).

This process, however, requires the usage of Java reflection:

  1. Retrieve the RenderScript.nAllocationCreateTyped hidden method.
  2. Invoke it to obtain an Allocation pointer.
  3. Instantiate a new Allocation class, using the hidden Allocation() constructor.

Reference: RenderScript: parallel computing on Android, the easy way