1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin
2020-12-11 19:27:20 +00:00
24 changed files with 983 additions and 224 deletions
@@ -1344,8 +1344,8 @@ public class ImgprocTest extends OpenCVTestCase {
RotatedRect rrect = Imgproc.minAreaRect(points);
assertEquals(new Size(2, 5), rrect.size);
assertEquals(-90., rrect.angle);
assertEquals(new Size(5, 2), rrect.size);
assertEquals(0., rrect.angle);
assertEquals(new Point(3.5, 2), rrect.center);
}
+1 -1
View File
@@ -352,7 +352,7 @@ cv::RotatedRect cv::minAreaRect( InputArray _points )
Point2f out[3];
RotatedRect box;
convexHull(_points, hull, true, true);
convexHull(_points, hull, false, true);
if( hull.depth() != CV_32F )
{
+128
View File
@@ -1197,6 +1197,78 @@ void hlineSmoothONa_yzy_a<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, co
}
}
}
template <>
void hlineSmoothONa_yzy_a<uint16_t, ufixedpoint32>(const uint16_t* src, int cn, const ufixedpoint32* m, int n, ufixedpoint32* dst, int len, int borderType)
{
int pre_shift = n / 2;
int post_shift = n - pre_shift;
int i = 0;
for (; i < min(pre_shift, len); i++, dst += cn) // Points that fall left from border
{
for (int k = 0; k < cn; k++)
dst[k] = m[pre_shift - i] * src[k];
if (borderType != BORDER_CONSTANT)// If BORDER_CONSTANT out of border values are equal to zero and could be skipped
for (int j = i - pre_shift, mid = 0; j < 0; j++, mid++)
{
int src_idx = borderInterpolate(j, len, borderType);
for (int k = 0; k < cn; k++)
dst[k] = dst[k] + m[mid] * src[src_idx*cn + k];
}
int j, mid;
for (j = 1, mid = pre_shift - i + 1; j < min(i + post_shift, len); j++, mid++)
for (int k = 0; k < cn; k++)
dst[k] = dst[k] + m[mid] * src[j*cn + k];
if (borderType != BORDER_CONSTANT)
for (; j < i + post_shift; j++, mid++)
{
int src_idx = borderInterpolate(j, len, borderType);
for (int k = 0; k < cn; k++)
dst[k] = dst[k] + m[mid] * src[src_idx*cn + k];
}
}
i *= cn;
int lencn = (len - post_shift + 1)*cn;
#if CV_SIMD
const int VECSZ = v_uint32::nlanes;
for (; i <= lencn - VECSZ * 2; i += VECSZ * 2, src += VECSZ * 2, dst += VECSZ * 2)
{
v_uint32 v_res0, v_res1;
v_mul_expand(vx_load(src + pre_shift * cn), vx_setall_u16((uint16_t) *((uint32_t*)(m + pre_shift))), v_res0, v_res1);
for (int j = 0; j < pre_shift; j ++)
{
v_uint32 v_add0, v_add1;
v_mul_expand(vx_load(src + j * cn) + vx_load(src + (n - 1 - j)*cn), vx_setall_u16((uint16_t) *((uint32_t*)(m + j))), v_add0, v_add1);
v_res0 += v_add0;
v_res1 += v_add1;
}
v_store((uint32_t*)dst, v_res0);
v_store((uint32_t*)dst + VECSZ, v_res1);
}
#endif
for (; i < lencn; i++, src++, dst++)
{
*dst = m[pre_shift] * src[pre_shift*cn];
for (int j = 0; j < pre_shift; j++)
*dst = *dst + m[j] * src[j*cn] + m[j] * src[(n - 1 - j)*cn];
}
i /= cn;
for (i -= pre_shift; i < len - pre_shift; i++, src += cn, dst += cn) // Points that fall right from border
{
for (int k = 0; k < cn; k++)
dst[k] = m[0] * src[k];
int j = 1;
for (; j < len - i; j++)
for (int k = 0; k < cn; k++)
dst[k] = dst[k] + m[j] * src[j*cn + k];
if (borderType != BORDER_CONSTANT)// If BORDER_CONSTANT out of border values are equal to zero and could be skipped
for (; j < n; j++)
{
int src_idx = borderInterpolate(i + j, len, borderType) - i;
for (int k = 0; k < cn; k++)
dst[k] = dst[k] + m[j] * src[src_idx*cn + k];
}
}
}
template <typename ET, typename FT>
void vlineSmooth1N(const FT* const * src, const FT* m, int, ET* dst, int len)
{
@@ -1788,6 +1860,62 @@ void vlineSmoothONa_yzy_a<uint8_t, ufixedpoint16>(const ufixedpoint16* const * s
dst[i] = val;
}
}
template <>
void vlineSmoothONa_yzy_a<uint16_t, ufixedpoint32>(const ufixedpoint32* const * src, const ufixedpoint32* m, int n, uint16_t* dst, int len)
{
int i = 0;
#if CV_SIMD
int pre_shift = n / 2;
const int VECSZ = v_uint32::nlanes;
for (; i <= len - 2*VECSZ; i += 2*VECSZ)
{
v_uint32 v_src00, v_src10, v_src01, v_src11;
v_uint64 v_res0, v_res1, v_res2, v_res3;
v_uint64 v_tmp0, v_tmp1, v_tmp2, v_tmp3, v_tmp4, v_tmp5, v_tmp6, v_tmp7;
v_uint32 v_mul = vx_setall_u32(*((uint32_t*)(m + pre_shift)));
const uint32_t* srcp = (const uint32_t*)src[pre_shift] + i;
v_src00 = vx_load(srcp);
v_src10 = vx_load(srcp + VECSZ);
v_mul_expand(v_src00, v_mul, v_res0, v_res1);
v_mul_expand(v_src10, v_mul, v_res2, v_res3);
int j = 0;
for (; j < pre_shift; j++)
{
v_mul = vx_setall_u32(*((uint32_t*)(m + j)));
const uint32_t* srcj0 = (const uint32_t*)src[j] + i;
const uint32_t* srcj1 = (const uint32_t*)src[n - 1 - j] + i;
v_src00 = vx_load(srcj0);
v_src01 = vx_load(srcj1);
v_mul_expand(v_src00, v_mul, v_tmp0, v_tmp1);
v_mul_expand(v_src01, v_mul, v_tmp2, v_tmp3);
v_res0 += v_tmp0 + v_tmp2;
v_res1 += v_tmp1 + v_tmp3;
v_src10 = vx_load(srcj0 + VECSZ);
v_src11 = vx_load(srcj1 + VECSZ);
v_mul_expand(v_src10, v_mul, v_tmp4, v_tmp5);
v_mul_expand(v_src11, v_mul, v_tmp6, v_tmp7);
v_res2 += v_tmp4 + v_tmp6;
v_res3 += v_tmp5 + v_tmp7;
}
v_store(dst + i, v_pack(v_rshr_pack<32>(v_res0, v_res1),
v_rshr_pack<32>(v_res2, v_res3)));
}
#endif
for (; i < len; i++)
{
ufixedpoint64 val = m[0] * src[0][i];
for (int j = 1; j < n; j++)
{
val = val + m[j] * src[j][i];
}
dst[i] = (uint16_t)val;
}
}
template <typename ET, typename FT>
class fixedSmoothInvoker : public ParallelLoopBody
{
+78
View File
@@ -2306,5 +2306,83 @@ TEST(Imgproc_ConvexHull, overflow)
ASSERT_EQ(hull, hullf);
}
static
bool checkMinAreaRect(const RotatedRect& rr, const Mat& c, double eps = 0.5f)
{
int N = c.rows;
Mat rr_pts;
boxPoints(rr, rr_pts);
double maxError = 0.0;
int nfailed = 0;
for (int i = 0; i < N; i++)
{
double d = pointPolygonTest(rr_pts, c.at<Point2f>(i), true);
maxError = std::max(-d, maxError);
if (d < -eps)
nfailed++;
}
if (nfailed)
std::cout << "nfailed=" << nfailed << " (total=" << N << ") maxError=" << maxError << std::endl;
return nfailed == 0;
}
TEST(Imgproc_minAreaRect, reproducer_18157)
{
const int N = 168;
float pts_[N][2] = {
{ 1903, 266 }, { 1897, 267 }, { 1893, 268 }, { 1890, 269 },
{ 1878, 275 }, { 1875, 277 }, { 1872, 279 }, { 1868, 282 },
{ 1862, 287 }, { 1750, 400 }, { 1748, 402 }, { 1742, 407 },
{ 1742, 408 }, { 1740, 410 }, { 1738, 412 }, { 1593, 558 },
{ 1590, 560 }, { 1588, 562 }, { 1586, 564 }, { 1580, 570 },
{ 1443, 709 }, { 1437, 714 }, { 1435, 716 }, { 1304, 848 },
{ 1302, 850 }, { 1292, 860 }, { 1175, 979 }, { 1172, 981 },
{ 1049, 1105 }, { 936, 1220 }, { 933, 1222 }, { 931, 1224 },
{ 830, 1326 }, { 774, 1383 }, { 769, 1389 }, { 766, 1393 },
{ 764, 1396 }, { 762, 1399 }, { 760, 1402 }, { 757, 1408 },
{ 757, 1410 }, { 755, 1413 }, { 754, 1416 }, { 753, 1420 },
{ 752, 1424 }, { 752, 1442 }, { 753, 1447 }, { 754, 1451 },
{ 755, 1454 }, { 757, 1457 }, { 757, 1459 }, { 761, 1467 },
{ 763, 1470 }, { 765, 1473 }, { 767, 1476 }, { 771, 1481 },
{ 779, 1490 }, { 798, 1510 }, { 843, 1556 }, { 847, 1560 },
{ 851, 1564 }, { 863, 1575 }, { 907, 1620 }, { 909, 1622 },
{ 913, 1626 }, { 1154, 1866 }, { 1156, 1868 }, { 1158, 1870 },
{ 1207, 1918 }, { 1238, 1948 }, { 1252, 1961 }, { 1260, 1968 },
{ 1264, 1971 }, { 1268, 1974 }, { 1271, 1975 }, { 1273, 1977 },
{ 1283, 1982 }, { 1286, 1983 }, { 1289, 1984 }, { 1294, 1985 },
{ 1300, 1986 }, { 1310, 1986 }, { 1316, 1985 }, { 1320, 1984 },
{ 1323, 1983 }, { 1326, 1982 }, { 1338, 1976 }, { 1341, 1974 },
{ 1344, 1972 }, { 1349, 1968 }, { 1358, 1960 }, { 1406, 1911 },
{ 1421, 1897 }, { 1624, 1693 }, { 1788, 1528 }, { 1790, 1526 },
{ 1792, 1524 }, { 1794, 1522 }, { 1796, 1520 }, { 1798, 1518 },
{ 1800, 1516 }, { 1919, 1396 }, { 1921, 1394 }, { 2038, 1275 },
{ 2047, 1267 }, { 2048, 1265 }, { 2145, 1168 }, { 2148, 1165 },
{ 2260, 1052 }, { 2359, 952 }, { 2434, 876 }, { 2446, 863 },
{ 2450, 858 }, { 2453, 854 }, { 2455, 851 }, { 2457, 846 },
{ 2459, 844 }, { 2460, 842 }, { 2460, 840 }, { 2462, 837 },
{ 2463, 834 }, { 2464, 830 }, { 2465, 825 }, { 2465, 809 },
{ 2464, 804 }, { 2463, 800 }, { 2462, 797 }, { 2461, 794 },
{ 2456, 784 }, { 2454, 781 }, { 2452, 778 }, { 2450, 775 },
{ 2446, 770 }, { 2437, 760 }, { 2412, 734 }, { 2410, 732 },
{ 2408, 730 }, { 2382, 704 }, { 2380, 702 }, { 2378, 700 },
{ 2376, 698 }, { 2372, 694 }, { 2370, 692 }, { 2368, 690 },
{ 2366, 688 }, { 2362, 684 }, { 2360, 682 }, { 2252, 576 },
{ 2250, 573 }, { 2168, 492 }, { 2166, 490 }, { 2085, 410 },
{ 2026, 352 }, { 1988, 315 }, { 1968, 296 }, { 1958, 287 },
{ 1953, 283 }, { 1949, 280 }, { 1946, 278 }, { 1943, 276 },
{ 1940, 274 }, { 1936, 272 }, { 1934, 272 }, { 1931, 270 },
{ 1928, 269 }, { 1925, 268 }, { 1921, 267 }, { 1915, 266 }
};
Mat contour(N, 1, CV_32FC2, (void*)pts_);
RotatedRect rr = cv::minAreaRect(contour);
EXPECT_TRUE(checkMinAreaRect(rr, contour)) << rr.center << " " << rr.size << " " << rr.angle;
}
}} // namespace
/* End of file. */