diff --git a/modules/cudawarping/test/test_resize.cpp b/modules/cudawarping/test/test_resize.cpp index 768ad09f982..a2b2f714533 100644 --- a/modules/cudawarping/test/test_resize.cpp +++ b/modules/cudawarping/test/test_resize.cpp @@ -261,5 +261,59 @@ INSTANTIATE_TEST_CASE_P(CUDA_Warping, ResizeTextures, testing::Combine( testing::Values(Interpolation(cv::INTER_NEAREST), Interpolation(cv::INTER_LINEAR), Interpolation(cv::INTER_CUBIC)))); + +// Test for issue #28407: cv::cuda::resize fails with continuous GpuMat +PARAM_TEST_CASE(ResizeContinuous, cv::cuda::DeviceInfo, cv::Size, MatType, Interpolation) +{ + cv::cuda::DeviceInfo devInfo; + cv::Size size; + int type; + int interpolation; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + size = GET_PARAM(1); + type = GET_PARAM(2); + interpolation = GET_PARAM(3); + + cv::cuda::setDevice(devInfo.deviceID()); + } +}; + +CUDA_TEST_P(ResizeContinuous, Regression_Issue28407) +{ + // Test both regular and continuous GpuMat + cv::Mat src = randomMat(size, type); + + // Test 1: Regular GpuMat (should work) + cv::cuda::GpuMat d_src_regular(src); + cv::cuda::GpuMat d_dst_regular; + EXPECT_NO_THROW( + cv::cuda::resize(d_src_regular, d_dst_regular, cv::Size(size.width * 2, size.height * 2), 0, 0, interpolation) + ); + + // Test 2: Continuous GpuMat (this is the bug - should work but currently fails) + cv::cuda::GpuMat d_src_continuous = cv::cuda::createContinuous(size.height, size.width, type); + d_src_continuous.upload(src); + cv::cuda::GpuMat d_dst_continuous; + EXPECT_NO_THROW( + cv::cuda::resize(d_src_continuous, d_dst_continuous, cv::Size(size.width * 2, size.height * 2), 0, 0, interpolation) + ); + + // Verify both produce the same result + cv::Mat h_dst_regular, h_dst_continuous; + d_dst_regular.download(h_dst_regular); + d_dst_continuous.download(h_dst_continuous); + + EXPECT_MAT_NEAR(h_dst_regular, h_dst_continuous, 0.0); +} + +INSTANTIATE_TEST_CASE_P(CUDA_Warping, ResizeContinuous, testing::Combine( + ALL_DEVICES, + testing::Values(cv::Size(10, 10), cv::Size(64, 64), cv::Size(128, 128)), + testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_32FC1)), + testing::Values(Interpolation(cv::INTER_NEAREST), Interpolation(cv::INTER_LINEAR), Interpolation(cv::INTER_CUBIC)))); + }} // namespace #endif // HAVE_CUDA diff --git a/modules/cudev/include/opencv2/cudev/ptr2d/texture.hpp b/modules/cudev/include/opencv2/cudev/ptr2d/texture.hpp index 4111c41d2f2..097e29ba918 100644 --- a/modules/cudev/include/opencv2/cudev/ptr2d/texture.hpp +++ b/modules/cudev/include/opencv2/cudev/ptr2d/texture.hpp @@ -175,8 +175,11 @@ namespace cv { namespace cudev { texRes.resType = cudaResourceTypePitch2D; texRes.res.pitch2D.height = rows; texRes.res.pitch2D.width = cols; - // temporary fix for single row/columns until TexturePtr is reworked - if (rows == 1 || cols == 1) { + const size_t minPitch = cols * sizeof(T1); + const size_t alignment = 32; + const bool isPitchAligned = (step % alignment == 0); + const bool needsReallocation = (rows == 1) || (cols == 1) || (step < minPitch) || (!isPitchAligned); + if (needsReallocation) { size_t dStep = 0; CV_CUDEV_SAFE_CALL(cudaMallocPitch(&internalSrc, &dStep, cols * sizeof(T1), rows)); CV_CUDEV_SAFE_CALL(cudaMemcpy2D(internalSrc, dStep, data, step, cols * sizeof(T1), rows, cudaMemcpyDeviceToDevice)); diff --git a/modules/face/src/getlandmarks.cpp b/modules/face/src/getlandmarks.cpp index 9a416197273..3f54ac230fa 100644 --- a/modules/face/src/getlandmarks.cpp +++ b/modules/face/src/getlandmarks.cpp @@ -154,6 +154,9 @@ void FacemarkKazemiImpl :: loadModel(String filename){ vector leaf; readLeaf(f,leaf); node.leaf = leaf; + node.split.index1 = 0; + node.split.index2 = 0; + node.split.thresh = 0.f; } else{ String error_message = "Data not saved properly.Aborting....."; diff --git a/modules/julia/gen/funclist.csv b/modules/julia/gen/funclist.csv index 88ec6e0a4be..e9ed6abec26 100644 --- a/modules/julia/gen/funclist.csv +++ b/modules/julia/gen/funclist.csv @@ -224,6 +224,7 @@ cv.calcBackProject cv.compareHist cv.equalizeHist cv.createCLAHE +cv.CLAHE.apply cv.wrapperEMD cv.watershed cv.pyrMeanShiftFiltering diff --git a/modules/julia/test/test_imgproc.jl b/modules/julia/test/test_imgproc.jl index 353232d95a1..a8186b49e79 100644 --- a/modules/julia/test/test_imgproc.jl +++ b/modules/julia/test/test_imgproc.jl @@ -23,6 +23,11 @@ ve_gray = OpenCV.cvtColor(ve, OpenCV.COLOR_RGB2GRAY) # Shape check @test size(ve_gray)[1] == 1 && size(img_gray)[1] == 1 +clahe_img = rand(UInt8, 1, 64, 64) +clahe = OpenCV.createCLAHE() +clahe_result = OpenCV.apply(clahe, clahe_img) +@test size(clahe_result) == size(clahe_img) +@test eltype(clahe_result) == UInt8 print("imgproc test passed\n")