opencv / opencv

Open Source Computer Vision Library
https://opencv.org
Apache License 2.0
78.83k stars 55.8k forks source link

Edge case in resize.cpp (support 8S / 32S) #20991

Open mister-drgn opened 2 years ago

mister-drgn commented 2 years ago
Detailed description

There is an issue with resizing images of depth CV_8S or CV_32S. The default interpolation method, INTER_LINEAR, does not work with matrices of these types. You can instead use INTER_LINEAR_EXACT. However, if you are resizing an image to exactly half of its former size, and your stated method is INTER_LINEAR_EXACT, then the code in resize.cpp changes the method to INTER_AREA, which again does not work for matrices of these types, causing an error.

Steps to reproduce

Mat img = new Mat(10, 10, CvType.CV_8SC1); Mat resizeimage = new Mat(); Size sz = new Size(5, 5); Imgproc.resize(img, resizeimage, sz, 0, 0, Imgproc.INTER_LINEAR_EXACT);

alalek commented 2 years ago

see here: #7862

Consider using conversion to CV_32F for such rare cases.

mister-drgn commented 2 years ago

I can easily fix the problem I personally ran into. My hope is to help other people with this issue. I was having trouble replicating the behavior in a colleague's code because we did not realize Imgproc.resize(img, resizeimage, sz, 0, 0, Imgproc.INTER_LINEAR_EXACT); would work most of the time, but fail when the new size is exactly half of the old size. The rareness of this edge case is was makes it so tricky when one runs into it.

emmenlau commented 1 year ago

Could this kindly be fixed in opencv? Users really do not know about such corner cases and can not maintain workaround code.