0

At the first contact with Java OpenCV (3.3.1, windows 8 x64) I'm trying to join two different size images with ROI dynamically. Here a bit of my code:

Mat _mat = Utils.imageFileToMat(new File("angelina_jolie.jpg")); //Angelina's face
Mat grayMat = new Mat();
Imgproc.cvtColor(_mat, grayMat, Imgproc.COLOR_BGR2GRAY);
Rect rect = new Rect(new Point(168, 104), new Point(254, 190)); //Angelina's eye ROI
Mat truncated = _mat.submat(rect); //Angelina's eye mat

Mat merge = _mat.clone();
truncated.copyTo(merge);

//show _mat
//show truncated
//show merge

What I want to see is Angelina Jolie with her eye on grayscale.

What I see is assertions or the truncated image only (just the eye).

I tried with copyTo(mat, mask), setOf, and a lot of things but always get a new assertion.

Should I change the size of truncated to the size of mat to match sizes? how can I do that programmatically?

jotapdiez
  • 1,456
  • 13
  • 28

1 Answers1

1

Mat::copyTo documentation:

The method copies the matrix data to another matrix. Before copying the data, the method invokes :

m.create(this->size(),this->type());

so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.

When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data.

@param m Destination matrix. If it does not have a proper size or type before the operation, it is reallocated.

Since you're your src and dst images don't have the same size and channels, the destination image is reallocated and initialized with zeros. To avoid that make sure both images have same dimensions and number of channels.

Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_GRAY2BGR);

Now create a mask:

Mat mask = new Mat(_mat.size(), CvType.CV_8UC1, new Scalar(0));
Imgproc.rectangle(mask, new Point(168, 104), new Point(254, 190),new Scalar(255));
// copy gray to _mat based on mask
Mat merge = _mat.clone();
grayMat.copyTo(merge,mask);
zindarod
  • 6,328
  • 3
  • 30
  • 58
  • I came here to answer my own question because I found the solution and I saw your answer. Thanks! (On answers opencv site i posted the same question if you want to answer that too) – jotapdiez Nov 08 '17 at 21:28
  • @jotapdiez You take that one ;) Great that you found the solution. – zindarod Nov 08 '17 at 21:33
  • I resolve the problem only with Imgproc.cvtColor(grayMat, grayMat, Imgproc.COLOR_GRAY2BGR) and truncated.copyTo(merge.submask.... A mask creation is better than submask? – jotapdiez Nov 08 '17 at 21:36
  • 1
    @jota better the submask approach – Miki Nov 08 '17 at 22:45
  • 1
    @jotapdiez As Miki said, submask is better. For a submask, only the header is created, the data pointer is the same as the original image. So no extra copy in submask. – zindarod Nov 08 '17 at 23:09