1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge pull request #25792 from asmorkalov:as/HAL_fast_GaussianBlur

Added flag to GaussianBlur for faster but not bit-exact implementation #25792

Rationale:
Current implementation of GaussianBlur is almost always bit-exact. It helps to get predictable results according platforms, but prohibits most of approximations and optimization tricks.

The patch converts `borderType` parameter to more generic `flags` and introduces `GAUSS_ALLOW_APPROXIMATIONS` flag to allow not bit-exact implementation. With the flag IPP and generic HAL implementation are called first. The flag naming and location is a subject for discussion.

Replaces https://github.com/opencv/opencv/pull/22073
Possibly related issue: https://github.com/opencv/opencv/issues/24135

### 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
- [ ] 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.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Alexander Smorkalov
2024-07-12 15:03:33 +03:00
committed by GitHub
parent 3ff97c5580
commit 15783d6598
10 changed files with 143 additions and 12 deletions
+55 -1
View File
@@ -244,7 +244,7 @@ static void checkGaussianBlur_8Uvs32F(const Mat& src8u, const Mat& src32f, int N
TEST(GaussianBlur_Bitexact, regression_9863)
{
Mat src8u = imread(cvtest::findDataFile("shared/lena.png"));
Mat src32f; src8u.convertTo(src32f, CV_32F);
Mat src32f; src8u.convertTo(src32f, CV_32F);
checkGaussianBlur_8Uvs32F(src8u, src32f, 151, 30);
}
@@ -260,4 +260,58 @@ TEST(GaussianBlur_Bitexact, overflow_20792)
EXPECT_GT(count, nintyPercent);
}
CV_ENUM(GaussInputType, CV_8U, CV_16S);
CV_ENUM(GaussBorder, BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT_101);
struct GaussianBlurVsBitexact: public testing::TestWithParam<tuple<GaussInputType, int, double, GaussBorder>>
{
virtual void SetUp()
{
orig = imread(findDataFile("shared/lena.png"));
EXPECT_FALSE(orig.empty()) << "Cannot find test image shared/lena.png";
}
Mat orig;
};
// NOTE: The test was designed for IPP (-DOPENCV_IPP_GAUSSIAN_BLUR=ON)
// Should be extended after new HAL integration
TEST_P(GaussianBlurVsBitexact, approx)
{
auto testParams = GetParam();
int dtype = get<0>(testParams);
int ksize = get<1>(testParams);
double sigma = get<2>(testParams);
int border = get<3>(testParams);
Mat src;
orig.convertTo(src, dtype);
cv::Mat gt;
GaussianBlur(src, gt, Size(ksize, ksize), sigma, sigma, border, ALGO_ACCURATE);
cv::Mat dst;
GaussianBlur(src, dst, Size(ksize, ksize), sigma, sigma, border, ALGO_APPROX);
cv::Mat diff;
cv::absdiff(dst, gt, diff);
cv::Mat flatten_diff = diff.reshape(1, diff.rows);
int nz = countNonZero(flatten_diff);
EXPECT_LE(nz, 0.06*src.total()); // Less 6% of different pixels
double min_val, max_val;
minMaxLoc(flatten_diff, &min_val, &max_val);
EXPECT_LE(max_val, 2); // expectes results floating +-1
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, GaussianBlurVsBitexact,
testing::Combine(
GaussInputType::all(),
testing::Values(3, 5, 7),
testing::Values(0.75, 1.25),
GaussBorder::all()
)
);
}} // namespace