Merge pull request #25898 from Octopus136:issue-25853

Add a check for src == dst in ocl warpTransform #25898

As mentioned in #25853, when doing WarpAffine with Mat and UMat respectively, if you force the use of the in-place operation (so that src and dst are passed the same variables), Mat produces the correct results, but UMat produces unexpected results.

Obviously in-place operations are not possible with this transformation. When Mat performs the operation, if dst and src are the same variable, the function inherently makes a copy of src without telling the user. 

74b50c7af0/modules/imgproc/src/imgwarp.cpp (L2831-L2834)

So I did the same check in UMat, but I'm not sure if it's appropriate, should we just do a copy operation without telling the user (even if the user thinks he's doing an in-place operation), or should we throw an exception to indicate that we shouldn't pass in two same variables here?

The possible reason for this problem is that there is a create function here, so it gives the developer the false impression that this create function has allocated new memory for dst, however it does not.

74b50c7af0/modules/imgproc/src/imgwarp.cpp (L2607-L2609)

Because by the time the check is done here, the function has returned back.

74b50c7af0/modules/core/src/umatrix.cpp (L668-L675)

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
_Ayaka 2024-07-19 14:08:19 +08:00 committed by GitHub
parent d892c7b142
commit 4dd54bbec9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 0 deletions

View File

@ -2501,6 +2501,9 @@ static bool ocl_warpTransform_cols4(InputArray _src, OutputArray _dst, InputArra
_dst.create( dsize.empty() ? src.size() : dsize, src.type() );
UMat dst = _dst.getUMat();
if (src.u == dst.u)
src = src.clone();
float M[9] = {0};
int matRows = (op_type == OCL_OP_AFFINE ? 2 : 3);
Mat matM(matRows, 3, CV_32F, M), M1 = _M0.getMat();
@ -2605,6 +2608,9 @@ static bool ocl_warpTransform(InputArray _src, OutputArray _dst, InputArray _M0,
_dst.create( dsize.empty() ? src.size() : dsize, src.type() );
UMat dst = _dst.getUMat();
if (src.u == dst.u)
src = src.clone();
double M[9] = {0};
int matRows = (op_type == OCL_OP_AFFINE ? 2 : 3);
Mat matM(matRows, 3, CV_64F, M), M1 = _M0.getMat();

View File

@ -185,6 +185,26 @@ OCL_TEST_P(WarpAffine, Mat)
}
}
OCL_TEST_P(WarpAffine, inplace_25853) // when src and dst are the same variable, ocl on/off should produce consistent and correct results
{
for (int j = 0; j < test_loop_times; j++)
{
double eps = depth < CV_32F ? 0.04 : 0.06;
random_roi();
Mat M = getRotationMatrix2D(Point2f(src_roi.cols / 2.0f, src_roi.rows / 2.0f),
rng.uniform(-180.f, 180.f), rng.uniform(0.4f, 2.0f));
OCL_OFF(cv::warpAffine(src_roi, src_roi, M, dsize, interpolation));
OCL_ON(cv::warpAffine(usrc_roi, usrc_roi, M, dsize, interpolation));
dst_roi = src_roi.clone();
udst_roi = usrc_roi.clone();
Near(eps);
}
}
typedef WarpTest_cols4_Base WarpAffine_cols4;
OCL_TEST_P(WarpAffine_cols4, Mat)