Hello,
I am experiencing an issue while porting a Python application to C++ because erode
gives slightly different results on the very same input.
For example, on this image taken from Google (for your convenience, already converted to jpg):
https://transfer.sh/n3BPNQPpPg/gatto.jpg
I have checked all the intermediate values that ultimately gets into erode
and they are all the same (an accurate check is performed by comparing pixels one by one).
It seems the problem is at the boundaries, as you can see by comparing the two output images (cpp vs py):
I do some pre-processing that is needed for my use case. The repro snippets are here below.
Python:
import sys
import cv2
crop_perc = 0.1
image_path = "cat.jpg"
img = cv2.imread(image_path, cv2.IMREAD_COLOR)
orig_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(orig_gray, 5)
thresholded = 255 - cv2.adaptiveThreshold(
gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 33, 4
)
thresholded = thresholded[
int(thresholded.shape[0] * crop_perc) : int(thresholded.shape[0] * (1 - crop_perc)),
:,
]
erosion_size = 3
element = cv2.getStructuringElement(
cv2.MORPH_ELLIPSE,
(1 * erosion_size + 1, 2 * erosion_size + 1),
(erosion_size, erosion_size),
)
thresholded_morph = cv2.erode(thresholded, element)
cv2.imshow("thresholded_morph", thresholded_morph)
cv2.waitKey(0)
cv2.imwrite("thresholded_morph_py.png", thresholded_morph)
And C++:
auto img = cv::imread("cat.jpg");
cv::Mat gray, original_gray;
cvtColor(img, original_gray, cv::COLOR_BGR2GRAY);
medianBlur(original_gray, gray, 5);
cv::Mat thresholded;
adaptiveThreshold(gray, thresholded, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 33, 4);
thresholded = 255 - thresholded;
const auto crop_perc = 0.1;
thresholded = thresholded(cv::Range(static_cast<int>(thresholded.size[0] * crop_perc), static_cast<int>(thresholded.size[0] * (1 - crop_perc))), cv::Range::all());
const auto erosion_size = 3;
const auto element = getStructuringElement(cv::MORPH_ELLIPSE, { 1 * erosion_size + 1, 2 * erosion_size + 1 }, { erosion_size, erosion_size });
cv::Mat thresholded_morph;
erode(thresholded, thresholded_morph, element);
imwrite("thresholded_morph_cpp.png", thresholded_morph);
Do you have any ideas what is causing the issue? Clearly, I am using the very same version of OpenCV for both Python and C++.
Also, it seems the error is portable to other platforms (e.g. MacOS).
Many thanks,
Marco