Convert OpenCV code from C ++ to Java

I'm currently trying to port a bit of outdated code from iPhone to Android. This code uses the OpenCV library to process some images. In general, everything is going well, but I am stuck in one line of code, I have no idea how to convert it to Java code:

Scalar dMean; Scalar scalar; std::vector<Mat> channels; split(mat, channels); for(int i=0; i<3; ++i) { channels[i] += dMean[i]; } 

The question is what should be used instead of the + = operator in Java code to add a Scalar object to Mat?

+6
source share
1 answer

Note: take this answer with salt, I have not fully tested it;)

OPTION1:

The most direct way, and if you are going to process only a few pixels, use your_mat.put (string, col, data) and your_mat.get (string, Col) .

Since the put() method does not accept Scalar objects as a data parameter, you need to convert Scalar to what put() accepts.

So, if your Scalar is (1,2,3), perhaps the array int int [] scalar = {1,2,3}; gotta do the trick.

 int[] scalar = ... // convert from Scalar object // assuming the result of get() is an int[], sum both arrays: int[] data = your_mat.get(row, col) + scalar // <- pseudo-code alert :D your_mat.put(row, col, data); 

OPTION2:

But the recommended way to handle a large number of pixels is to first convert Mat to a Java primitive, process the primitive, and then convert it back to Mat . This is done in order to avoid too many JNI calls, this method makes 2 JNI calls, while the first one makes one for put / get.

The corresponding type of array of Java primitives depends on the type of Mat:

 CV_8U and CV_8S -> byte[]; CV_16U and CV_16S -> short[]; CV_32S -> int[]; CV_32F -> float[]; CV_64F-> double[]; 

So the code would be something like this:

 // assuming Mat it of CV_32S type int buff[] = new int[your_mat.total() * your_mat.channels()]; your_mat.get(0, 0, buff); // buff is now Mat converted to int[] your_mat.put(0, 0, buff); // after processing buff, convert it back to Mat type 

OPTION 3:

Ok, so these solutions are pretty ugly, this one is not the most efficient, but it is a little less ugly, in different ways:

 List<Integer> scalarList = ... // your conversion from a Scalar to a List List<Integer> channelsList = new ArrayList<Integer>(); Converters.Mat_to_vector_int(channels, channelsList); // this is an existing OpenCV4Android converter // process channelsList and scalarList, store in channelsList channels = Converters.vector_int_to_Mat(channelsList); // after processing, convert it back to Mat type 

Now, when I think about it, option 3 is very similar to option 2 , if OpenCV Converters works the same way inside option 2 > conversion.

+5
source

Source: https://habr.com/ru/post/904490/


All Articles