-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Description
System Information
OpenCV version: 4.9.0
Operating System / Platform: Windows 10
Compiler & compiler version: MSVC 19.29.30148
Detailed description
Adapting the unit test from here (thanks, @asmorkalov!) to CV_32F data, inpainting a cv::Mat that has the same float value (128.0) on each known (= not to be inpainted) element does not yield the expected result with Telea's algorithm.
The Navier Stokes method gives the expected result.
Image:
128.00, 128.00, 128.00, 128.00, 128.00,
128.00, 0, 0, 0, 128.00,
128.00, 0, 0, 0, 128.00,
128.00, 0, 0, 0, 128.00,
128.00, 128.00, 128.00, 128.00, 128.00
Mask:
0, 0, 0, 0, 0,
0, 255, 255, 255, 0,
0, 255, 255, 255, 0,
0, 255, 255, 255, 0,
0, 0, 0, 0, 0
Expected/Navier Stokes:
128.00, 128.00, 128.00, 128.00, 128.00,
128.00, 128.00, 128.00, 128.00, 128.00,
128.00, 128.00, 128.00, 128.00, 128.00,
128.00, 128.00, 128.00, 128.00, 128.00,
128.00, 128.00, 128.00, 128.00, 128.00
Telea:
128.00, 128.00, 128.00, 128.00, 128.00,
128.00, 129.50, 128.78, 130.18, 128.00,
128.00, 128.78, 127.55, 128.14, 128.00,
128.00, 130.18, 127.50, 129.55, 128.00,
128.00, 128.00, 128.00, 128.00, 128.00
I could not determine if this is an artifact produced by Telea's algorithm itself or a erroneous implementation in OpenCV.
An indication for an error is the lack of rotational symmetry, which I would expect from a general purpose algorithm.
Steps to reproduce
Since the Issue with top and left borders being not inpainted correctly is not yet fixed, a workaround is added. The calls to inpaint_25389_workaround can be replaced with cv::inpaint once the fix is through.
// Workaround for https://github.com/opencv/opencv/issues/25389
void inpaint_25389_workaround(cv::Mat const& src, cv::Mat const& mask, cv::Mat& dst, double inpaint_radius, int flags) {
cv::Mat bordered_src, bordered_mask;
cv::copyMakeBorder(src, bordered_src, 1, 0, 1, 0, cv::BORDER_CONSTANT, 0);
cv::copyMakeBorder(mask, bordered_mask, 1, 0, 1, 0, cv::BORDER_CONSTANT, 1);
cv::inpaint(bordered_src, bordered_mask, dst, inpaint_radius, flags);
dst = dst(cv::Rect(1, 1, dst.cols - 1, dst.rows - 1));
}
TEST(Photo_InpaintSmallBorders32F, regression)
{
cv::Mat img(5, 5, CV_32F);
img = 128.f;
img(cv::Rect(1, 1, 3, 3)) = 0;
cv::Mat mask(5, 5, CV_8U);
mask = 0;
mask(cv::Rect(1, 1, 3, 3)) = 255;
cv::Mat expected(5, 5, img.type());
expected = 128.f;
cv::Mat inpainted, diff;
inpaint_25389_workaround(img, mask, inpainted, 1, cv::INPAINT_NS);
cv::absdiff(inpainted, expected, diff);
ASSERT_EQ(countNonZero(diff), 0);
inpaint_25389_workaround(img, mask, inpainted, 1, cv::INPAINT_TELEA);
cv::absdiff(inpainted, expected, diff);
ASSERT_EQ(countNonZero(diff), 0);
}Issue submission checklist
- I report the issue, it's not a question
- I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- I updated to the latest OpenCV version and the issue is still there
- There is reproducer code and related data files (videos, images, onnx, etc)