mirror of
https://github.com/opencv/opencv.git
synced 2024-11-27 20:50:25 +08:00
Merge pull request #25413 from Linaname:#25404
Correct inpainting floating point values with Telea's algorithm
This commit is contained in:
commit
66fb5021e9
@ -46,6 +46,7 @@
|
||||
// */
|
||||
|
||||
#include <queue>
|
||||
#include <type_traits>
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
@ -55,6 +56,16 @@
|
||||
#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \
|
||||
((mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))
|
||||
|
||||
template<typename T>
|
||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type round_cast(float val) {
|
||||
return cv::saturate_cast<T>(val);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename std::enable_if<!std::is_floating_point<T>::value, T>::type round_cast(float val) {
|
||||
return cv::saturate_cast<T>(val + 0.5);
|
||||
}
|
||||
|
||||
inline float
|
||||
min4( float a, float b, float c, float d )
|
||||
{
|
||||
@ -339,8 +350,8 @@ icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQu
|
||||
}
|
||||
}
|
||||
for (color=0; color<=2; color++) {
|
||||
sat = (float)((Ia[color]/s[color]+(Jx[color]+Jy[color])/(sqrt(Jx[color]*Jx[color]+Jy[color]*Jy[color])+1.0e-20f)+0.5f));
|
||||
CV_MAT_3COLOR_ELEM(*out,uchar,i-1,j-1,color) = cv::saturate_cast<uchar>(sat);
|
||||
sat = (float)(Ia[color]/s[color]+(Jx[color]+Jy[color])/(sqrt(Jx[color]*Jx[color]+Jy[color]*Jy[color])+1.0e-20f));
|
||||
CV_MAT_3COLOR_ELEM(*out,uchar,i-1,j-1,color) = round_cast<uchar>(sat);
|
||||
}
|
||||
|
||||
CV_MAT_ELEM(*f,uchar,i,j) = BAND;
|
||||
@ -449,9 +460,9 @@ icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQu
|
||||
}
|
||||
}
|
||||
}
|
||||
sat = (float)((Ia/s+(Jx+Jy)/(sqrt(Jx*Jx+Jy*Jy)+1.0e-20f)+0.5f));
|
||||
sat = (float)(Ia/s+(Jx+Jy)/(sqrt(Jx*Jx+Jy*Jy)+1.0e-20f));
|
||||
{
|
||||
CV_MAT_ELEM(*out,data_type,i-1,j-1) = cv::saturate_cast<data_type>(sat);
|
||||
CV_MAT_ELEM(*out,data_type,i-1,j-1) = round_cast<data_type>(sat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,9 +116,9 @@ void CV_InpaintTest::run( int )
|
||||
|
||||
TEST(Photo_Inpaint, regression) { CV_InpaintTest test; test.safe_run(); }
|
||||
|
||||
typedef testing::TestWithParam<tuple<int> > formats;
|
||||
typedef testing::TestWithParam<tuple<perf::MatType> > formats;
|
||||
|
||||
TEST_P(formats, 1c)
|
||||
TEST_P(formats, basic)
|
||||
{
|
||||
const int type = get<0>(GetParam());
|
||||
Mat src(100, 100, type);
|
||||
@ -126,18 +126,18 @@ TEST_P(formats, 1c)
|
||||
Mat ref = src.clone();
|
||||
Mat dst, mask = Mat::zeros(src.size(), CV_8U);
|
||||
|
||||
circle(src, Point(50, 50), 5, Scalar(200), 6);
|
||||
circle(mask, Point(50, 50), 5, Scalar(200), 6);
|
||||
circle(src, Point(50, 50), 5, Scalar::all(200), 6);
|
||||
circle(mask, Point(50, 50), 5, Scalar::all(200), 6);
|
||||
inpaint(src, mask, dst, 10, INPAINT_NS);
|
||||
|
||||
Mat dst2;
|
||||
inpaint(src, mask, dst2, 10, INPAINT_TELEA);
|
||||
|
||||
ASSERT_LE(cv::norm(dst, ref, NORM_INF), 3.);
|
||||
ASSERT_LE(cv::norm(dst2, ref, NORM_INF), 3.);
|
||||
ASSERT_EQ(cv::norm(dst, ref, NORM_INF), 0.);
|
||||
ASSERT_EQ(cv::norm(dst2, ref, NORM_INF), 0.);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Photo_Inpaint, formats, testing::Values(CV_32F, CV_16U, CV_8U));
|
||||
INSTANTIATE_TEST_CASE_P(Photo_Inpaint, formats, testing::Values(CV_32FC1, CV_16UC1, CV_8UC1, CV_8UC3));
|
||||
|
||||
TEST(Photo_InpaintBorders, regression)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user