6

I'm currently trying to migrate a bit of legacy code from iPhone to Android. This code uses the OpenCV library to do some image processing. Overall it goes well, but I'm stuck on one line of code I have no idea how can be converted into 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 a Mat?

9
  • Can you show us what you've got, where exactly (in Java) you are stuck? Commented Dec 26, 2011 at 14:00
  • += is an acceptable operator for primitives, but not for Objects. You'll probably have to write a method that does the add for the object. Commented Dec 26, 2011 at 14:01
  • The C++ code adds a Scalar to a Mat object. In Java I have created both Scalar and Mat objects but cannot find a method to add Scalar to Mat. The Core class in JavaCV contains a static metod add(Mat, Mat, Mat), but it only allows you add two Mat's Commented Dec 26, 2011 at 14:05
  • @Binyamin Sharet I have indicated the exact line I have problems with - the line which contains the += operator Commented Dec 26, 2011 at 14:07
  • 1
    You can write the method in c++ and use the javacpp library by the same author to invoke it from your code. Should be much faster. I am pretty sure there is no existing corresponding operation in the java yet. Commented Dec 26, 2011 at 14:32

1 Answer 1

5

Note: take this answer with a grain of salt, I haven't fully tested this ;)

OPTION1:

The most direct way, and if you are only going to process a few pixels, is by using your_mat.put(row, col, data) and your_mat.get(row, col).

Because the put() method does not accept Scalar objects as the data parameter, you have to convert the Scalar to something that put() accepts.

So if your Scalar is (1,2,3) maybe an int array int[] scalar = {1,2,3}; should 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, for a lot of pixel processing, is to first convert a Mat to a Java primitive, process the primitive and then convert it back to Mat. This is to avoid too many JNI calls, this method does 2 JNI calls while the former makes one per put/get.

The corresponding Java primitive array type depends on the Mat type:

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

So the code will be something like this:

// assuming Mat it's 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 those solutions are pretty ugly, this one is not the most effective but it's a little less ugly, in a Java way:

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 that I think about it option 3 is quite similar to option 2, if OpenCV's Converters work similar internally as the option 2 conversion.

Sign up to request clarification or add additional context in comments.

2 Comments

Although this answer is not relevant anymore, I will accept it as it seems to be correct and complete
Yes i noticed later that the question was a bit old. But the problem is still quite common today for new opencv users. AFAIK these options are currently the best choices for iterating through pixels in java.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.