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

This commit is contained in:
Alexander Alekhin
2019-09-20 21:11:49 +00:00
36 changed files with 4716 additions and 60 deletions
+32 -8
View File
@@ -41,20 +41,18 @@ namespace opencv_test
using namespace perf;
using namespace testing;
static void MakeArtificialExample(RNG rng, Mat& dst_left_view, Mat& dst_view);
static void MakeArtificialExample(Mat& dst_left_view, Mat& dst_view);
CV_ENUM(SGBMModes, StereoSGBM::MODE_SGBM, StereoSGBM::MODE_SGBM_3WAY, StereoSGBM::MODE_HH4);
typedef tuple<Size, int, SGBMModes> SGBMParams;
typedef TestBaseWithParam<SGBMParams> TestStereoCorresp;
typedef TestBaseWithParam<SGBMParams> TestStereoCorrespSGBM;
#ifndef _DEBUG
PERF_TEST_P( TestStereoCorresp, SGBM, Combine(Values(Size(1280,720),Size(640,480)), Values(256,128), SGBMModes::all()) )
PERF_TEST_P( TestStereoCorrespSGBM, SGBM, Combine(Values(Size(1280,720),Size(640,480)), Values(256,128), SGBMModes::all()) )
#else
PERF_TEST_P( TestStereoCorresp, DISABLED_TooLongInDebug_SGBM, Combine(Values(Size(1280,720),Size(640,480)), Values(256,128), SGBMModes::all()) )
PERF_TEST_P( TestStereoCorrespSGBM, DISABLED_TooLongInDebug_SGBM, Combine(Values(Size(1280,720),Size(640,480)), Values(256,128), SGBMModes::all()) )
#endif
{
RNG rng(0);
SGBMParams params = GetParam();
Size sz = get<0>(params);
@@ -65,7 +63,7 @@ PERF_TEST_P( TestStereoCorresp, DISABLED_TooLongInDebug_SGBM, Combine(Values(Siz
Mat src_right(sz, CV_8UC3);
Mat dst(sz, CV_16S);
MakeArtificialExample(rng,src_left,src_right);
MakeArtificialExample(src_left,src_right);
int wsize = 3;
int P1 = 8*src_left.channels()*wsize*wsize;
@@ -78,8 +76,34 @@ PERF_TEST_P( TestStereoCorresp, DISABLED_TooLongInDebug_SGBM, Combine(Values(Siz
SANITY_CHECK(dst, .01, ERROR_RELATIVE);
}
void MakeArtificialExample(RNG rng, Mat& dst_left_view, Mat& dst_right_view)
typedef tuple<Size, int> BMParams;
typedef TestBaseWithParam<BMParams> TestStereoCorrespBM;
PERF_TEST_P(TestStereoCorrespBM, BM, Combine(Values(Size(1280, 720), Size(640, 480)), Values(256, 128)))
{
BMParams params = GetParam();
Size sz = get<0>(params);
int num_disparities = get<1>(params);
Mat src_left(sz, CV_8UC1);
Mat src_right(sz, CV_8UC1);
Mat dst(sz, CV_16S);
MakeArtificialExample(src_left, src_right);
int wsize = 21;
TEST_CYCLE()
{
Ptr<StereoBM> bm = StereoBM::create(num_disparities, wsize);
bm->compute(src_left, src_right, dst);
}
SANITY_CHECK(dst, .01, ERROR_RELATIVE);
}
void MakeArtificialExample(Mat& dst_left_view, Mat& dst_right_view)
{
RNG rng(0);
int w = dst_left_view.cols;
int h = dst_left_view.rows;
+2 -1
View File
@@ -571,7 +571,8 @@ int cv::recoverPose( InputArray E, InputArray _points1, InputArray _points2,
if (!_mask.empty())
{
Mat mask = _mask.getMat();
CV_Assert(mask.size() == mask1.size());
CV_Assert(npoints == mask.checkVector(1));
mask = mask.reshape(1, npoints);
bitwise_and(mask, mask1, mask1);
bitwise_and(mask, mask2, mask2);
bitwise_and(mask, mask3, mask3);
+13 -8
View File
@@ -153,19 +153,24 @@ public:
m_2 = vx_setall_f64(k5);
m_0 /= v_muladd(v_muladd(v_muladd(m_3, r2_0, m_2), r2_0, vx_setall_f64(k4)), r2_0, v_one);
m_1 /= v_muladd(v_muladd(v_muladd(m_3, r2_1, m_2), r2_1, vx_setall_f64(k4)), r2_1, v_one);
m_3 = vx_setall_f64(2.0);
xd_0 = v_muladd(m_3, xd_0, r2_0);
yd_0 = v_muladd(m_3, yd_0, r2_0);
xd_1 = v_muladd(m_3, xd_1, r2_1);
yd_1 = v_muladd(m_3, yd_1, r2_1);
m_2 = x_0 * y_0 * m_3;
m_3 = x_1 * y_1 * m_3;
x_0 *= m_0; y_0 *= m_0; x_1 *= m_1; y_1 *= m_1;
m_0 = vx_setall_f64(p1);
m_1 = vx_setall_f64(p2);
m_2 = vx_setall_f64(2.0);
xd_0 = v_muladd(v_muladd(m_2, xd_0, r2_0), m_1, x_0);
yd_0 = v_muladd(v_muladd(m_2, yd_0, r2_0), m_0, y_0);
xd_1 = v_muladd(v_muladd(m_2, xd_1, r2_1), m_1, x_1);
yd_1 = v_muladd(v_muladd(m_2, yd_1, r2_1), m_0, y_1);
xd_0 = v_muladd(xd_0, m_1, x_0);
yd_0 = v_muladd(yd_0, m_0, y_0);
xd_1 = v_muladd(xd_1, m_1, x_1);
yd_1 = v_muladd(yd_1, m_0, y_1);
m_0 *= m_2; m_1 *= m_2;
m_2 = x_0 * y_0;
m_3 = x_1 * y_1;
xd_0 = v_muladd(m_0, m_2, xd_0);
yd_0 = v_muladd(m_1, m_2, yd_0);
xd_1 = v_muladd(m_0, m_3, xd_1);
@@ -2196,4 +2196,102 @@ TEST(Calib3d_Triangulate, accuracy)
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
TEST(CV_RecoverPoseTest, regression_15341)
{
// initialize test data
const int invalid_point_count = 2;
const float _points1_[] = {
1537.7f, 166.8f,
1599.1f, 179.6f,
1288.0f, 207.5f,
1507.1f, 193.2f,
1742.7f, 210.0f,
1041.6f, 271.7f,
1591.8f, 247.2f,
1524.0f, 261.3f,
1330.3f, 285.0f,
1403.1f, 284.0f,
1506.6f, 342.9f,
1502.8f, 347.3f,
1344.9f, 364.9f,
0.0f, 0.0f // last point is initial invalid
};
const float _points2_[] = {
1533.4f, 532.9f,
1596.6f, 552.4f,
1277.0f, 556.4f,
1502.1f, 557.6f,
1744.4f, 601.3f,
1023.0f, 612.6f,
1589.2f, 621.6f,
1519.4f, 629.0f,
1320.3f, 637.3f,
1395.2f, 642.2f,
1501.5f, 710.3f,
1497.6f, 714.2f,
1335.1f, 719.61f,
1000.0f, 1000.0f // last point is initial invalid
};
vector<Point2f> _points1; Mat(14, 1, CV_32FC2, (void*)_points1_).copyTo(_points1);
vector<Point2f> _points2; Mat(14, 1, CV_32FC2, (void*)_points2_).copyTo(_points2);
const int point_count = (int) _points1.size();
CV_Assert(point_count == (int) _points2.size());
// camera matrix with both focal lengths = 1, and principal point = (0, 0)
const Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
int Inliers = 0;
const int ntests = 3;
for (int testcase = 1; testcase <= ntests; ++testcase)
{
if (testcase == 1) // testcase with vector input data
{
// init temporary test data
vector<unsigned char> mask(point_count);
vector<Point2f> points1(_points1);
vector<Point2f> points2(_points2);
// Estimation of fundamental matrix using the RANSAC algorithm
Mat E, R, t;
E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask);
EXPECT_EQ(0, (int)mask[13]) << "Detecting outliers in function findEssentialMat failed, testcase " << testcase;
points2[12] = Point2f(0.0f, 0.0f); // provoke another outlier detection for recover Pose
Inliers = recoverPose(E, points1, points2, cameraMatrix, R, t, mask);
EXPECT_EQ(0, (int)mask[12]) << "Detecting outliers in function failed, testcase " << testcase;
}
else // testcase with mat input data
{
Mat points1(_points1, true);
Mat points2(_points2, true);
Mat mask;
if (testcase == 2)
{
// init temporary testdata
mask = Mat::zeros(point_count, 1, CV_8UC1);
}
else // testcase == 3 - with transposed mask
{
mask = Mat::zeros(1, point_count, CV_8UC1);
}
// Estimation of fundamental matrix using the RANSAC algorithm
Mat E, R, t;
E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask);
EXPECT_EQ(0, (int)mask.at<unsigned char>(13)) << "Detecting outliers in function findEssentialMat failed, testcase " << testcase;
points2.at<Point2f>(12) = Point2f(0.0f, 0.0f); // provoke an outlier detection
Inliers = recoverPose(E, points1, points2, cameraMatrix, R, t, mask);
EXPECT_EQ(0, (int)mask.at<unsigned char>(12)) << "Detecting outliers in function failed, testcase " << testcase;
}
EXPECT_EQ(Inliers, point_count - invalid_point_count) <<
"Number of inliers differs from expected number of inliers, testcase " << testcase;
}
}
}} // namespace
+38
View File
@@ -1469,6 +1469,44 @@ TEST(Calib3d_UndistortPoints, outputShape)
}
}
TEST(Imgproc_undistort, regression_15286)
{
double kmat_data[9] = { 3217, 0, 1592, 0, 3217, 1201, 0, 0, 1 };
Mat kmat(3, 3, CV_64F, kmat_data);
double dist_coeff_data[5] = { 0.04, -0.4, -0.01, 0.04, 0.7 };
Mat dist_coeffs(5, 1, CV_64F, dist_coeff_data);
Mat img = Mat::zeros(512, 512, CV_8UC1);
img.at<uchar>(128, 128) = 255;
img.at<uchar>(128, 384) = 255;
img.at<uchar>(384, 384) = 255;
img.at<uchar>(384, 128) = 255;
Mat ref = Mat::zeros(512, 512, CV_8UC1);
ref.at<uchar>(Point(24, 98)) = 78;
ref.at<uchar>(Point(24, 99)) = 114;
ref.at<uchar>(Point(25, 98)) = 36;
ref.at<uchar>(Point(25, 99)) = 60;
ref.at<uchar>(Point(27, 361)) = 6;
ref.at<uchar>(Point(28, 361)) = 188;
ref.at<uchar>(Point(28, 362)) = 49;
ref.at<uchar>(Point(29, 361)) = 44;
ref.at<uchar>(Point(29, 362)) = 16;
ref.at<uchar>(Point(317, 366)) = 134;
ref.at<uchar>(Point(317, 367)) = 78;
ref.at<uchar>(Point(318, 366)) = 40;
ref.at<uchar>(Point(318, 367)) = 29;
ref.at<uchar>(Point(310, 104)) = 106;
ref.at<uchar>(Point(310, 105)) = 30;
ref.at<uchar>(Point(311, 104)) = 112;
ref.at<uchar>(Point(311, 105)) = 38;
Mat img_undist;
undistort(img, img_undist, kmat, dist_coeffs);
ASSERT_EQ(0.0, cvtest::norm(img_undist, ref, cv::NORM_INF));
}
TEST(Calib3d_initUndistortRectifyMap, regression_14467)
{
Size size_w_h(512 + 3, 512);
@@ -152,6 +152,11 @@
# define CV_VSX3 1
#endif
#ifdef CV_CPU_COMPILE_MSA
# include "hal/msa_macros.h"
# define CV_MSA 1
#endif
#endif // CV_ENABLE_INTRINSICS && !CV_DISABLE_OPTIMIZATION && !__CUDACC__
#if defined CV_CPU_COMPILE_AVX && !defined CV_CPU_BASELINE_COMPILE_AVX
@@ -319,3 +324,7 @@ struct VZeroUpperGuard {
#ifndef CV_VSX3
# define CV_VSX3 0
#endif
#ifndef CV_MSA
# define CV_MSA 0
#endif
@@ -420,6 +420,27 @@
#endif
#define __CV_CPU_DISPATCH_CHAIN_NEON(fn, args, mode, ...) CV_CPU_CALL_NEON(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_MSA
# define CV_TRY_MSA 1
# define CV_CPU_FORCE_MSA 1
# define CV_CPU_HAS_SUPPORT_MSA 1
# define CV_CPU_CALL_MSA(fn, args) return (cpu_baseline::fn args)
# define CV_CPU_CALL_MSA_(fn, args) return (opt_MSA::fn args)
#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_MSA
# define CV_TRY_MSA 1
# define CV_CPU_FORCE_MSA 0
# define CV_CPU_HAS_SUPPORT_MSA (cv::checkHardwareSupport(CV_CPU_MSA))
# define CV_CPU_CALL_MSA(fn, args) if (CV_CPU_HAS_SUPPORT_MSA) return (opt_MSA::fn args)
# define CV_CPU_CALL_MSA_(fn, args) if (CV_CPU_HAS_SUPPORT_MSA) return (opt_MSA::fn args)
#else
# define CV_TRY_MSA 0
# define CV_CPU_FORCE_MSA 0
# define CV_CPU_HAS_SUPPORT_MSA 0
# define CV_CPU_CALL_MSA(fn, args)
# define CV_CPU_CALL_MSA_(fn, args)
#endif
#define __CV_CPU_DISPATCH_CHAIN_MSA(fn, args, mode, ...) CV_CPU_CALL_MSA(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_VSX
# define CV_TRY_VSX 1
# define CV_CPU_FORCE_VSX 1
@@ -244,6 +244,8 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
#define CV_CPU_NEON 100
#define CV_CPU_MSA 150
#define CV_CPU_VSX 200
#define CV_CPU_VSX3 201
@@ -294,6 +296,8 @@ enum CpuFeatures {
CPU_NEON = 100,
CPU_MSA = 150,
CPU_VSX = 200,
CPU_VSX3 = 201,
@@ -165,9 +165,10 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
# undef CV_NEON
# undef CV_VSX
# undef CV_FP16
# undef CV_MSA
#endif
#if CV_SSE2 || CV_NEON || CV_VSX
#if CV_SSE2 || CV_NEON || CV_VSX || CV_MSA
#define CV__SIMD_FORWARD 128
#include "opencv2/core/hal/intrin_forward.hpp"
#endif
@@ -185,6 +186,10 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
#include "opencv2/core/hal/intrin_vsx.hpp"
#elif CV_MSA
#include "opencv2/core/hal/intrin_msa.hpp"
#else
#define CV_SIMD128_CPP 1
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -409,13 +409,13 @@ static void bin_loop(const T1* src1, size_t step1, const T1* src2, size_t step2,
int x = 0;
#if CV_SIMD
#if !CV_NEON
#if !CV_NEON && !CV_MSA
if (is_aligned(src1, src2, dst))
{
for (; x <= width - wide_step_l; x += wide_step_l)
{
ldr::la(src1 + x, src2 + x, dst + x);
#if !CV_NEON && CV_SIMD_WIDTH == 16
#if CV_SIMD_WIDTH == 16
ldr::la(src1 + x + wide_step, src2 + x + wide_step, dst + x + wide_step);
#endif
}
+39
View File
@@ -2476,6 +2476,45 @@ double dotProd_8s(const schar* src1, const schar* src2, int len)
i += blockSize;
}
}
#elif CV_MSA
int len0 = len & -8, blockSize0 = (1 << 14), blockSize;
v4i32 v_zero = msa_dupq_n_s32(0);
CV_DECL_ALIGNED(16) int buf[4];
while( i < len0 )
{
blockSize = std::min(len0 - i, blockSize0);
v4i32 v_sum = v_zero;
int j = 0;
for( ; j <= blockSize - 16; j += 16 )
{
v16i8 v_src1 = msa_ld1q_s8(src1 + j), v_src2 = msa_ld1q_s8(src2 + j);
v8i16 v_src10 = msa_movl_s8(msa_get_low_s8(v_src1)), v_src20 = msa_movl_s8(msa_get_low_s8(v_src2));
v_sum = msa_mlal_s16(v_sum, msa_get_low_s16(v_src10), msa_get_low_s16(v_src20));
v_sum = msa_mlal_s16(v_sum, msa_get_high_s16(v_src10), msa_get_high_s16(v_src20));
v_src10 = msa_movl_s8(msa_get_high_s8(v_src1));
v_src20 = msa_movl_s8(msa_get_high_s8(v_src2));
v_sum = msa_mlal_s16(v_sum, msa_get_low_s16(v_src10), msa_get_low_s16(v_src20));
v_sum = msa_mlal_s16(v_sum, msa_get_high_s16(v_src10), msa_get_high_s16(v_src20));
}
for( ; j <= blockSize - 8; j += 8 )
{
v8i16 v_src1 = msa_movl_s8(msa_ld1_s8(src1 + j)), v_src2 = msa_movl_s8(msa_ld1_s8(src2 + j));
v_sum = msa_mlal_s16(v_sum, msa_get_low_s16(v_src1), msa_get_low_s16(v_src2));
v_sum = msa_mlal_s16(v_sum, msa_get_high_s16(v_src1), msa_get_high_s16(v_src2));
}
msa_st1q_s32(buf, v_sum);
r += buf[0] + buf[1] + buf[2] + buf[3];
src1 += blockSize;
src2 += blockSize;
i += blockSize;
}
#endif
return r + dotProd_(src1, src2, len - i);
+2
View File
@@ -47,6 +47,8 @@ DECLARE_CV_PAUSE
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("yield" ::: "memory"); } } while (0)
# elif defined __GNUC__ && defined __arm__
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("" ::: "memory"); } } while (0)
# elif defined __GNUC__ && defined __mips__ && __mips_isa_rev >= 2
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("pause" ::: "memory"); } } while (0)
# elif defined __GNUC__ && defined __PPC64__
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("or 27,27,27" ::: "memory"); } } while (0)
# else
+5
View File
@@ -368,6 +368,8 @@ struct HWFeatures
g_hwFeatureNames[CPU_VSX] = "VSX";
g_hwFeatureNames[CPU_VSX3] = "VSX3";
g_hwFeatureNames[CPU_MSA] = "CPU_MSA";
g_hwFeatureNames[CPU_AVX512_SKX] = "AVX512-SKX";
g_hwFeatureNames[CPU_AVX512_KNL] = "AVX512-KNL";
g_hwFeatureNames[CPU_AVX512_KNM] = "AVX512-KNM";
@@ -557,6 +559,9 @@ struct HWFeatures
#if defined _ARM_ && (defined(_WIN32_WCE) && _WIN32_WCE >= 0x800)
have[CV_CPU_NEON] = true;
#endif
#ifdef __mips_msa
have[CV_CPU_MSA] = true;
#endif
// there's no need to check VSX availability in runtime since it's always available on ppc64le CPUs
have[CV_CPU_VSX] = (CV_VSX);
// TODO: Check VSX3 availability in runtime for other platforms
+22 -4
View File
@@ -339,10 +339,28 @@ int CvCaptureCAM::startCaptureDevice(int cameraNum) {
}
else if (status != AVAuthorizationStatusAuthorized)
{
fprintf(stderr, "OpenCV: not authorized to capture video (status %ld), requesting...\n", status);
// TODO: doesn't work via ssh
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL) { /* we don't care */}];
// we do not wait for completion
if (!cv::utils::getConfigurationParameterBool("OPENCV_AVFOUNDATION_SKIP_AUTH", false))
{
fprintf(stderr, "OpenCV: not authorized to capture video (status %ld), requesting...\n", status);
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL) { /* we don't care */}];
if ([NSThread isMainThread])
{
// we run the main loop for 0.1 sec to show the message
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
else
{
fprintf(stderr, "OpenCV: can not spin main run loop from other thread, set "
"OPENCV_AVFOUNDATION_SKIP_AUTH=1 to disable authorization request "
"and perform it in your application.\n");
}
}
else
{
fprintf(stderr, "OpenCV: not authorized to capture video (status %ld), set "
"OPENCV_AVFOUNDATION_SKIP_AUTH=0 to enable authorization request or "
"perform it in your application.\n", status);
}
[localpool drain];
return 0;
}