-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
OpenCL: resizeLN (without INTER_LINEAR_INTEGER) gives invalid results for CV_16U #21198
Description
System information (version)
- OpenCV => Tested on 4.5.4. Relevant source code has not changed since 3.x.
- Operating System / Platform => Tested on Windows (AMD OpenCL, NVIDIA OpenCL) and Mac (Intel OpenCL)
Detailed description
For CV_16U depth, if the resizeLN OpenCL kernel is compiled without INTER_LINEAR_INTEGER, it gives invalid results. The resized image is either all dark or has dark regions that look somewhat like integer overflow.
Note that as of OpenCV 4.5.4, resizeLN is always compiled without INTER_LINEAR_INTEGER because the INTER_LINEAR_INTEGER path is disabled in the following line:
opencv/modules/imgproc/src/resize.cpp
Lines 3322 to 3323 in 4223495
| // integer path is slower because of CPU part, so it's disabled | |
| if (depth == CV_8U && ((void)0, 0)) |
Thus, OpenCV 4.5.4 does exercise the broken code path.
Steps to reproduce
As of OpenCV 4.5.4, the broken code path is exercised under the following circumstances:
- OpenCL optimizations are enabled.
- The
resizeis called on aUMatsource image that meets the following criteria:
- The depth is
CV_16U - The row pitch is not a multiple of the OpenCL device's
CL_DEVICE_IMAGE_PITCH_ALIGNMENTproperty (because in this narrow case,ocl_resizeselects theresizeSamplerkernel instead)
The following Python script can be used to test various cases of resize:
import cv2
import numpy
def main():
read_flags = cv2.IMREAD_COLOR
method = cv2.INTER_LINEAR
src_size = (600, 600)
dst_size = (1024, 1024)
mat_8u = cv2.imread('Lena.png', read_flags)
mat_8u = cv2.resize(mat_8u, src_size, interpolation=method)
mat_8s = (mat_8u / 2).astype(numpy.int8)
mat_16s = mat_8u.astype(numpy.int16)
mat_16u = mat_8u.astype(numpy.uint16) * 256
mat_32s = mat_8u.astype(numpy.int32)
umat_8s = cv2.UMat(mat_8s)
umat_8u = cv2.UMat(mat_8u)
umat_16s = cv2.UMat(mat_16s)
umat_16u = cv2.UMat(mat_16u)
umat_32s = cv2.UMat(mat_32s)
mat_8u_resized = cv2.resize(mat_8u, dst_size, interpolation=method)
#mat_8s_resized = cv2.resize(mat_8s, dst_size, interpolation=method)
mat_16s_resized = cv2.resize(mat_16s, dst_size, interpolation=method)
mat_16u_resized = cv2.resize(mat_16u, dst_size, interpolation=method)
#mat_32s_resized = cv2.resize(mat_32s, dst_size, interpolation=method)
umat_8u_resized = cv2.resize(umat_8u, dst_size, interpolation=method)
umat_8s_resized = cv2.resize(umat_8s, dst_size, interpolation=method)
umat_16s_resized = cv2.resize(umat_16s, dst_size, interpolation=method)
umat_16u_resized = cv2.resize(umat_16u, dst_size, interpolation=method)
umat_32s_resized = cv2.resize(umat_32s, dst_size, interpolation=method)
cv2.imwrite('mat_8u_resized.png', mat_8u_resized)
#cv2.imwrite('mat_8s_resized.png', mat_8s_resized)
cv2.imwrite('mat_16s_resized.png', mat_16s_resized)
cv2.imwrite('mat_16u_resized.png', mat_16u_resized)
#cv2.imwrite('mat_32s_resized.png', mat_32s_resized)
cv2.imwrite('umat_8u_resized.png', umat_8u_resized)
cv2.imwrite('umat_8s_resized.png', umat_8s_resized)
cv2.imwrite('umat_16s_resized.png', umat_16s_resized)
cv2.imwrite('umat_16u_resized.png', umat_16u_resized)
cv2.imwrite('umat_32s_resized.png', umat_32s_resized)
if __name__ == '__main__':
main()
Sample input image:
Sample output image (good) from Mat, CV_16U:
Sample output image (bad) from UMat, CV_16U:
Issue submission checklist
- I report the issue, it's not a question
- I checked the problem with documentation, FAQ, open issues,
forum.opencv.org, Stack Overflow, etc and have not found solution - I updated to latest OpenCV version and the issue is still there
- There is reproducer code and related data files: videos, images, onnx, etc


