opencv-python icon indicating copy to clipboard operation
opencv-python copied to clipboard

Alternative to cv2.warpPerspective

Open FiReTiTi opened this issue 2 years ago • 8 comments

Expected behaviour

I use OpenCV to register bio-medical images, but these images are really big.

I'm able to extract features and compute the homography H, and then I use cv2.warpPerspective to compute the final image.

warped_img = cv2.warpPerspective(image, H, (width, height), borderMode=cv2.BORDER_CONSTANT, borderValue=0)

Actual behaviour

But when width or height is bigger than 32767, then I get the following error.

cv2.error: OpenCV(4.5.1) /tmp/pip-req-build-s8zh4qlk/opencv/modules/imgproc/src/imgwarp.cpp:1724: error: (-215:Assertion failed) dst.cols < SHRT_MAX && dst.rows < SHRT_MAX && src.cols < SHRT_MAX && src.rows < SHRT_MAX in function 'remap'

I took a look online, and I found out that is a hard limitation because of the short encoding used to improve warpPerspective .

Is there a workaround to lift such limitation? If no, is there a solution using another library to replace cv2.warpPerspective?

FiReTiTi avatar Sep 29 '21 08:09 FiReTiTi

@FiReTiTi Thanks for the report. The issue is mostly related to cv::remap, because it uses 16-bit indexing in public interface. I need to check if there are options for warping, as it does not expose indexing externally. The issue itself is not related to OpenCV-Python bindings, but general OpenCV issue. It's more efficient to file such bugs to core repository https://github.com/opencv/opencv/

asmorkalov avatar Sep 29 '21 14:09 asmorkalov

Possibly related: https://github.com/opencv/opencv/issues/7544

asmorkalov avatar Sep 29 '21 14:09 asmorkalov

OpenCV uses cv::remap to handle "tails" if the image size is not multiplier of block size 16. For core details see https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.cpp#L3046. As work around you can try to align all image sizes to it.

asmorkalov avatar Sep 29 '21 14:09 asmorkalov

Mmm... I'm a little bit confused. In the first link below they talk about replacing short by int which should fix the issue.

[https://github.com/opencv/opencv/pull/7555]

But few days later they add an assertion in the code.

Possibly related: opencv/opencv#7544

FiReTiTi avatar Sep 29 '21 17:09 FiReTiTi

The assertion is done to make the remap issue obvious for developers. It's better than just crash or messy result.

asmorkalov avatar Sep 30 '21 04:09 asmorkalov

I found a workaround using skimage. I posted the answer here.

FiReTiTi avatar Sep 30 '21 17:09 FiReTiTi

OpenCV uses cv::remap to handle "tails" if the image size is not multiplier of block size 16. For core details see https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.cpp#L3046. As work around you can try to align all image sizes to it.

remap is not the only problem, short is used to compute indices: https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.cpp#L2962 https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.cpp#L2987

also SIMD/SSE4 functions use short: https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.cpp#L2691 https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.cpp#L2810 https://github.com/opencv/opencv/blob/c1148c4ea6c800730e1bb31fa3032f3fbe4c8c4a/modules/imgproc/src/imgwarp.sse4_1.cpp#L219

there may be more functions which use short

Also OpenCV uses cv::remap to handle whole image (not just the tails). To add support large image need to fix remap also.

AleksandrPanov avatar Oct 08 '21 16:10 AleksandrPanov

https://github.com/opencv/opencv/pull/20949

asmorkalov avatar Dec 07 '21 07:12 asmorkalov