Java – How do I convert OpenCV-C++ code with pointers to JAVA?

How do I convert OpenCV-C++ code with pointers to JAVA?… here is a solution to the problem.

How do I convert OpenCV-C++ code with pointers to JAVA?

I’m currently translating some C++ code into Java for use in Android applications. However, I stumbled upon some tricky C++ code (C++ is not my primary language either). Below is the C++ code. This function calculates the image gradient (grayscale) in the openCV imageFrame.

cv::Mat computeMatXGradient(const cv::Mat &mat) {
  cv::Mat out(mat.rows,mat.cols,CV_64F);

  for (int y = 0; y < mat.rows; ++y) {
    const uchar *Mr = mat.ptr<uchar>(y);
    double *Or = out.ptr<double>(y);

    Or[0] = Mr[1] - Mr[0];
    for (int x = 1; x < mat.cols - 1; ++x) {
      Or[x] = (Mr[x+1] - Mr[x-1])/2.0;
    }
    Or[mat.cols-1] = Mr[mat.cols-1] - Mr[mat.cols-2];
  }
}

In this code, I don’t know how to interpret the first two lines in the first loop:

    const uchar *Mr = mat.ptr<uchar>(y);
    double *Or = out.ptr<double>(y);

What is done here and how do I translate it into Java code? I looked at the “mat.ptr<>()” function, but that wasn’t very helpful either. (The documentation can be found here .) Basic information about pointers (like here ) I’ve read it, but I still don’t understand how to read the lines above. Aside from the pointers used, I’m not quite sure what to do with the “uchar” type in use. How does this translate to Java?

The entire code can be found here .

I’ve looked at ways to implement the Matlab gradient function from scratch, but this seems much more difficult. (Yes, there are already topics about this (e.g. here ), but the thread doesn’t provide an actual answer on how to do this.) )

I really hope someone can explain how to handle the above C++ structure in Java. So far, I’ve done all the possible research I can, but I just don’t know how to do it in Java.
Thanks in advance!

Edit; Finally, I’ve been able to get it to work by using a double for loop. The code is as follows. However, it is much less efficient. On the Galaxy Tab4, the processing rate is only about 1 frame per second. I didn’t expect to get perfect results, but I wish it would be a little faster. Does anyone know if the code below could be done more efficiently? Even the smallest change will be huge because there are about six such double for loops in the algorithm.

private static Mat computeXGradient (Mat mat) {
    //Mat output = new Mat(mat.rows(), mat.cols(), CvType.CV_64F);
    Mat output = new Mat(mat.rows(), mat.cols(), CvType.CV_32F);
    for (byte y = 0; y < mat.rows(); ++y) {
        Mat mr = mat.row(y);
        output.put(y,0, mr.get(0,1)[0] - mr.get(0,0)[0]);
        for (byte x = 1; x < mat.cols() - 1; ++x) {
            output.put(y,x, (mr.get(0,x+1)[0] - mr.get(0,x-1)[0])/2.0);
        }
    }
    return output;
}

I’ve implemented multithreading (actually forcing more processors) and as you can see, I’ve also reduced the size of the Mat object I’m using.

Edit; After adjusting the resolution, the frame rate rises to a very acceptable level. Hopefully, this change won’t have much impact on spatial performance, but we’ll see that.

Solution

mat.ptr(y)Get the yth row from the matrix.

Similarly,out.ptr(y) get the yth row from the output matrix.

As far as translation is concerned, you can create a Row class in Java or just return an array from the ptr function.

If you don’t already provide a Matrix class, you can make Row a generic type, just as this library does. (e.g. Row<Integer>)

uchar (unsigned char) roughly translates to bytein Java. It is an 8-bit (signed) integer value. If you want to ensure that you can use the entire 0-255 range, use int instead.

Related Problems and Solutions