bytedeco / javacpp-presets

The missing Java distribution of native C++ libraries
Other
2.65k stars 738 forks source link

Crash on cvtColor #979

Closed cotfas closed 3 years ago

cotfas commented 3 years ago

Mac OS X Catalina 10.15.7 (19H15) Apache Karaf 4.1.5

Dump file:

Stack: [0x0000700005eeb000,0x0000700005feb000], sp=0x0000700005fe5e80, free space=1003k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C [libsystem_platform.dylib+0x929] _platform_memmove$VARIANT$Haswell+0x29 C [libopencv_core.3.2.dylib+0x614ee] _ZNK2cv3Mat6copyToERKNS_12_OutputArrayE+0xc2e C [libopencv_core.3.2.dylib+0x147077] _ZNK2cv11_InputArray6copyToERKNS_12_OutputArrayE+0x387 C [libopencv_imgproc.3.2.dylib+0x276b7] _ZN2cv8cvtColorERKNS_11_InputArrayERKNS_12_OutputArrayEii+0x257 C [libjniopencv_imgproc.dylib+0x7be79] Java_org_bytedeco_javacpp_opencv_1imgproc_cvtColor__Lorg_bytedeco_javacpp_opencv_1core_00024Mat_2Lorg_bytedeco_javacpp_opencv_1core_00024Mat_2I+0xf9

Dependencies:

<javacv.version>1.3.3</javacv.version>
<javacv.presets.version>3.2.0-1.3</javacv.presets.version>

 <dependency>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>opencv-platform</artifactId>
    <version>${javacv.presets.version}</version>
</dependency>
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacpp</artifactId>
    <version>${javacv.version}</version>
</dependency>
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>${javacv.version}</version>
</dependency>

Code:

Mat matrix = new OpenCVFrameConverter.ToMat().convert(new Java2DFrameConverter().convert(bufferedImage)); Mat grayMatrix = new Mat(matrix.size(), CV_8UC1); if (matrix.channels() == 4) { cvtColor(matrix, matrix, CV_BGRA2BGR); <<< crashing here with SIGSEGV on 6k/9k pixel image (PNG size 45mb) }

Console:

/# SIGSEGV (0xb) at pc=0x00007fff6f52d929, pid=10594, tid=0x000000000001b923 /# /# JRE version: Java(TM) SE Runtime Environment (8.0_261-b12) (build 1.8.0_261-b12) /# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.261-b12 mixed mode bsd-amd64 compressed oops) /# Problematic frame: /# C [libsystem_platform.dylib+0x929] _platform_memmove$VARIANT$Haswell+0x29

Posted:

https://gitter.im/bytedeco/javacpp https://github.com/bytedeco/javacpp/issues/441 https://github.com/opencv/opencv/issues/19039 https://github.com/bytedeco/javacpp-presets/issues/979

saudet commented 3 years ago

Please try again with OpenCV 4.4.0.

cotfas commented 3 years ago

Will it work with 4.4.0? Is there any commit related to it so I can check? I`m asking because updating the version will be hard due to Karaf/OSGi stuff. Thank you.

saudet commented 3 years ago

As pointed out by @alalek, cvtColor() won't always work correctly inplace, so try not to do that.

cotfas commented 3 years ago

I have a lot of errors when trying to upgrade the versions.

Like:

missing requirement [**.service/1..**] osgi.wiring.package; filter:="(osgi.wiring.package=android.app)"]]]

It only crashes with some kind of image over 6/9k pixels. Other ones works.

What I should do, is it possible to catch the NDK/C++ crash so the whole server does not shutdown..? Because in this case I can try resizing dynamically the resolution as fallback.

I can not remove the cvtColor the whole project depends on it, and better I would want to do a hotfix rather than upgrading the lib versions (maybe it fixes the problem, but then maybe there are cases where it work with older version and with the newer one not, and I can not have that risk :S)

Thank you

cotfas commented 3 years ago

As pointed out by @alalek, cvtColor() won't always work correctly inplace, so try not to do that.

I already corrected src/dest object but still the same..

saudet commented 3 years ago

Then one of the Mat objects is corrupted. Try to find which one, for example, by performing some operation on it.

cotfas commented 3 years ago

Alright, tnx for the idea.

What I will try is the matrix will convert it back to BufferedImage without cvtColor and then write to disk to check it.

eg: BufferedImage buff = new Java2DFrameConverter().convert(new OpenCVFrameConverter.ToMat().convert(matrix));

One question, from low level C++ can I do debug as well? eg. when it enters into cvtColor method I would want to debug inside to see what it is happening.

saudet commented 3 years ago

BTW, the lifetime of the Mat object returned by OpenCVFrameConverter is linked to it, so when it gets garbage collected, the Mat object becomes invalid. Make sure that's not happening.

jpsacha commented 3 years ago

@saudet What would be a way to deal with "lifetime" if it is not possible to maintain a reference to OpenCVFrameConverter?

For instance, if I have a library utility method that converts some Java-based image representation to OpenCV:

public class MyUtils {
  public static Mat toMat(ImagePlus src) {
    Frame frame = new MyCustomConverter().convert(src);
    return new OpenCVFrameConverter.ToMat().convert(frame);
  }
}

Should I create a "clone" at place of call to toMat to ensure a transfer of "lifetime" to the place of call? For instance:

  ImagePlus imp = ...
  Mat mat = MyUtils.toMat(imp).clone();

Though it may be too late to call clone() (it is outside of scope of toMat())?

saudet commented 3 years ago

We need to make a copy before it goes out of scope, yes.

cotfas commented 3 years ago

Sorry, from what I saw the image has over 30k pixels size and ~800mb png size.

saudet commented 3 years ago

So, you're just running out of memory?

cotfas commented 3 years ago

I guess, it were crashing with NDK/C level so not much to know about what error is. From my point of view we can close this issue as I am resizing the image to lower values before I`m doing the conversion stuff, 30k is to much..