mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -920,20 +920,23 @@ static inline void interpolateLanczos4( float x, float* coeffs )
|
||||
static const double cs[][2]=
|
||||
{{1, 0}, {-s45, -s45}, {0, 1}, {s45, -s45}, {-1, 0}, {s45, s45}, {0, -1}, {-s45, s45}};
|
||||
|
||||
if( x < FLT_EPSILON )
|
||||
{
|
||||
for( int i = 0; i < 8; i++ )
|
||||
coeffs[i] = 0;
|
||||
coeffs[3] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
float sum = 0;
|
||||
double y0=-(x+3)*CV_PI*0.25, s0 = std::sin(y0), c0= std::cos(y0);
|
||||
for(int i = 0; i < 8; i++ )
|
||||
{
|
||||
double y = -(x+3-i)*CV_PI*0.25;
|
||||
coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y));
|
||||
float y0_ = (x+3-i);
|
||||
if (fabs(y0_) >= 1e-6f)
|
||||
{
|
||||
double y = -y0_*CV_PI*0.25;
|
||||
coeffs[i] = (float)((cs[i][0]*s0 + cs[i][1]*c0)/(y*y));
|
||||
}
|
||||
else
|
||||
{
|
||||
// special handling for 'x' values:
|
||||
// - ~0.0: 0 0 0 1 0 0 0 0
|
||||
// - ~1.0: 0 0 0 0 1 0 0 0
|
||||
coeffs[i] = 1e30f;
|
||||
}
|
||||
sum += coeffs[i];
|
||||
}
|
||||
|
||||
@@ -1605,13 +1608,14 @@ struct HResizeLinearVecU8_X4
|
||||
|
||||
for( dx = 0; dx < len0; dx += step )
|
||||
{
|
||||
int ofs[4] = { xofs[dx], xofs[dx + 2], xofs[dx + 4], xofs[dx + 6] };
|
||||
v_int16x8 al = v_load(alpha+dx*2);
|
||||
v_int16x8 ah = v_load(alpha+dx*2+8);
|
||||
v_uint16x8 sl, sh;
|
||||
v_expand(v_interleave_pairs(v_lut_quads(S0, xofs+dx)), sl, sh);
|
||||
v_expand(v_interleave_pairs(v_lut_quads(S0, ofs)), sl, sh);
|
||||
v_store(&D0[dx], v_dotprod(v_reinterpret_as_s16(sl), al));
|
||||
v_store(&D0[dx+4], v_dotprod(v_reinterpret_as_s16(sh), ah));
|
||||
v_expand(v_interleave_pairs(v_lut_pairs(S1, xofs+dx)), sl, sh);
|
||||
v_expand(v_interleave_pairs(v_lut_quads(S1, ofs)), sl, sh);
|
||||
v_store(&D1[dx], v_dotprod(v_reinterpret_as_s16(sl), al));
|
||||
v_store(&D1[dx+4], v_dotprod(v_reinterpret_as_s16(sh), ah));
|
||||
}
|
||||
@@ -1622,10 +1626,11 @@ struct HResizeLinearVecU8_X4
|
||||
int *D = dst[k];
|
||||
for( dx = 0; dx < len0; dx += step )
|
||||
{
|
||||
int ofs[4] = { xofs[dx], xofs[dx + 2], xofs[dx + 4], xofs[dx + 6] };
|
||||
v_int16x8 al = v_load(alpha+dx*2);
|
||||
v_int16x8 ah = v_load(alpha+dx*2+8);
|
||||
v_uint16x8 sl, sh;
|
||||
v_expand(v_interleave_pairs(v_lut_quads(S, xofs+dx)), sl, sh);
|
||||
v_expand(v_interleave_pairs(v_lut_quads(S, ofs)), sl, sh);
|
||||
v_store(&D[dx], v_dotprod(v_reinterpret_as_s16(sl), al));
|
||||
v_store(&D[dx+4], v_dotprod(v_reinterpret_as_s16(sh), ah));
|
||||
}
|
||||
|
||||
@@ -60,6 +60,29 @@ static void findCircle3pts(Point2f *pts, Point2f ¢er, float &radius)
|
||||
Point2f midPoint2 = (pts[0] + pts[2]) / 2.0f;
|
||||
float c2 = midPoint2.x * v2.x + midPoint2.y * v2.y;
|
||||
float det = v1.x * v2.y - v1.y * v2.x;
|
||||
if (fabs(det) <= EPS)
|
||||
{
|
||||
// v1 and v2 are colinear, so the longest distance between any 2 points
|
||||
// is the diameter of the minimum enclosing circle.
|
||||
float d1 = normL2Sqr<float>(pts[0] - pts[1]);
|
||||
float d2 = normL2Sqr<float>(pts[0] - pts[2]);
|
||||
float d3 = normL2Sqr<float>(pts[1] - pts[2]);
|
||||
radius = sqrt(std::max(d1, std::max(d2, d3))) * 0.5f + EPS;
|
||||
if (d1 >= d2 && d1 >= d3)
|
||||
{
|
||||
center = (pts[0] + pts[1]) * 0.5f;
|
||||
}
|
||||
else if (d2 >= d1 && d2 >= d3)
|
||||
{
|
||||
center = (pts[0] + pts[2]) * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_DbgAssert(d3 >= d1 && d3 >= d2);
|
||||
center = (pts[1] + pts[2]) * 0.5f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
float cx = (c1 * v2.y - c2 * v1.y) / det;
|
||||
float cy = (v1.x * c2 - v2.x * c1) / det;
|
||||
center.x = (float)cx;
|
||||
@@ -92,7 +115,13 @@ static void findThirdPoint(const PT *pts, int i, int j, Point2f ¢er, float &
|
||||
ptsf[0] = (Point2f)pts[i];
|
||||
ptsf[1] = (Point2f)pts[j];
|
||||
ptsf[2] = (Point2f)pts[k];
|
||||
findCircle3pts(ptsf, center, radius);
|
||||
Point2f new_center; float new_radius = 0;
|
||||
findCircle3pts(ptsf, new_center, new_radius);
|
||||
if (new_radius > 0)
|
||||
{
|
||||
radius = new_radius;
|
||||
center = new_center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +146,13 @@ void findSecondPoint(const PT *pts, int i, Point2f ¢er, float &radius)
|
||||
}
|
||||
else
|
||||
{
|
||||
findThirdPoint(pts, i, j, center, radius);
|
||||
Point2f new_center; float new_radius = 0;
|
||||
findThirdPoint(pts, i, j, new_center, new_radius);
|
||||
if (new_radius > 0)
|
||||
{
|
||||
radius = new_radius;
|
||||
center = new_center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +178,13 @@ static void findMinEnclosingCircle(const PT *pts, int count, Point2f ¢er, fl
|
||||
}
|
||||
else
|
||||
{
|
||||
findSecondPoint(pts, i, center, radius);
|
||||
Point2f new_center; float new_radius = 0;
|
||||
findSecondPoint(pts, i, new_center, new_radius);
|
||||
if (new_radius > 0)
|
||||
{
|
||||
radius = new_radius;
|
||||
center = new_center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,6 +1084,87 @@ int CV_MinCircleTest2::validate_test_results( int test_case_idx )
|
||||
return code;
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* minEnclosingCircle Test 3 *
|
||||
\****************************************************************************************/
|
||||
|
||||
TEST(Imgproc_minEnclosingCircle, basic_test)
|
||||
{
|
||||
vector<Point2f> pts;
|
||||
pts.push_back(Point2f(0, 0));
|
||||
pts.push_back(Point2f(10, 0));
|
||||
pts.push_back(Point2f(5, 1));
|
||||
const float EPS = 1.0e-3f;
|
||||
Point2f center;
|
||||
float radius;
|
||||
|
||||
// pts[2] is within the circle with diameter pts[0] - pts[1].
|
||||
// 2
|
||||
// 0 1
|
||||
// NB: The triangle is obtuse, so the only pts[0] and pts[1] are on the circle.
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 5, EPS);
|
||||
EXPECT_NEAR(center.y, 0, EPS);
|
||||
EXPECT_NEAR(5, radius, EPS);
|
||||
|
||||
// pts[2] is on the circle with diameter pts[0] - pts[1].
|
||||
// 2
|
||||
// 0 1
|
||||
pts[2] = Point2f(5, 5);
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 5, EPS);
|
||||
EXPECT_NEAR(center.y, 0, EPS);
|
||||
EXPECT_NEAR(5, radius, EPS);
|
||||
|
||||
// pts[2] is outside the circle with diameter pts[0] - pts[1].
|
||||
// 2
|
||||
//
|
||||
//
|
||||
// 0 1
|
||||
// NB: The triangle is acute, so all 3 points are on the circle.
|
||||
pts[2] = Point2f(5, 10);
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 5, EPS);
|
||||
EXPECT_NEAR(center.y, 3.75, EPS);
|
||||
EXPECT_NEAR(6.25f, radius, EPS);
|
||||
|
||||
// The 3 points are colinear.
|
||||
pts[2] = Point2f(3, 0);
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 5, EPS);
|
||||
EXPECT_NEAR(center.y, 0, EPS);
|
||||
EXPECT_NEAR(5, radius, EPS);
|
||||
|
||||
// 2 points are the same.
|
||||
pts[2] = pts[1];
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 5, EPS);
|
||||
EXPECT_NEAR(center.y, 0, EPS);
|
||||
EXPECT_NEAR(5, radius, EPS);
|
||||
|
||||
// 3 points are the same.
|
||||
pts[0] = pts[1];
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 10, EPS);
|
||||
EXPECT_NEAR(center.y, 0, EPS);
|
||||
EXPECT_NEAR(0, radius, EPS);
|
||||
}
|
||||
|
||||
TEST(Imgproc_minEnclosingCircle, regression_16051) {
|
||||
vector<Point2f> pts;
|
||||
pts.push_back(Point2f(85, 1415));
|
||||
pts.push_back(Point2f(87, 1415));
|
||||
pts.push_back(Point2f(89, 1414));
|
||||
pts.push_back(Point2f(89, 1414));
|
||||
pts.push_back(Point2f(87, 1412));
|
||||
Point2f center;
|
||||
float radius;
|
||||
minEnclosingCircle(pts, center, radius);
|
||||
EXPECT_NEAR(center.x, 86.9f, 1e-3);
|
||||
EXPECT_NEAR(center.y, 1414.1f, 1e-3);
|
||||
EXPECT_NEAR(2.1024551f, radius, 1e-3);
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* Perimeter Test *
|
||||
\****************************************************************************************/
|
||||
|
||||
@@ -1400,6 +1400,19 @@ TEST(Resize, Area_half)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Resize, lanczos4_regression_16192)
|
||||
{
|
||||
Size src_size(11, 17);
|
||||
Size dst_size(11, 153);
|
||||
Mat src(src_size, CV_8UC3, Scalar::all(128));
|
||||
Mat dst(dst_size, CV_8UC3, Scalar::all(255));
|
||||
|
||||
cv::resize(src, dst, dst_size, 0, 0, INTER_LANCZOS4);
|
||||
|
||||
Mat expected(dst_size, CV_8UC3, Scalar::all(128));
|
||||
EXPECT_EQ(cvtest::norm(dst, expected, NORM_INF), 0) << dst(Rect(0,0,8,8));
|
||||
}
|
||||
|
||||
TEST(Imgproc_Warp, multichannel)
|
||||
{
|
||||
static const int inter_types[] = {INTER_NEAREST, INTER_AREA, INTER_CUBIC,
|
||||
|
||||
Reference in New Issue
Block a user