3

I am trying to figure out how to set the ROI for an Image in OpenCV on Android. I have done this on other operating systems, so I think HOW I am doing it is semantically correct, but there is an error somewhere.

So far I have tried this

Rect roi = new Rect(0, 0, inputFrame.cols(), inputFrame.rows());
Mat cropped = new Mat(inputFrame, roi);

However I get an error somewhere in the OpenCV classes that looks like this

Utils.matToBitmap() throws an exception:/home/reports/ci/slave/opencv/modules/java/generator/src/cpp/utils.cpp:107: 
error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width ==
(uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2
(JNIEnv*, jclass, jlong, jobject, jboolean)

I am calling this in the onCameraFrame callback provided by opencv wrapper class

Not sure how to go about this, has anyone successfully done this?

Jameo
  • 4,507
  • 8
  • 40
  • 66

2 Answers2

8

OpenCV for Android (and the new Java API) has its own way to create ROI's.

All you have to do is to call the submat method of your Mat object. If I am not mistaken, calling submat does not create a copy of that image region, if you want a copy you can use copyTo on the submat for that purpose.

Mat roi = inputFrame.submat(rowStart, rowEnd, colStart, colEnd);

You can call submat in 3 different ways, check the links for more details:

  • submat(int rowStart, int rowEnd, int colStart, int colEnd)

submat 1

  • submat(Range rowRange, Range colRange)

submat 2

  • submat(Rect roi)

submat 3

Rui Marques
  • 8,567
  • 3
  • 60
  • 91
  • I actually use this so I can display some image processing that Im doing in a different part of the window. I actually didnt even think that this is really the same thing as ROI. Thanks for you input!! – Jameo Feb 13 '13 at 19:28
  • Yes, feel free to accept this answer instead. I think @karlphillip will also agree this method is more adequate. – Rui Marques Feb 13 '13 at 19:32
  • I chose your answer because its very similar to what I ended up using in the end. But I believe they are almost identical memory wise – Jameo Feb 13 '13 at 19:38
  • @Jameo It's not cool to do that since you got a working answer from someone almost 10 days ago. But you are allowed to do what you want. :) – karlphillip Feb 13 '13 at 21:41
2

The error is stating that you are trying to set a ROI with the same dimensions of the image, so there's no need for a ROI in this case.

To make sure this is the problem, the following should work:

Rect roi = new Rect(0, 0, inputFrame.cols() - 1, inputFrame.rows() - 1);
Mat cropped = new Mat(inputFrame, roi);
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • Yes, I changed it to be the entire image because I though I was having problems with an invalid crop size. Your code above does not work either. It looks like it only has to do with this call to Utils.matToBitmap() (in fact I've stepped through and everything looks fine up until then). Any idea why changing the ROI could effect this? – Jameo Feb 05 '13 at 14:03
  • This is random but may have caused my problem, is there a differnece between img.copyTo(img2) and img2 = img.clone() ? – Jameo Feb 05 '13 at 21:16
  • [Mat::copyTo](http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-copyto) vs [Mat::clone](http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-clone). It seems that `copyTo()` respects the ROI if one is set, and `clone()` ignores it. – karlphillip Feb 05 '13 at 21:35
  • Thanks for your help, I did end up figuring it out!! – Jameo Feb 05 '13 at 21:40