java unknown exception when using Mat.put
I need to allocate rather large matrix using OpenCV 3.1.0. I'm running following code with -Djava.library.path=$MODULE_DIR$\opencv\310\windows\x64\ -Xmx8g arguments:
public class MatTest extends BaseTest {
static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
@Test
public void tooBig() throws IOException {
float[] data = new float[13320*67294];
Mat iMatrix = new Mat(13320, 67294, CvType.CV_32FC1);
iMatrix.put(0, 0, data); //exception here
}
@Test
public void medium() throws IOException {
float[] data = new float[13918*13240];
Mat iMatrix = new Mat(13918, 13240, CvType.CV_32FC1);
iMatrix.put(0, 0, data);
}
}
The first test works, since the seconds throws (line: iMatrix.put(0, 0, data))
java.lang.Exception: unknown exception
at org.opencv.core.Mat.nPutF(Native Method)
at org.opencv.core.Mat.put(Mat.java:953)
at my.app.MatTest.tooBig(MatTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
Is it a OpenCV or native library usage limitation? Is there a workaround for such issue?
Edited: attached full code and stacktrace
13320*67294*4 = 3585424320
, so you're overflowing signed int type used for thecount
variable heremaybe you can work around it by putting 2 slices of half the size ?
I have tried with smaller pieces, same result:
hmm, sorry for putting you on the wrong track, then (but that's exactly, what i meant)
I would try to recompile opencv and change this signed int to something bigger. Do you think it would help?
yea, it's obviously some bug in the c++ -> java wrappers. if you want to sink a screwdiver somewhere, this might be a good entry point (count, num, and some others should be unsigned, not signed, imho.)
but that only will kinda double your headroom. even if count is unsigned int, it'll only allow 4294967295 bytes in one go (that's where the previous 'try to ^do it in slices' idea originated.)
It took me some time to compile opencv but yes, making those variable unsigned int solved the problem. Thanks a lot. I'll create a pull request with this change - hopefully somone can confirm that it won't break anything.