opencv / opencv

Open Source Computer Vision Library
https://opencv.org
Apache License 2.0
75.95k stars 55.62k forks source link

GaussianBlur different results between c++ and python #25516

Closed jbyuki closed 2 weeks ago

jbyuki commented 2 weeks ago

System Information

OpenCV python version: 4.9.0 Operating System / Platform: Ubuntu 22.04 Python version: 3.11.5

OpenCV c++ version: 4.9.0 Operating System / Platform: Ubuntu 22.04 Compiler & compiler version: GCC 11.3.0

Detailed description

The results of cv.GaussianBlur (python) and cv::GaussianBlur (cpp) on the exact same cv::Mat does not reproduce the same results. Interestingly, using cv.getGaussianKernel and cv.sepFilter2D does produce the same results.

From what I can observe, cv.GaussianBlur (python) does give slightly off results. This has consequences on all algorithms using it, which is most likely a lot as it is often used as a preprocessing step.

Steps to reproduce

In c++:

cv::Mat img; // has type cv::CV_32F
cv::Mat blurred;
cv::GaussianBlur(img, blurred, cv::Size(9,9), 1.5, 1.5, cv::BORDER_REPLICATE);

In python:

# img is a numpy array of np.float32
blurred = cv.GaussianBlur(img, (9, 9), sigmaX=1.5, sigmaY=1.5, borderType=cv.BORDER_REPLICATE)

The workaround for python is to use:

# img is a numpy array of np.float32
Kx = cv.getGaussianKernel(9, 1.5)
Ky = cv.getGaussianKernel(9, 1.5)
blurred  = cv.sepFilter2D(img, cv.CV_32F, Kx, Ky, borderType=cv.BORDER_REPLICATE)

Issue submission checklist

LaurentBerger commented 2 weeks ago
# img is a numpy array of np.float32
blurred = cv.GaussianBlur(img, (9, 9), 1.5, 1.5, cv.BORDER_REPLICATE)``

please can you use name parameter?

jbyuki commented 2 weeks ago

Apologies, this is a wrong diagnostic on my part. The discrepency actually came from another part of the code. I thought

cv::Mat gray = cv::imread("image.png", cv::IMREAD_GRAYSCALE);

and

cv::Mat img = cv::imread("image.png");
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

would give the same grayscale image but apparently not. This is most likely just a subtility and not a bug.