opencv-python
opencv-python copied to clipboard
Alternative to cv2.warpPerspective
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 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/
Possibly related: https://github.com/opencv/opencv/issues/7544
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.
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
The assertion is done to make the remap issue obvious for developers. It's better than just crash or messy result.
I found a workaround using skimage
. I posted the answer here.
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.
https://github.com/opencv/opencv/pull/20949