Watershed segmentation Visual Studio C++ to Java Android Studio

I have a problem when I traslate my code to Android Studio. The code in C++ is:

String folder = "images/categoria4/";
String filename = "ischaemic-leg-ulcer-with-tendon-visible";
String extension = ".jpg";
cv::Mat original = imread(folder + filename + extension);
cv::Mat frame_HSV, frame_threshold, final, res, diferencia, outImage, prueba, prueba2;
while (true) {

    cv::Mat dest, hsv;

    // Create markers image
    cv::Mat markers(original.size(), CV_8U, cv::Scalar(-1));
    //top rectangle
    markers(Rect(0, 0, original.cols, 5)) = Scalar::all(1);
    //bottom rectangle
    markers(Rect(0, original.rows - 5, original.cols, 5)) = Scalar::all(1);
    //left rectangle
    markers(Rect(0, 0, 5, original.rows)) = Scalar::all(1);
    //right rectangle
    markers(Rect(original.cols - 5, 0, 5, original.rows)) = Scalar::all(1);
    //centre rectangle
    int centreW = original.cols / 4;
    int centreH = original.rows / 4;
    markers(Rect((original.cols / 2) - (centreW / 2), (original.rows / 2) - (centreH / 2), centreW, centreH)) = Scalar::all(2);
    markers.convertTo(markers, COLOR_BGR2GRAY);
    imshow("markers", markers);

    //Create watershed segmentation object
    WatershedSegmenter segmenter;
    cv::Mat wshedMask = segmenter.process(original);
    cv::Mat mask;
    convertScaleAbs(wshedMask, mask, 1, 0);
    double thresh = threshold(mask, mask, 1, 255, THRESH_BINARY);
    bitwise_and(original, original, dest, mask);
    dest.convertTo(dest, CV_8U);
    imshow("Watershed", mask);
    imwrite(folder + filename + "_W" + extension, dest);

If I execute that program, the image Mat markers look like a black picture with a square on centre. I use it to localize the section in the original image.
The problem is when I try do it on Android Studio, the image markers don’t look like the previous code. It’s looks like a black image. This is the code in Java:

    public Mat watershedGithub2(Bitmap bmp){
    Mat img = new Mat();
    Mat rgba = new Mat();
    Mat dest = new Mat();
    Utils.bitmapToMat(bmp, img);
    Mat threeChannel = new Mat();
    img.convertTo(img, CvType.CV_8UC3);

    Imgproc.cvtColor(img, rgba, Imgproc.COLOR_RGBA2RGB);

    Imgproc.cvtColor(rgba, threeChannel, Imgproc.COLOR_BGR2GRAY);
    Imgproc.threshold(threeChannel, threeChannel, 100, 255, Imgproc.THRESH_BINARY);

    Mat fg = new Mat(rgba.size(),CvType.CV_8UC3);
    Imgproc.erode(threeChannel,fg,new Mat());

    Mat bg = new Mat(rgba.size(),CvType.CV_8UC3);
    Imgproc.dilate(threeChannel,bg,new Mat());
    Imgproc.threshold(bg,bg,1, 128,Imgproc.THRESH_BINARY_INV);

    Mat markers = new Mat(rgba.size(),CvType.CV_8UC3, new Scalar(-1));
    Imgproc.rectangle(markers, new Point(0,0), new Point(rgba.cols(),5), new Scalar(255), -1);
    Imgproc.rectangle(markers, new Point(0,rgba.rows()-5), new Point(rgba.cols(),5), new Scalar(255), -1);
    Imgproc.rectangle(markers, new Point(0,0), new Point(5,rgba.rows()), new Scalar(255), -1);
    Imgproc.rectangle(markers, new Point(rgba.cols()-5,0), new Point(5,rgba.rows()), new Scalar(255), -1);

    int centreW = rgba.cols()/4;
    int centreH = rgba.rows()/4;

    Imgproc.rectangle(markers, new Point((rgba.cols()/2)-(centreW/2),(rgba.rows()/2)-(centreH/2)), new Point(centreW,centreH), new Scalar(255), -1);
    markers.convertTo(markers, Imgproc.COLOR_BGR2GRAY);

    Core.add(fg, bg, markers);
    Mat result1 = new Mat();
    WatershedSegmenter segmenter = new WatershedSegmenter();
    result1 = segmenter.process(rgba);
    Mat mask = new Mat();
    Core.convertScaleAbs(result1, mask, 1, 0);
    double thresh = Imgproc.threshold(mask, mask, 1, 255, Imgproc.THRESH_BINARY);
    Core.bitwise_and(rgba, rgba, dest, mask);
    dest.convertTo(dest, CvType.CV_8UC3);
    return dest;


How can I fix it?

Rect and rectangle are different things.

Rect describes the position and size of a rectangle. a matrix “called” with a Rect returns a matrix of that subregion.

rectangle draws a rectangle.

Then how can I pass that code line to Java? I think it was the correct form.

 markers(Rect(0, 0, original.cols, 5)) = Scalar::all(1);

that line takes the specified subregion and sets all its elements to 1.

I am not familiar with the java API. try submat() and then setTo() on the submatrix.

I try translate, and I try this:

    Mat markers = new Mat(rgba.size(),CvType.CV_8UC3, new Scalar(-1));
    markers.submat(new Rect(0,0,rgba.cols(), 5)).setTo(new Scalar(1,1,1));
    markers.submat(new Rect(0,rgba.rows()-5,rgba.cols(), 5)).setTo(new Scalar(1,1,1));
    markers.submat(new Rect(0,0,5, rgba.rows())).setTo(new Scalar(1,1,1));
    markers.submat(new Rect(rgba.cols()-5,0,5, rgba.rows())).setTo(new Scalar(1,1,1));

    int centreW = rgba.cols()/4;
    int centreH = rgba.rows()/4;

    markers.submat(new Rect((rgba.cols()/2)-(centreW/2), (rgba.rows()/2)-(centreH/2), centreW, centreH)).setTo(new Scalar(2,2,2));
    markers.convertTo(markers, Imgproc.COLOR_BGR2GRAY);

But now I have that error with opencv:

E/cv::error(): OpenCV(3.4.11) Error: Assertion failed (src.type() == CV_8UC3 && dst.type() == CV_32SC1) in void cv::watershed(cv::InputArray, cv::InputOutputArray), file /build/3_4_pack-android/opencv/modules/imgproc/src/segmentation.cpp, line 161

I change type in that part, but it don’t work or not change correctly:

    class WatershedSegmenter {
    public Mat markers=new Mat();

    public void setMarkers(Mat markerImage)
        markerImage.convertTo(markers, CvType.CV_32SC1);

    public Mat process(Mat image)
        image.convertTo(image, CvType.CV_8UC3);
        //Log.i(TAG, "LLEGA AQUI");
        return markers;

Any help?

your original code says

    WatershedSegmenter segmenter;

why did you translate that into just Imgproc.watershed(image,markers);?

Because that part in C++ is like that

    watershed(image, markers);

So the only way I found to translate is with Imgproc.watershed(image,markers);.

what is the WatershedSegmenter in the C++ code? it is not an OpenCV class.

it looks like you took your code from some book, without mentioning that. you also didn’t post all the relevant code, leaving me/us to guess what your problem is.

don’t keep secrets. be forthcoming with information. I will not drag this information out of you or dig it up myself when you could have simply provided it.

Yes, I forgot to mention the site from which I have documented. But I can’t solve my problem yet. Why is that error in java but it’s not happen in c++?

try not converting in-place. convert into different Mat objects.

how? sorry but it’s my first time using opencv and doing anything like that, and I have problems programming that