feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
1973
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_arithm.cpp
vendored
Normal file
1973
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_arithm.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
469
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_channels.cpp
vendored
Normal file
469
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_channels.cpp
vendored
Normal file
@ -0,0 +1,469 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
|
||||
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// @Authors
|
||||
// Jia Haipeng, jiahaipeng95@gmail.com
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
//////////////////////////////////////// Merge ///////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(Merge, MatDepth, int, bool)
|
||||
{
|
||||
int depth, nsrc;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src1);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src2);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src3);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src4);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
std::vector<Mat> src_roi;
|
||||
std::vector<UMat> usrc_roi;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
depth = GET_PARAM(0);
|
||||
nsrc = GET_PARAM(1);
|
||||
use_roi = GET_PARAM(2);
|
||||
|
||||
CV_Assert(nsrc >= 1 && nsrc <= 4);
|
||||
}
|
||||
|
||||
int type()
|
||||
{
|
||||
return CV_MAKE_TYPE(depth, randomInt(1, 3));
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
|
||||
{
|
||||
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src1, src1_roi, roiSize, src1Border, type(), 2, 11);
|
||||
|
||||
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src2, src2_roi, roiSize, src2Border, type(), -1540, 1740);
|
||||
|
||||
Border src3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src3, src3_roi, roiSize, src3Border, type(), -1540, 1740);
|
||||
|
||||
Border src4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src4, src4_roi, roiSize, src4Border, type(), -1540, 1740);
|
||||
}
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src1);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src2);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src3);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src4);
|
||||
|
||||
src_roi.clear(); usrc_roi.clear(); // for test_loop_times > 1
|
||||
src_roi.push_back(src1_roi), usrc_roi.push_back(usrc1_roi);
|
||||
if (nsrc >= 2)
|
||||
src_roi.push_back(src2_roi), usrc_roi.push_back(usrc2_roi);
|
||||
if (nsrc >= 3)
|
||||
src_roi.push_back(src3_roi), usrc_roi.push_back(usrc3_roi);
|
||||
if (nsrc >= 4)
|
||||
src_roi.push_back(src4_roi), usrc_roi.push_back(usrc4_roi);
|
||||
|
||||
int dcn = 0;
|
||||
for (int i = 0; i < nsrc; ++i)
|
||||
dcn += src_roi[i].channels();
|
||||
|
||||
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, dcn), 5, 16);
|
||||
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
|
||||
}
|
||||
|
||||
void Near(double threshold = 0.)
|
||||
{
|
||||
OCL_EXPECT_MATS_NEAR(dst, threshold);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(Merge, Accuracy)
|
||||
{
|
||||
for(int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::merge(src_roi, dst_roi));
|
||||
OCL_ON(cv::merge(usrc_roi, udst_roi));
|
||||
|
||||
Near();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Split ///////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(Split, MatType, Channels, bool)
|
||||
{
|
||||
int depth, cn;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst1);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst2);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst3);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst4);
|
||||
|
||||
std::vector<Mat> dst_roi, dst;
|
||||
std::vector<UMat> udst_roi, udst;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
depth = GET_PARAM(0);
|
||||
cn = GET_PARAM(1);
|
||||
use_roi = GET_PARAM(2);
|
||||
|
||||
CV_Assert(cn >= 1 && cn <= 4);
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src, src_roi, roiSize, srcBorder, CV_MAKE_TYPE(depth, cn), 5, 16);
|
||||
|
||||
{
|
||||
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst1, dst1_roi, roiSize, dst1Border, depth, 2, 11);
|
||||
|
||||
Border dst2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst2, dst2_roi, roiSize, dst2Border, depth, -1540, 1740);
|
||||
|
||||
Border dst3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst3, dst3_roi, roiSize, dst3Border, depth, -1540, 1740);
|
||||
|
||||
Border dst4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst4, dst4_roi, roiSize, dst4Border, depth, -1540, 1740);
|
||||
}
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst3);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst4);
|
||||
|
||||
dst_roi.push_back(dst1_roi), udst_roi.push_back(udst1_roi),
|
||||
dst.push_back(dst1), udst.push_back(udst1);
|
||||
if (cn >= 2)
|
||||
dst_roi.push_back(dst2_roi), udst_roi.push_back(udst2_roi),
|
||||
dst.push_back(dst2), udst.push_back(udst2);
|
||||
if (cn >= 3)
|
||||
dst_roi.push_back(dst3_roi), udst_roi.push_back(udst3_roi),
|
||||
dst.push_back(dst3), udst.push_back(udst3);
|
||||
if (cn >= 4)
|
||||
dst_roi.push_back(dst4_roi), udst_roi.push_back(udst4_roi),
|
||||
dst.push_back(dst4), udst.push_back(udst4);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(Split, Accuracy)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::split(src_roi, dst_roi));
|
||||
OCL_ON(cv::split(usrc_roi, udst_roi));
|
||||
|
||||
for (int i = 0; i < cn; ++i)
|
||||
{
|
||||
EXPECT_MAT_NEAR(dst[i], udst[i], 0.0);
|
||||
EXPECT_MAT_NEAR(dst_roi[i], udst_roi[i], 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// MixChannels ///////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(MixChannels, MatType, bool)
|
||||
{
|
||||
int depth;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src1);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src2);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src3);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src4);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst1);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst2);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst3);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst4);
|
||||
|
||||
std::vector<Mat> src_roi, dst_roi, dst;
|
||||
std::vector<UMat> usrc_roi, udst_roi, udst;
|
||||
std::vector<int> fromTo;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
depth = GET_PARAM(0);
|
||||
use_roi = GET_PARAM(1);
|
||||
}
|
||||
|
||||
// generate number of channels and create type
|
||||
int type()
|
||||
{
|
||||
int cn = randomInt(1, 5);
|
||||
return CV_MAKE_TYPE(depth, cn);
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
src_roi.clear();
|
||||
dst_roi.clear();
|
||||
dst.clear();
|
||||
usrc_roi.clear();
|
||||
udst_roi.clear();
|
||||
udst.clear();
|
||||
fromTo.clear();
|
||||
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
|
||||
{
|
||||
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src1, src1_roi, roiSize, src1Border, type(), 2, 11);
|
||||
|
||||
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src2, src2_roi, roiSize, src2Border, type(), -1540, 1740);
|
||||
|
||||
Border src3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src3, src3_roi, roiSize, src3Border, type(), -1540, 1740);
|
||||
|
||||
Border src4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src4, src4_roi, roiSize, src4Border, type(), -1540, 1740);
|
||||
}
|
||||
|
||||
{
|
||||
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst1, dst1_roi, roiSize, dst1Border, type(), 2, 11);
|
||||
|
||||
Border dst2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst2, dst2_roi, roiSize, dst2Border, type(), -1540, 1740);
|
||||
|
||||
Border dst3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst3, dst3_roi, roiSize, dst3Border, type(), -1540, 1740);
|
||||
|
||||
Border dst4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst4, dst4_roi, roiSize, dst4Border, type(), -1540, 1740);
|
||||
}
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src1);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src2);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src3);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src4);
|
||||
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst3);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst4);
|
||||
|
||||
int nsrc = randomInt(1, 5), ndst = randomInt(1, 5);
|
||||
|
||||
src_roi.push_back(src1_roi), usrc_roi.push_back(usrc1_roi);
|
||||
if (nsrc >= 2)
|
||||
src_roi.push_back(src2_roi), usrc_roi.push_back(usrc2_roi);
|
||||
if (nsrc >= 3)
|
||||
src_roi.push_back(src3_roi), usrc_roi.push_back(usrc3_roi);
|
||||
if (nsrc >= 4)
|
||||
src_roi.push_back(src4_roi), usrc_roi.push_back(usrc4_roi);
|
||||
|
||||
dst_roi.push_back(dst1_roi), udst_roi.push_back(udst1_roi),
|
||||
dst.push_back(dst1), udst.push_back(udst1);
|
||||
if (ndst >= 2)
|
||||
dst_roi.push_back(dst2_roi), udst_roi.push_back(udst2_roi),
|
||||
dst.push_back(dst2), udst.push_back(udst2);
|
||||
if (ndst >= 3)
|
||||
dst_roi.push_back(dst3_roi), udst_roi.push_back(udst3_roi),
|
||||
dst.push_back(dst3), udst.push_back(udst3);
|
||||
if (ndst >= 4)
|
||||
dst_roi.push_back(dst4_roi), udst_roi.push_back(udst4_roi),
|
||||
dst.push_back(dst4), udst.push_back(udst4);
|
||||
|
||||
int scntotal = 0, dcntotal = 0;
|
||||
for (int i = 0; i < nsrc; ++i)
|
||||
scntotal += src_roi[i].channels();
|
||||
for (int i = 0; i < ndst; ++i)
|
||||
dcntotal += dst_roi[i].channels();
|
||||
|
||||
int npairs = randomInt(1, std::min(scntotal, dcntotal) + 1);
|
||||
fromTo.resize(npairs << 1);
|
||||
|
||||
for (int i = 0; i < npairs; ++i)
|
||||
{
|
||||
fromTo[i<<1] = randomInt(0, scntotal);
|
||||
fromTo[(i<<1)+1] = randomInt(0, dcntotal);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(MixChannels, Accuracy)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times + 10; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::mixChannels(src_roi, dst_roi, fromTo));
|
||||
OCL_ON(cv::mixChannels(usrc_roi, udst_roi, fromTo));
|
||||
|
||||
for (size_t i = 0, size = dst_roi.size(); i < size; ++i)
|
||||
{
|
||||
EXPECT_MAT_NEAR(dst[i], udst[i], 0.0);
|
||||
EXPECT_MAT_NEAR(dst_roi[i], udst_roi[i], 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// InsertChannel ///////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(InsertChannel, MatDepth, Channels, bool)
|
||||
{
|
||||
int depth, cn, coi;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
depth = GET_PARAM(0);
|
||||
cn = GET_PARAM(1);
|
||||
use_roi = GET_PARAM(2);
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
coi = randomInt(0, cn);
|
||||
|
||||
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src, src_roi, roiSize, srcBorder, depth, 2, 11);
|
||||
|
||||
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, cn), 5, 16);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(InsertChannel, Accuracy)
|
||||
{
|
||||
for(int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::insertChannel(src_roi, dst_roi, coi));
|
||||
OCL_ON(cv::insertChannel(usrc_roi, udst_roi, coi));
|
||||
|
||||
OCL_EXPECT_MATS_NEAR(dst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// ExtractChannel ///////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(ExtractChannel, MatDepth, Channels, bool)
|
||||
{
|
||||
int depth, cn, coi;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
depth = GET_PARAM(0);
|
||||
cn = GET_PARAM(1);
|
||||
use_roi = GET_PARAM(2);
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
coi = randomInt(0, cn);
|
||||
|
||||
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src, src_roi, roiSize, srcBorder, CV_MAKE_TYPE(depth, cn), 2, 11);
|
||||
|
||||
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst, dst_roi, roiSize, dstBorder, depth, 5, 16);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(ExtractChannel, Accuracy)
|
||||
{
|
||||
for(int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::extractChannel(src_roi, dst_roi, coi));
|
||||
OCL_ON(cv::extractChannel(usrc_roi, udst_roi, coi));
|
||||
|
||||
OCL_EXPECT_MATS_NEAR(dst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////// Instantiation ///////////////////////////////////////////////
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Channels, Merge, Combine(OCL_ALL_DEPTHS, Values(1, 2, 3, 4), Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Channels, Split, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Channels, MixChannels, Combine(OCL_ALL_DEPTHS, Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Channels, InsertChannel, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Channels, ExtractChannel, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
|
||||
|
||||
} } // namespace opencv_test::ocl
|
||||
|
||||
#endif // HAVE_OPENCL
|
190
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_dft.cpp
vendored
Normal file
190
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_dft.cpp
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
|
||||
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// @Authors
|
||||
// Peng Xiao, pengxiao@multicorewareinc.com
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors as is and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
enum OCL_FFT_TYPE
|
||||
{
|
||||
R2R = 0,
|
||||
C2R = 1,
|
||||
R2C = 2,
|
||||
C2C = 3
|
||||
};
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Dft
|
||||
|
||||
PARAM_TEST_CASE(Dft, cv::Size, OCL_FFT_TYPE, MatDepth, bool, bool, bool, bool)
|
||||
{
|
||||
cv::Size dft_size;
|
||||
int dft_flags, depth, cn, dft_type;
|
||||
bool hint;
|
||||
bool is1d;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
dft_size = GET_PARAM(0);
|
||||
dft_type = GET_PARAM(1);
|
||||
depth = GET_PARAM(2);
|
||||
|
||||
dft_flags = 0;
|
||||
switch (dft_type)
|
||||
{
|
||||
case R2R: dft_flags |= cv::DFT_REAL_OUTPUT; cn = 1; break;
|
||||
case C2R: dft_flags |= cv::DFT_REAL_OUTPUT; cn = 2; break;
|
||||
case R2C: dft_flags |= cv::DFT_COMPLEX_OUTPUT; cn = 1; break;
|
||||
case C2C: dft_flags |= cv::DFT_COMPLEX_OUTPUT; cn = 2; break;
|
||||
}
|
||||
|
||||
if (GET_PARAM(3))
|
||||
dft_flags |= cv::DFT_INVERSE;
|
||||
if (GET_PARAM(4))
|
||||
dft_flags |= cv::DFT_ROWS;
|
||||
if (GET_PARAM(5))
|
||||
dft_flags |= cv::DFT_SCALE;
|
||||
hint = GET_PARAM(6);
|
||||
is1d = (dft_flags & DFT_ROWS) != 0 || dft_size.height == 1;
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
src = randomMat(dft_size, CV_MAKE_TYPE(depth, cn), 0.0, 100.0);
|
||||
usrc = src.getUMat(ACCESS_READ);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(Dft, Mat)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
int nonzero_rows = hint ? src.rows - randomInt(1, src.rows-1) : 0;
|
||||
OCL_OFF(cv::dft(src, dst, dft_flags, nonzero_rows));
|
||||
OCL_ON(cv::dft(usrc, udst, dft_flags, nonzero_rows));
|
||||
|
||||
// In case forward R2C 1d transform dst contains only half of output
|
||||
// without complex conjugate
|
||||
if (dft_type == R2C && is1d && (dft_flags & cv::DFT_INVERSE) == 0)
|
||||
{
|
||||
dst = dst(cv::Range(0, dst.rows), cv::Range(0, dst.cols/2 + 1));
|
||||
udst = udst(cv::Range(0, udst.rows), cv::Range(0, udst.cols/2 + 1));
|
||||
}
|
||||
|
||||
double eps = src.size().area() * 1e-4;
|
||||
EXPECT_MAT_NEAR(dst, udst, eps);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// MulSpectrums
|
||||
|
||||
PARAM_TEST_CASE(MulSpectrums, bool, bool)
|
||||
{
|
||||
bool ccorr, useRoi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src1);
|
||||
TEST_DECLARE_INPUT_PARAMETER(src2);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
ccorr = GET_PARAM(0);
|
||||
useRoi = GET_PARAM(1);
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
Size srcRoiSize = randomSize(1, MAX_VALUE);
|
||||
Border src1Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
|
||||
randomSubMat(src1, src1_roi, srcRoiSize, src1Border, CV_32FC2, -11, 11);
|
||||
|
||||
|
||||
Border src2Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
|
||||
randomSubMat(src2, src2_roi, srcRoiSize, src2Border, CV_32FC2, -11, 11);
|
||||
|
||||
Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst, dst_roi, srcRoiSize, dstBorder, CV_32FC2, 5, 16);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src1);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src2);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(MulSpectrums, Mat)
|
||||
{
|
||||
for (int i = 0; i < test_loop_times; ++i)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(cv::mulSpectrums(src1_roi, src2_roi, dst_roi, 0, ccorr));
|
||||
OCL_ON(cv::mulSpectrums(usrc1_roi, usrc2_roi, udst_roi, 0, ccorr));
|
||||
|
||||
OCL_EXPECT_MATS_NEAR_RELATIVE(dst, 1e-6);
|
||||
}
|
||||
}
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(OCL_ImgProc, MulSpectrums, testing::Combine(Bool(), Bool()));
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Core, Dft, Combine(Values(cv::Size(45, 72), cv::Size(36, 36), cv::Size(512, 1), cv::Size(1280, 768)),
|
||||
Values((OCL_FFT_TYPE) R2C, (OCL_FFT_TYPE) C2C, (OCL_FFT_TYPE) R2R, (OCL_FFT_TYPE) C2R),
|
||||
Values(CV_32F, CV_64F),
|
||||
Bool(), // DFT_INVERSE
|
||||
Bool(), // DFT_ROWS
|
||||
Bool(), // DFT_SCALE
|
||||
Bool() // hint
|
||||
)
|
||||
);
|
||||
|
||||
} } // namespace opencv_test::ocl
|
||||
|
||||
#endif // HAVE_OPENCL
|
165
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_gemm.cpp
vendored
Normal file
165
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_gemm.cpp
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
|
||||
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// @Authors
|
||||
// Peng Xiao, pengxiao@multicorewareinc.com
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors as is and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// GEMM
|
||||
|
||||
PARAM_TEST_CASE(Gemm,
|
||||
MatType,
|
||||
bool, // GEMM_1_T
|
||||
bool, // GEMM_2_T
|
||||
bool, // GEMM_3_T
|
||||
bool // ROI
|
||||
)
|
||||
{
|
||||
bool use_roi;
|
||||
int type, flags;
|
||||
bool atrans, btrans, ctrans;
|
||||
|
||||
double alpha, beta;
|
||||
|
||||
int M, N, K;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(A);
|
||||
TEST_DECLARE_INPUT_PARAMETER(B);
|
||||
TEST_DECLARE_INPUT_PARAMETER(C);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(D);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
atrans = btrans = ctrans = false;
|
||||
|
||||
type = GET_PARAM(0);
|
||||
use_roi = GET_PARAM(4);
|
||||
|
||||
flags = 0;
|
||||
if (GET_PARAM(1))
|
||||
flags |= GEMM_1_T, atrans = true;
|
||||
if (GET_PARAM(2))
|
||||
flags |= GEMM_2_T, btrans = true;
|
||||
if (GET_PARAM(3))
|
||||
flags |= GEMM_3_T, ctrans = true;
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
M = (int)randomDoubleLog(1, 100);
|
||||
N = (int)randomDoubleLog(1, 100);
|
||||
K = (int)randomDoubleLog(1, 1200);
|
||||
|
||||
M = roundUp(M, 1);
|
||||
N = roundUp(N, 1);
|
||||
K = roundUp(K, 1);
|
||||
|
||||
Size ARoiSize = (atrans) ? Size(M, K) : Size(K, M);
|
||||
Border ABorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(A, A_roi, ARoiSize, ABorder, type, -11, 11);
|
||||
|
||||
Size BRoiSize = (btrans) ? Size(K, N) : Size(N, K);
|
||||
Border BBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(B, B_roi, BRoiSize, BBorder, type, -11, 11);
|
||||
|
||||
Size CRoiSize = (ctrans) ? Size(M, N) : Size(N, M);
|
||||
Border CBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(C, C_roi, CRoiSize, CBorder, type, -11, 11);
|
||||
|
||||
Size DRoiSize = Size(N, M);
|
||||
Border DBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(D, D_roi, DRoiSize, DBorder, type, -11, 11);
|
||||
|
||||
alpha = randomDouble(-4, 4);
|
||||
beta = randomDouble(-4, 4);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(A);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(B);
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(C);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(D);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(Gemm, Accuracy)
|
||||
{
|
||||
for (int i = 0; i < test_loop_times; ++i)
|
||||
{
|
||||
generateTestData();
|
||||
SCOPED_TRACE(cv::format("i=%d: M=%d N=%d K=%d", i, M, N, K));
|
||||
|
||||
OCL_OFF(cv::gemm(A_roi, B_roi, alpha, C_roi, beta, D_roi, flags));
|
||||
OCL_ON(cv::gemm(uA_roi, uB_roi, alpha, uC_roi, beta, uD_roi, flags));
|
||||
|
||||
double eps = D_roi.size().area() * (1e-5 * K);
|
||||
OCL_EXPECT_MATS_NEAR(D, eps);
|
||||
}
|
||||
}
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(Core, Gemm, ::testing::Combine(
|
||||
testing::Values(CV_32FC1, CV_32FC2, CV_64FC1, CV_64FC2),
|
||||
Bool(), Bool(), Bool(), Bool()));
|
||||
|
||||
// Test for non-Intel GPUs to check CL_INVALID_WORK_GROUP_SIZE when localsize > globalsize
|
||||
OCL_TEST(Gemm, small)
|
||||
{
|
||||
UMat A(2, 3, CV_32F), B(4, 3, CV_32F), uC(2, 4, CV_32F);
|
||||
Mat C(2, 4, CV_32F);
|
||||
|
||||
randu(A, -1, 1);
|
||||
randu(B, -1, 1);
|
||||
|
||||
OCL_OFF(cv::gemm(A, B, 1, noArray(), 0, C, GEMM_2_T));
|
||||
OCL_ON(cv::gemm(A, B, 1, noArray(), 0, uC, GEMM_2_T));
|
||||
|
||||
EXPECT_LE(cvtest::norm(C, uC, cv::NORM_INF), 1e-5);
|
||||
}
|
||||
|
||||
} } // namespace opencv_test::ocl
|
||||
|
||||
#endif // HAVE_OPENCL
|
96
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_image2d.cpp
vendored
Normal file
96
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_image2d.cpp
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2014, Itseez, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
TEST(Image2D, createAliasEmptyUMat)
|
||||
{
|
||||
if (cv::ocl::haveOpenCL())
|
||||
{
|
||||
UMat um;
|
||||
EXPECT_FALSE(cv::ocl::Image2D::canCreateAlias(um));
|
||||
}
|
||||
else
|
||||
std::cout << "OpenCL runtime not found. Test skipped." << std::endl;
|
||||
}
|
||||
|
||||
TEST(Image2D, createImage2DWithEmptyUMat)
|
||||
{
|
||||
if (cv::ocl::haveOpenCL())
|
||||
{
|
||||
UMat um;
|
||||
EXPECT_ANY_THROW(cv::ocl::Image2D image(um));
|
||||
}
|
||||
else
|
||||
std::cout << "OpenCL runtime not found. Test skipped." << std::endl;
|
||||
}
|
||||
|
||||
TEST(Image2D, createAlias)
|
||||
{
|
||||
if (cv::ocl::haveOpenCL())
|
||||
{
|
||||
const cv::ocl::Device & d = cv::ocl::Device::getDefault();
|
||||
int minor = d.deviceVersionMinor(), major = d.deviceVersionMajor();
|
||||
|
||||
// aliases is OpenCL 1.2 extension
|
||||
if (1 < major || (1 == major && 2 <= minor))
|
||||
{
|
||||
UMat um(128, 128, CV_8UC1);
|
||||
bool isFormatSupported = false, canCreateAlias = false;
|
||||
|
||||
EXPECT_NO_THROW(isFormatSupported = cv::ocl::Image2D::isFormatSupported(CV_8U, 1, false));
|
||||
EXPECT_NO_THROW(canCreateAlias = cv::ocl::Image2D::canCreateAlias(um));
|
||||
|
||||
if (isFormatSupported && canCreateAlias)
|
||||
{
|
||||
EXPECT_NO_THROW(cv::ocl::Image2D image(um, false, true));
|
||||
}
|
||||
else
|
||||
std::cout << "Impossible to create alias for selected image. Test skipped." << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cout << "OpenCL runtime not found. Test skipped" << std::endl;
|
||||
}
|
||||
|
||||
TEST(Image2D, turnOffOpenCL)
|
||||
{
|
||||
if (cv::ocl::haveOpenCL())
|
||||
{
|
||||
// save the current state
|
||||
bool useOCL = cv::ocl::useOpenCL();
|
||||
bool isFormatSupported = false;
|
||||
|
||||
cv::ocl::setUseOpenCL(true);
|
||||
UMat um(128, 128, CV_8UC1);
|
||||
|
||||
cv::ocl::setUseOpenCL(false);
|
||||
EXPECT_NO_THROW(isFormatSupported = cv::ocl::Image2D::isFormatSupported(CV_8U, 1, true));
|
||||
|
||||
if (isFormatSupported)
|
||||
{
|
||||
EXPECT_NO_THROW(cv::ocl::Image2D image(um));
|
||||
}
|
||||
else
|
||||
std::cout << "CV_8UC1 is not supported for OpenCL images. Test skipped." << std::endl;
|
||||
|
||||
// reset state to the previous one
|
||||
cv::ocl::setUseOpenCL(useOCL);
|
||||
}
|
||||
else
|
||||
std::cout << "OpenCL runtime not found. Test skipped." << std::endl;
|
||||
}
|
||||
|
||||
} } // namespace opencv_test::ocl
|
||||
|
||||
#endif // HAVE_OPENCL
|
103
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_matrix_expr.cpp
vendored
Normal file
103
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_matrix_expr.cpp
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
//////////////////////////////// UMat Expressions /////////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(UMatExpr, MatDepth, Channels)
|
||||
{
|
||||
int type;
|
||||
Size size;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
type = CV_MAKE_TYPE(GET_PARAM(0), GET_PARAM(1));
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
size = randomSize(1, MAX_VALUE);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////// UMat::eye /////////////////////////////////////////////////
|
||||
|
||||
OCL_TEST_P(UMatExpr, Eye)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
Mat m = Mat::eye(size, type);
|
||||
UMat um = UMat::eye(size, type);
|
||||
|
||||
EXPECT_MAT_NEAR(m, um, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// UMat::zeros /////////////////////////////////////////////////
|
||||
|
||||
OCL_TEST_P(UMatExpr, Zeros)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
Mat m = Mat::zeros(size, type);
|
||||
UMat um = UMat::zeros(size, type);
|
||||
|
||||
EXPECT_MAT_NEAR(m, um, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// UMat::ones /////////////////////////////////////////////////
|
||||
|
||||
OCL_TEST_P(UMatExpr, Ones)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
Mat m = Mat::ones(size, type);
|
||||
UMat um = UMat::ones(size, type);
|
||||
|
||||
EXPECT_MAT_NEAR(m, um, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// with usageFlags /////////////////////////////////////////////////
|
||||
|
||||
OCL_TEST_P(UMatExpr, WithUsageFlags)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
UMat u0 = UMat::zeros(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
|
||||
UMat u1 = UMat::ones(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
|
||||
UMat u8 = UMat::eye(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
|
||||
|
||||
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u0.usageFlags);
|
||||
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u1.usageFlags);
|
||||
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u8.usageFlags);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// Instantiation /////////////////////////////////////////////////
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, UMatExpr, Combine(OCL_ALL_DEPTHS_16F, OCL_ALL_CHANNELS));
|
||||
|
||||
} } // namespace opencv_test::ocl
|
||||
|
||||
#endif
|
224
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_matrix_operation.cpp
vendored
Normal file
224
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_matrix_operation.cpp
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
|
||||
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// @Authors
|
||||
// Jia Haipeng, jiahaipeng95@gmail.com
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
////////////////////////////////converto/////////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(ConvertTo, MatDepth, MatDepth, Channels, bool)
|
||||
{
|
||||
int src_depth, cn, dstType;
|
||||
bool use_roi;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
src_depth = GET_PARAM(0);
|
||||
cn = GET_PARAM(2);
|
||||
dstType = CV_MAKE_TYPE(GET_PARAM(1), cn);
|
||||
|
||||
use_roi = GET_PARAM(3);
|
||||
}
|
||||
|
||||
void generateTestData()
|
||||
{
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src, src_roi, roiSize, srcBorder, CV_MAKE_TYPE(src_depth, cn), -MAX_VALUE, MAX_VALUE);
|
||||
|
||||
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst, dst_roi, roiSize, dstBorder, dstType, 5, 16);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
|
||||
}
|
||||
};
|
||||
|
||||
OCL_TEST_P(ConvertTo, WithScale_Accuracy)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
double alpha = randomDouble(-4, 4), beta = randomDouble(-4, 4);
|
||||
|
||||
OCL_OFF(src_roi.convertTo(dst_roi, dstType, alpha, beta));
|
||||
OCL_ON(usrc_roi.convertTo(udst_roi, dstType, alpha, beta));
|
||||
|
||||
double eps = CV_MAT_DEPTH(dstType) >= CV_32F ? 2e-4 : 1;
|
||||
OCL_EXPECT_MATS_NEAR(dst, eps);
|
||||
}
|
||||
}
|
||||
|
||||
OCL_TEST_P(ConvertTo, NoScale_Accuracy)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
OCL_OFF(src_roi.convertTo(dst_roi, dstType, 1, 0));
|
||||
OCL_ON(usrc_roi.convertTo(udst_roi, dstType, 1, 0));
|
||||
|
||||
double eps = CV_MAT_DEPTH(dstType) >= CV_32F ? 2e-4 : 1;
|
||||
OCL_EXPECT_MATS_NEAR(dst, eps);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// CopyTo /////////////////////////////////////////////////
|
||||
|
||||
PARAM_TEST_CASE(CopyTo, MatDepth, Channels, bool, bool)
|
||||
{
|
||||
int depth, cn;
|
||||
bool use_roi, use_mask;
|
||||
Scalar val;
|
||||
|
||||
TEST_DECLARE_INPUT_PARAMETER(src);
|
||||
TEST_DECLARE_INPUT_PARAMETER(mask);
|
||||
TEST_DECLARE_OUTPUT_PARAMETER(dst);
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
depth = GET_PARAM(0);
|
||||
cn = GET_PARAM(1);
|
||||
use_roi = GET_PARAM(2);
|
||||
use_mask = GET_PARAM(3);
|
||||
}
|
||||
|
||||
void generateTestData(bool one_cn_mask = false)
|
||||
{
|
||||
const int type = CV_MAKE_TYPE(depth, cn);
|
||||
|
||||
Size roiSize = randomSize(1, MAX_VALUE);
|
||||
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(src, src_roi, roiSize, srcBorder, type, -MAX_VALUE, MAX_VALUE);
|
||||
|
||||
if (use_mask)
|
||||
{
|
||||
Border maskBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
int mask_cn = 1;
|
||||
if (!one_cn_mask && randomDouble(0.0, 2.0) > 1.0)
|
||||
mask_cn = cn;
|
||||
randomSubMat(mask, mask_roi, roiSize, maskBorder, CV_8UC(mask_cn), 0, 2);
|
||||
cv::threshold(mask, mask, 0.5, 255., THRESH_BINARY);
|
||||
}
|
||||
|
||||
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
|
||||
randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 5, 16);
|
||||
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(src);
|
||||
if (use_mask)
|
||||
UMAT_UPLOAD_INPUT_PARAMETER(mask);
|
||||
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
|
||||
|
||||
val = randomScalar(-MAX_VALUE, MAX_VALUE);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
OCL_TEST_P(CopyTo, Accuracy)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
if (use_mask)
|
||||
{
|
||||
OCL_OFF(src_roi.copyTo(dst_roi, mask_roi));
|
||||
OCL_ON(usrc_roi.copyTo(udst_roi, umask_roi));
|
||||
}
|
||||
else
|
||||
{
|
||||
OCL_OFF(src_roi.copyTo(dst_roi));
|
||||
OCL_ON(usrc_roi.copyTo(udst_roi));
|
||||
}
|
||||
|
||||
OCL_EXPECT_MATS_NEAR(dst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
typedef CopyTo SetTo;
|
||||
|
||||
OCL_TEST_P(SetTo, Accuracy)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData(true); // see modules/core/src/umatrix.cpp Ln:791 => CV_Assert( mask.size() == size() && mask.type() == CV_8UC1 );
|
||||
|
||||
if (use_mask)
|
||||
{
|
||||
OCL_OFF(dst_roi.setTo(val, mask_roi));
|
||||
OCL_ON(udst_roi.setTo(val, umask_roi));
|
||||
}
|
||||
else
|
||||
{
|
||||
OCL_OFF(dst_roi.setTo(val));
|
||||
OCL_ON(udst_roi.setTo(val));
|
||||
}
|
||||
|
||||
OCL_EXPECT_MATS_NEAR(dst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, ConvertTo, Combine(
|
||||
OCL_ALL_DEPTHS, OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, CopyTo, Combine(
|
||||
OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));
|
||||
|
||||
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, SetTo, Combine(
|
||||
OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));
|
||||
|
||||
} } // namespace opencv_test::ocl
|
||||
|
||||
#endif
|
318
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_opencl.cpp
vendored
Normal file
318
3rdparty/opencv-4.5.4/modules/core/test/ocl/test_opencl.cpp
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "../test_precomp.hpp"
|
||||
|
||||
#include <opencv2/core/ocl.hpp>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static void testOpenCLKernel(cv::ocl::Kernel& k)
|
||||
{
|
||||
ASSERT_FALSE(k.empty());
|
||||
cv::UMat src(cv::Size(4096, 2048), CV_8UC1, cv::Scalar::all(100));
|
||||
cv::UMat dst(src.size(), CV_8UC1);
|
||||
size_t globalSize[2] = {(size_t)src.cols, (size_t)src.rows};
|
||||
size_t localSize[2] = {8, 8};
|
||||
int64 kernel_time = k.args(
|
||||
cv::ocl::KernelArg::ReadOnlyNoSize(src), // size is not used (similar to 'dst' size)
|
||||
cv::ocl::KernelArg::WriteOnly(dst),
|
||||
(int)5
|
||||
).runProfiling(2, globalSize, localSize);
|
||||
ASSERT_GE(kernel_time, (int64)0);
|
||||
std::cout << "Kernel time: " << (kernel_time * 1e-6) << " ms" << std::endl;
|
||||
cv::Mat res, reference(src.size(), CV_8UC1, cv::Scalar::all(105));
|
||||
dst.copyTo(res);
|
||||
EXPECT_EQ(0, cvtest::norm(reference, res, cv::NORM_INF));
|
||||
}
|
||||
|
||||
TEST(OpenCL, support_binary_programs)
|
||||
{
|
||||
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
|
||||
if (!ctx.ptr())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL is not available");
|
||||
}
|
||||
cv::ocl::Device device = cv::ocl::Device::getDefault();
|
||||
if (!device.compilerAvailable())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL compiler is not available");
|
||||
}
|
||||
std::vector<char> program_binary_code;
|
||||
|
||||
cv::String module_name; // empty to disable OpenCL cache
|
||||
|
||||
{ // Generate program binary from OpenCL C source
|
||||
static const char* opencl_kernel_src =
|
||||
"__kernel void test_kernel(__global const uchar* src, int src_step, int src_offset,\n"
|
||||
" __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,\n"
|
||||
" int c)\n"
|
||||
"{\n"
|
||||
" int x = get_global_id(0);\n"
|
||||
" int y = get_global_id(1);\n"
|
||||
" if (x < dst_cols && y < dst_rows)\n"
|
||||
" {\n"
|
||||
" int src_idx = y * src_step + x + src_offset;\n"
|
||||
" int dst_idx = y * dst_step + x + dst_offset;\n"
|
||||
" dst[dst_idx] = src[src_idx] + c;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
cv::ocl::ProgramSource src(module_name, "simple", opencl_kernel_src, "");
|
||||
cv::String errmsg;
|
||||
cv::ocl::Program program(src, "", errmsg);
|
||||
ASSERT_TRUE(program.ptr() != NULL);
|
||||
cv::ocl::Kernel k("test_kernel", program);
|
||||
EXPECT_FALSE(k.empty());
|
||||
program.getBinary(program_binary_code);
|
||||
std::cout << "Program binary size: " << program_binary_code.size() << " bytes" << std::endl;
|
||||
}
|
||||
|
||||
cv::ocl::Kernel k;
|
||||
|
||||
{ // Load program from binary (without sources)
|
||||
ASSERT_FALSE(program_binary_code.empty());
|
||||
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromBinary(module_name, "simple_binary", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
|
||||
cv::String errmsg;
|
||||
cv::ocl::Program program(src, "", errmsg);
|
||||
ASSERT_TRUE(program.ptr() != NULL);
|
||||
k.create("test_kernel", program);
|
||||
}
|
||||
|
||||
testOpenCLKernel(k);
|
||||
}
|
||||
|
||||
|
||||
TEST(OpenCL, support_SPIR_programs)
|
||||
{
|
||||
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
|
||||
if (!ctx.ptr())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL is not available");
|
||||
}
|
||||
cv::ocl::Device device = cv::ocl::Device::getDefault();
|
||||
if (!device.isExtensionSupported("cl_khr_spir"))
|
||||
{
|
||||
throw cvtest::SkipTestException("'cl_khr_spir' extension is not supported by OpenCL device");
|
||||
}
|
||||
std::vector<char> program_binary_code;
|
||||
cv::String fname = cv::format("test_kernel.spir%d", device.addressBits());
|
||||
std::string full_path = cvtest::findDataFile(std::string("opencl/") + fname);
|
||||
|
||||
{
|
||||
std::fstream f(full_path.c_str(), std::ios::in|std::ios::binary);
|
||||
ASSERT_TRUE(f.is_open());
|
||||
size_t pos = (size_t)f.tellg();
|
||||
f.seekg(0, std::fstream::end);
|
||||
size_t fileSize = (size_t)f.tellg();
|
||||
std::cout << "Program SPIR size: " << fileSize << " bytes" << std::endl;
|
||||
f.seekg(pos, std::fstream::beg);
|
||||
program_binary_code.resize(fileSize);
|
||||
f.read(&program_binary_code[0], fileSize);
|
||||
ASSERT_FALSE(f.fail());
|
||||
}
|
||||
|
||||
cv::String module_name; // empty to disable OpenCL cache
|
||||
|
||||
cv::ocl::Kernel k;
|
||||
|
||||
{ // Load program from SPIR format
|
||||
ASSERT_FALSE(program_binary_code.empty());
|
||||
cv::ocl::ProgramSource src = cv::ocl::ProgramSource::fromSPIR(module_name, "simple_spir", (uchar*)&program_binary_code[0], program_binary_code.size(), "");
|
||||
cv::String errmsg;
|
||||
cv::ocl::Program program(src, "", errmsg);
|
||||
if (program.ptr() == NULL && device.isAMD())
|
||||
{
|
||||
// https://community.amd.com/t5/opencl/spir-support-in-new-drivers-lost/td-p/170165
|
||||
throw cvtest::SkipTestException("Bypass AMD OpenCL runtime bug: 'cl_khr_spir' extension is declared, but it doesn't really work");
|
||||
}
|
||||
ASSERT_TRUE(program.ptr() != NULL);
|
||||
k.create("test_kernel", program);
|
||||
}
|
||||
|
||||
testOpenCLKernel(k);
|
||||
}
|
||||
|
||||
|
||||
TEST(OpenCL, image2Dcount_regression_19334)
|
||||
{
|
||||
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
|
||||
if (!ctx.ptr())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL is not available");
|
||||
}
|
||||
cv::ocl::Device device = cv::ocl::Device::getDefault();
|
||||
if (!device.compilerAvailable())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL compiler is not available");
|
||||
}
|
||||
|
||||
std::string module_name; // empty to disable OpenCL cache
|
||||
|
||||
static const char* opencl_kernel_src =
|
||||
"__kernel void test_kernel(int a,\n"
|
||||
" __global const uchar* src0, int src0_step, int src0_offset, int src0_rows, int src0_cols,\n"
|
||||
" __global const uchar* src1, int src1_step, int src1_offset, int src1_rows, int src1_cols,\n"
|
||||
" __global const uchar* src2, int src2_step, int src2_offset, int src2_rows, int src2_cols,\n"
|
||||
" __read_only image2d_t image)\n"
|
||||
"{\n"
|
||||
"}";
|
||||
cv::ocl::ProgramSource src(module_name, "test_opencl_image_arg", opencl_kernel_src, "");
|
||||
cv::String errmsg;
|
||||
cv::ocl::Program program(src, "", errmsg);
|
||||
ASSERT_TRUE(program.ptr() != NULL);
|
||||
cv::ocl::Kernel k("test_kernel", program);
|
||||
ASSERT_FALSE(k.empty());
|
||||
|
||||
std::vector<UMat> images(4);
|
||||
for (size_t i = 0; i < images.size(); ++i)
|
||||
images[i] = UMat(10, 10, CV_8UC1);
|
||||
cv::ocl::Image2D image;
|
||||
try
|
||||
{
|
||||
cv::ocl::Image2D image_(images.back());
|
||||
image = image_;
|
||||
}
|
||||
catch (const cv::Exception&)
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL images are not supported");
|
||||
}
|
||||
|
||||
int nargs = 0;
|
||||
int a = 0;
|
||||
nargs = k.set(nargs, a);
|
||||
ASSERT_EQ(1, nargs);
|
||||
nargs = k.set(nargs, images[0]);
|
||||
ASSERT_EQ(6, nargs);
|
||||
nargs = k.set(nargs, images[1]);
|
||||
ASSERT_EQ(11, nargs);
|
||||
nargs = k.set(nargs, images[2]);
|
||||
ASSERT_EQ(16, nargs);
|
||||
|
||||
// do not throw (issue of #19334)
|
||||
ASSERT_NO_THROW(nargs = k.set(nargs, image));
|
||||
ASSERT_EQ(17, nargs);
|
||||
|
||||
// allow to replace image argument if kernel is not running
|
||||
UMat image2(10, 10, CV_8UC1);
|
||||
ASSERT_NO_THROW(nargs = k.set(16, cv::ocl::Image2D(image2)));
|
||||
ASSERT_EQ(17, nargs);
|
||||
}
|
||||
|
||||
|
||||
TEST(OpenCL, move_construct_assign)
|
||||
{
|
||||
cv::ocl::Context ctx1 = cv::ocl::Context::getDefault();
|
||||
if (!ctx1.ptr())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL is not available");
|
||||
}
|
||||
void* const ctx_ptr = ctx1.ptr();
|
||||
cv::ocl::Context ctx2(std::move(ctx1));
|
||||
ASSERT_EQ(ctx1.ptr(), nullptr);
|
||||
ASSERT_EQ(ctx2.ptr(), ctx_ptr);
|
||||
cv::ocl::Context ctx3 = std::move(ctx2);
|
||||
ASSERT_EQ(ctx2.ptr(), nullptr);
|
||||
ASSERT_EQ(ctx3.ptr(), ctx_ptr);
|
||||
|
||||
cv::ocl::Platform pl1 = cv::ocl::Platform::getDefault();
|
||||
void* const pl_ptr = pl1.ptr();
|
||||
cv::ocl::Platform pl2(std::move(pl1));
|
||||
ASSERT_EQ(pl1.ptr(), nullptr);
|
||||
ASSERT_EQ(pl2.ptr(), pl_ptr);
|
||||
cv::ocl::Platform pl3 = std::move(pl2);
|
||||
ASSERT_EQ(pl2.ptr(), nullptr);
|
||||
ASSERT_EQ(pl3.ptr(), pl_ptr);
|
||||
|
||||
std::vector<cv::ocl::PlatformInfo> platformInfos;
|
||||
cv::ocl::getPlatfomsInfo(platformInfos);
|
||||
const cv::String pi_name = platformInfos[0].name();
|
||||
cv::ocl::PlatformInfo pinfo2(std::move(platformInfos[0]));
|
||||
ASSERT_EQ(platformInfos[0].name(), cv::String());
|
||||
ASSERT_EQ(pinfo2.name(), pi_name);
|
||||
cv::ocl::PlatformInfo pinfo3 = std::move(pinfo2);
|
||||
ASSERT_EQ(pinfo2.name(), cv::String());
|
||||
ASSERT_EQ(pinfo3.name(), pi_name);
|
||||
|
||||
cv::ocl::Queue q1 = cv::ocl::Queue::getDefault();
|
||||
void* const q_ptr = q1.ptr();
|
||||
cv::ocl::Queue q2(std::move(q1));
|
||||
ASSERT_EQ(q1.ptr(), nullptr);
|
||||
ASSERT_EQ(q2.ptr(), q_ptr);
|
||||
cv::ocl::Queue q3 = std::move(q2);
|
||||
ASSERT_EQ(q2.ptr(), nullptr);
|
||||
ASSERT_EQ(q3.ptr(), q_ptr);
|
||||
|
||||
cv::ocl::Device d1 = cv::ocl::Device::getDefault();
|
||||
if (!d1.compilerAvailable())
|
||||
{
|
||||
throw cvtest::SkipTestException("OpenCL compiler is not available");
|
||||
}
|
||||
void* const d_ptr = d1.ptr();
|
||||
cv::ocl::Device d2(std::move(d1));
|
||||
ASSERT_EQ(d1.ptr(), nullptr);
|
||||
ASSERT_EQ(d2.ptr(), d_ptr);
|
||||
cv::ocl::Device d3 = std::move(d2);
|
||||
ASSERT_EQ(d2.ptr(), nullptr);
|
||||
ASSERT_EQ(d3.ptr(), d_ptr);
|
||||
|
||||
if (d3.imageSupport()) {
|
||||
cv::UMat umat1 = cv::UMat::ones(640, 480, CV_32FC1);
|
||||
cv::ocl::Image2D img1(umat1);
|
||||
void *const img_ptr = img1.ptr();
|
||||
cv::ocl::Image2D img2(std::move(img1));
|
||||
ASSERT_EQ(img1.ptr(), nullptr);
|
||||
ASSERT_EQ(img2.ptr(), img_ptr);
|
||||
cv::ocl::Image2D img3 = std::move(img2);
|
||||
ASSERT_EQ(img2.ptr(), nullptr);
|
||||
ASSERT_EQ(img3.ptr(), img_ptr);
|
||||
}
|
||||
|
||||
static const char* opencl_kernel_src =
|
||||
"__kernel void test_kernel(__global const uchar* src, int src_step, int src_offset,\n"
|
||||
" __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,\n"
|
||||
" int c)\n"
|
||||
"{\n"
|
||||
" int x = get_global_id(0);\n"
|
||||
" int y = get_global_id(1);\n"
|
||||
" if (x < dst_cols && y < dst_rows)\n"
|
||||
" {\n"
|
||||
" int src_idx = y * src_step + x + src_offset;\n"
|
||||
" int dst_idx = y * dst_step + x + dst_offset;\n"
|
||||
" dst[dst_idx] = src[src_idx] + c;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
cv::String module_name; // empty to disable OpenCL cache
|
||||
cv::ocl::ProgramSource ps1(module_name, "move_construct_assign", opencl_kernel_src, "");
|
||||
cv::ocl::ProgramSource::Impl* const ps_ptr = ps1.getImpl();
|
||||
cv::ocl::ProgramSource ps2(std::move(ps1));
|
||||
ASSERT_EQ(ps1.getImpl(), nullptr);
|
||||
ASSERT_EQ(ps2.getImpl(), ps_ptr);
|
||||
cv::ocl::ProgramSource ps3 = std::move(ps2);
|
||||
ASSERT_EQ(ps2.getImpl(), nullptr);
|
||||
ASSERT_EQ(ps3.getImpl(), ps_ptr);
|
||||
|
||||
cv::String errmsg;
|
||||
cv::ocl::Program prog1(ps3, "", errmsg);
|
||||
void* const prog_ptr = prog1.ptr();
|
||||
ASSERT_NE(prog_ptr, nullptr);
|
||||
cv::ocl::Program prog2(std::move(prog1));
|
||||
ASSERT_EQ(prog1.ptr(), nullptr);
|
||||
ASSERT_EQ(prog2.ptr(), prog_ptr);
|
||||
cv::ocl::Program prog3 = std::move(prog2);
|
||||
ASSERT_EQ(prog2.ptr(), nullptr);
|
||||
ASSERT_EQ(prog3.ptr(), prog_ptr);
|
||||
|
||||
cv::ocl::Kernel k1("test_kernel", prog3);
|
||||
void* const k_ptr = k1.ptr();
|
||||
ASSERT_NE(k_ptr, nullptr);
|
||||
cv::ocl::Kernel k2(std::move(k1));
|
||||
ASSERT_EQ(k1.ptr(), nullptr);
|
||||
ASSERT_EQ(k2.ptr(), k_ptr);
|
||||
cv::ocl::Kernel k3 = std::move(k2);
|
||||
ASSERT_EQ(k2.ptr(), nullptr);
|
||||
ASSERT_EQ(k3.ptr(), k_ptr);
|
||||
|
||||
testOpenCLKernel(k3);
|
||||
}
|
||||
|
||||
}} // namespace
|
2480
3rdparty/opencv-4.5.4/modules/core/test/test_arithm.cpp
vendored
Normal file
2480
3rdparty/opencv-4.5.4/modules/core/test/test_arithm.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
155
3rdparty/opencv-4.5.4/modules/core/test/test_async.cpp
vendored
Normal file
155
3rdparty/opencv-4.5.4/modules/core/test/test_async.cpp
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/core/async.hpp>
|
||||
#include <opencv2/core/detail/async_promise.hpp>
|
||||
|
||||
#include <opencv2/core/bindings_utils.hpp>
|
||||
|
||||
#if defined(CV_CXX11) && !defined(OPENCV_DISABLE_THREAD_SUPPORT)
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(Core_Async, BasicCheck)
|
||||
{
|
||||
Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
|
||||
AsyncPromise p;
|
||||
AsyncArray r = p.getArrayResult();
|
||||
EXPECT_TRUE(r.valid());
|
||||
|
||||
// Follow the limitations of std::promise::get_future
|
||||
// https://en.cppreference.com/w/cpp/thread/promise/get_future
|
||||
EXPECT_THROW(AsyncArray r2 = p.getArrayResult(), cv::Exception);
|
||||
|
||||
p.setValue(m);
|
||||
|
||||
Mat m2;
|
||||
r.get(m2);
|
||||
EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF));
|
||||
|
||||
// Follow the limitations of std::future::get
|
||||
// https://en.cppreference.com/w/cpp/thread/future/get
|
||||
EXPECT_FALSE(r.valid());
|
||||
Mat m3;
|
||||
EXPECT_THROW(r.get(m3), cv::Exception);
|
||||
}
|
||||
|
||||
TEST(Core_Async, ExceptionCheck)
|
||||
{
|
||||
Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
|
||||
AsyncPromise p;
|
||||
AsyncArray r = p.getArrayResult();
|
||||
EXPECT_TRUE(r.valid());
|
||||
|
||||
try
|
||||
{
|
||||
CV_Error(Error::StsOk, "Test: Generated async error");
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
p.setException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
Mat m2;
|
||||
r.get(m2);
|
||||
FAIL() << "Exception is expected";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_EQ(Error::StsOk, e.code) << e.what();
|
||||
}
|
||||
|
||||
// Follow the limitations of std::future::get
|
||||
// https://en.cppreference.com/w/cpp/thread/future/get
|
||||
EXPECT_FALSE(r.valid());
|
||||
}
|
||||
|
||||
|
||||
TEST(Core_Async, LikePythonTest)
|
||||
{
|
||||
Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
|
||||
AsyncArray r = cv::utils::testAsyncArray(m);
|
||||
EXPECT_TRUE(r.valid());
|
||||
Mat m2;
|
||||
r.get(m2);
|
||||
EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF));
|
||||
|
||||
// Follow the limitations of std::future::get
|
||||
// https://en.cppreference.com/w/cpp/thread/future/get
|
||||
EXPECT_FALSE(r.valid());
|
||||
}
|
||||
|
||||
|
||||
#if defined(CV_CXX11) && !defined(OPENCV_DISABLE_THREAD_SUPPORT)
|
||||
|
||||
TEST(Core_Async, AsyncThread_Simple)
|
||||
{
|
||||
Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
|
||||
AsyncPromise p;
|
||||
AsyncArray r = p.getArrayResult();
|
||||
|
||||
std::thread t([&]{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
try {
|
||||
p.setValue(m);
|
||||
} catch (const std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "Unknown C++ exception" << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
Mat m2;
|
||||
r.get(m2);
|
||||
EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF));
|
||||
|
||||
t.join();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
t.join();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_Async, AsyncThread_DetachedResult)
|
||||
{
|
||||
Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
|
||||
AsyncPromise p;
|
||||
{
|
||||
AsyncArray r = p.getArrayResult();
|
||||
r.release();
|
||||
}
|
||||
|
||||
bool exception_ok = false;
|
||||
|
||||
std::thread t([&]{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
try {
|
||||
p.setValue(m);
|
||||
} catch (const cv::Exception& e) {
|
||||
if (e.code == Error::StsError)
|
||||
exception_ok = true;
|
||||
else
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
} catch (...) {
|
||||
std::cout << "Unknown C++ exception" << std::endl;
|
||||
}
|
||||
});
|
||||
t.join();
|
||||
|
||||
EXPECT_TRUE(exception_ok);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespace
|
77
3rdparty/opencv-4.5.4/modules/core/test/test_concatenation.cpp
vendored
Normal file
77
3rdparty/opencv-4.5.4/modules/core/test/test_concatenation.cpp
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(Core_Concatenation, empty)
|
||||
{
|
||||
const Mat mat0x5(0,5, CV_8U, Scalar::all(1));
|
||||
const Mat mat10x5(10,5, CV_8U, Scalar::all(1));
|
||||
const Mat mat20x5(20,5, CV_8U, Scalar::all(1));
|
||||
|
||||
const Mat mat5x0(5,0, CV_8U, Scalar::all(1));
|
||||
const Mat mat5x10(5,10, CV_8U, Scalar::all(1));
|
||||
const Mat mat5x20(5,20, CV_8U, Scalar::all(1));
|
||||
|
||||
Mat result;
|
||||
|
||||
cv::hconcat(mat5x0, mat5x0, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat5x0, 0);
|
||||
cv::hconcat(mat5x0, mat5x10, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat5x10, 0);
|
||||
cv::hconcat(mat5x10, mat5x0, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat5x10, 0);
|
||||
cv::hconcat(mat5x10, mat5x10, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat5x20, 0);
|
||||
|
||||
cv::vconcat(mat0x5, mat0x5, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat0x5, 0);
|
||||
cv::vconcat(mat0x5, mat10x5, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat10x5, 0);
|
||||
cv::vconcat(mat10x5, mat0x5, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat10x5, 0);
|
||||
cv::vconcat(mat10x5, mat10x5, result);
|
||||
EXPECT_MAT_N_DIFF(result, mat20x5, 0);
|
||||
}
|
||||
|
||||
}} // namespace
|
108
3rdparty/opencv-4.5.4/modules/core/test/test_conjugate_gradient.cpp
vendored
Normal file
108
3rdparty/opencv-4.5.4/modules/core/test/test_conjugate_gradient.cpp
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static void mytest(cv::Ptr<cv::ConjGradSolver> solver,cv::Ptr<cv::MinProblemSolver::Function> ptr_F,cv::Mat& x,
|
||||
cv::Mat& etalon_x,double etalon_res){
|
||||
solver->setFunction(ptr_F);
|
||||
//int ndim=MAX(step.cols,step.rows);
|
||||
double res=solver->minimize(x);
|
||||
std::cout<<"res:\n\t"<<res<<std::endl;
|
||||
std::cout<<"x:\n\t"<<x<<std::endl;
|
||||
std::cout<<"etalon_res:\n\t"<<etalon_res<<std::endl;
|
||||
std::cout<<"etalon_x:\n\t"<<etalon_x<<std::endl;
|
||||
double tol = 1e-2;
|
||||
ASSERT_TRUE(std::abs(res-etalon_res)<tol);
|
||||
/*for(cv::Mat_<double>::iterator it1=x.begin<double>(),it2=etalon_x.begin<double>();it1!=x.end<double>();it1++,it2++){
|
||||
ASSERT_TRUE(std::abs((*it1)-(*it2))<tol);
|
||||
}*/
|
||||
std::cout<<"--------------------------\n";
|
||||
}
|
||||
|
||||
class SphereF_CG:public cv::MinProblemSolver::Function{
|
||||
public:
|
||||
int getDims() const { return 4; }
|
||||
double calc(const double* x)const{
|
||||
return x[0]*x[0]+x[1]*x[1]+x[2]*x[2]+x[3]*x[3];
|
||||
}
|
||||
// use automatically computed gradient
|
||||
/*void getGradient(const double* x,double* grad){
|
||||
for(int i=0;i<4;i++){
|
||||
grad[i]=2*x[i];
|
||||
}
|
||||
}*/
|
||||
};
|
||||
class RosenbrockF_CG:public cv::MinProblemSolver::Function{
|
||||
int getDims() const { return 2; }
|
||||
double calc(const double* x)const{
|
||||
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
|
||||
}
|
||||
void getGradient(const double* x,double* grad){
|
||||
grad[0]=-2*(1-x[0])-400*(x[1]-x[0]*x[0])*x[0];
|
||||
grad[1]=200*(x[1]-x[0]*x[0]);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_ConjGradSolver, regression_basic){
|
||||
cv::Ptr<cv::ConjGradSolver> solver=cv::ConjGradSolver::create();
|
||||
#if 1
|
||||
{
|
||||
cv::Ptr<cv::MinProblemSolver::Function> ptr_F(new SphereF_CG());
|
||||
cv::Mat x=(cv::Mat_<double>(4,1)<<50.0,10.0,1.0,-10.0),
|
||||
etalon_x=(cv::Mat_<double>(1,4)<<0.0,0.0,0.0,0.0);
|
||||
double etalon_res=0.0;
|
||||
mytest(solver,ptr_F,x,etalon_x,etalon_res);
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
{
|
||||
cv::Ptr<cv::MinProblemSolver::Function> ptr_F(new RosenbrockF_CG());
|
||||
cv::Mat x=(cv::Mat_<double>(2,1)<<0.0,0.0),
|
||||
etalon_x=(cv::Mat_<double>(2,1)<<1.0,1.0);
|
||||
double etalon_res=0.0;
|
||||
mytest(solver,ptr_F,x,etalon_x,etalon_res);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}} // namespace
|
298
3rdparty/opencv-4.5.4/modules/core/test/test_countnonzero.cpp
vendored
Normal file
298
3rdparty/opencv-4.5.4/modules/core/test/test_countnonzero.cpp
vendored
Normal file
@ -0,0 +1,298 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
#define CORE_COUNTNONZERO_ERROR_COUNT 1
|
||||
|
||||
#define MESSAGE_ERROR_COUNT "Count non zero elements returned by OpenCV function is incorrect."
|
||||
|
||||
#define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1
|
||||
|
||||
#define MAX_WIDTH 100
|
||||
#define MAX_HEIGHT 100
|
||||
|
||||
class CV_CountNonZeroTest: public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_CountNonZeroTest();
|
||||
~CV_CountNonZeroTest();
|
||||
|
||||
protected:
|
||||
void run (int);
|
||||
|
||||
private:
|
||||
float eps_32;
|
||||
double eps_64;
|
||||
Mat src;
|
||||
int current_type;
|
||||
|
||||
void generate_src_data(cv::Size size, int type);
|
||||
void generate_src_data(cv::Size size, int type, int count_non_zero);
|
||||
void generate_src_stat_data(cv::Size size, int type, int distribution);
|
||||
|
||||
int get_count_non_zero();
|
||||
|
||||
void print_information(int right, int result);
|
||||
};
|
||||
|
||||
CV_CountNonZeroTest::CV_CountNonZeroTest(): eps_32(std::numeric_limits<float>::min()), eps_64(std::numeric_limits<double>::min()), src(Mat()), current_type(-1) {}
|
||||
CV_CountNonZeroTest::~CV_CountNonZeroTest() {}
|
||||
|
||||
void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type)
|
||||
{
|
||||
src.create(size, CV_MAKETYPE(type, 1));
|
||||
|
||||
for (int j = 0; j < size.width; ++j)
|
||||
for (int i = 0; i < size.height; ++i)
|
||||
switch (type)
|
||||
{
|
||||
case CV_8U: { src.at<uchar>(i, j) = cv::randu<uchar>(); break; }
|
||||
case CV_8S: { src.at<char>(i, j) = cv::randu<uchar>() - 128; break; }
|
||||
case CV_16U: { src.at<ushort>(i, j) = cv::randu<ushort>(); break; }
|
||||
case CV_16S: { src.at<short>(i, j) = cv::randu<short>(); break; }
|
||||
case CV_32S: { src.at<int>(i, j) = cv::randu<int>(); break; }
|
||||
case CV_32F: { src.at<float>(i, j) = cv::randu<float>(); break; }
|
||||
case CV_64F: { src.at<double>(i, j) = cv::randu<double>(); break; }
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type, int count_non_zero)
|
||||
{
|
||||
src = Mat::zeros(size, CV_MAKETYPE(type, 1));
|
||||
|
||||
int n = 0; RNG& rng = ts->get_rng();
|
||||
|
||||
while (n < count_non_zero)
|
||||
{
|
||||
int i = rng.next()%size.height, j = rng.next()%size.width;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CV_8U: { if (!src.at<uchar>(i, j)) {src.at<uchar>(i, j) = cv::randu<uchar>(); n += (src.at<uchar>(i, j) > 0);} break; }
|
||||
case CV_8S: { if (!src.at<char>(i, j)) {src.at<char>(i, j) = cv::randu<uchar>() - 128; n += abs(sign(src.at<char>(i, j)));} break; }
|
||||
case CV_16U: { if (!src.at<ushort>(i, j)) {src.at<ushort>(i, j) = cv::randu<ushort>(); n += (src.at<ushort>(i, j) > 0);} break; }
|
||||
case CV_16S: { if (!src.at<short>(i, j)) {src.at<short>(i, j) = cv::randu<short>(); n += abs(sign(src.at<short>(i, j)));} break; }
|
||||
case CV_32S: { if (!src.at<int>(i, j)) {src.at<int>(i, j) = cv::randu<int>(); n += abs(sign(src.at<int>(i, j)));} break; }
|
||||
case CV_32F: { if (fabs(src.at<float>(i, j)) <= eps_32) {src.at<float>(i, j) = cv::randu<float>(); n += (fabs(src.at<float>(i, j)) > eps_32);} break; }
|
||||
case CV_64F: { if (fabs(src.at<double>(i, j)) <= eps_64) {src.at<double>(i, j) = cv::randu<double>(); n += (fabs(src.at<double>(i, j)) > eps_64);} break; }
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CV_CountNonZeroTest::generate_src_stat_data(cv::Size size, int type, int distribution)
|
||||
{
|
||||
src.create(size, CV_MAKETYPE(type, 1));
|
||||
|
||||
double mean = 0.0, sigma = 1.0;
|
||||
double left = -1.0, right = 1.0;
|
||||
|
||||
RNG& rng = ts->get_rng();
|
||||
|
||||
if (distribution == RNG::NORMAL)
|
||||
rng.fill(src, RNG::NORMAL, Scalar::all(mean), Scalar::all(sigma));
|
||||
else if (distribution == RNG::UNIFORM)
|
||||
rng.fill(src, RNG::UNIFORM, Scalar::all(left), Scalar::all(right));
|
||||
}
|
||||
|
||||
int CV_CountNonZeroTest::get_count_non_zero()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
for (int i = 0; i < src.rows; ++i)
|
||||
for (int j = 0; j < src.cols; ++j)
|
||||
{
|
||||
if (current_type == CV_8U) result += (src.at<uchar>(i, j) > 0);
|
||||
else if (current_type == CV_8S) result += abs(sign(src.at<char>(i, j)));
|
||||
else if (current_type == CV_16U) result += (src.at<ushort>(i, j) > 0);
|
||||
else if (current_type == CV_16S) result += abs(sign(src.at<short>(i, j)));
|
||||
else if (current_type == CV_32S) result += abs(sign(src.at<int>(i, j)));
|
||||
else if (current_type == CV_32F) result += (fabs(src.at<float>(i, j)) > eps_32);
|
||||
else result += (fabs(src.at<double>(i, j)) > eps_64);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CV_CountNonZeroTest::print_information(int right, int result)
|
||||
{
|
||||
cout << endl; cout << "Checking for the work of countNonZero function..." << endl; cout << endl;
|
||||
cout << "Type of Mat: ";
|
||||
switch (current_type)
|
||||
{
|
||||
case 0: {cout << "CV_8U"; break;}
|
||||
case 1: {cout << "CV_8S"; break;}
|
||||
case 2: {cout << "CV_16U"; break;}
|
||||
case 3: {cout << "CV_16S"; break;}
|
||||
case 4: {cout << "CV_32S"; break;}
|
||||
case 5: {cout << "CV_32F"; break;}
|
||||
case 6: {cout << "CV_64F"; break;}
|
||||
default: break;
|
||||
}
|
||||
cout << endl;
|
||||
cout << "Number of rows: " << src.rows << " Number of cols: " << src.cols << endl;
|
||||
cout << "True count non zero elements: " << right << " Result: " << result << endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void CV_CountNonZeroTest::run(int)
|
||||
{
|
||||
const size_t N = 1500;
|
||||
|
||||
for (int k = 1; k <= 3; ++k)
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
|
||||
int w = rng.next()%MAX_WIDTH + 1, h = rng.next()%MAX_HEIGHT + 1;
|
||||
|
||||
current_type = rng.next()%7;
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case 1: {
|
||||
generate_src_data(Size(w, h), current_type);
|
||||
int right = get_count_non_zero(), result = countNonZero(src);
|
||||
if (result != right)
|
||||
{
|
||||
cout << "Number of experiment: " << i << endl;
|
||||
cout << "Method of data generation: RANDOM" << endl;
|
||||
print_information(right, result);
|
||||
CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
int count_non_zero = rng.next()%(w*h);
|
||||
generate_src_data(Size(w, h), current_type, count_non_zero);
|
||||
int result = countNonZero(src);
|
||||
if (result != count_non_zero)
|
||||
{
|
||||
cout << "Number of experiment: " << i << endl;
|
||||
cout << "Method of data generation: HALF-RANDOM" << endl;
|
||||
print_information(count_non_zero, result);
|
||||
CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
int distribution = cv::randu<uchar>()%2;
|
||||
generate_src_stat_data(Size(w, h), current_type, distribution);
|
||||
int right = get_count_non_zero(), result = countNonZero(src);
|
||||
if (right != result)
|
||||
{
|
||||
cout << "Number of experiment: " << i << endl;
|
||||
cout << "Method of data generation: STATISTIC" << endl;
|
||||
print_information(right, result);
|
||||
CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST (Core_CountNonZero, accuracy) { CV_CountNonZeroTest test; test.safe_run(); }
|
||||
|
||||
|
||||
typedef testing::TestWithParam<tuple<int, int> > CountNonZeroND;
|
||||
|
||||
TEST_P (CountNonZeroND, ndim)
|
||||
{
|
||||
const int dims = get<0>(GetParam());
|
||||
const int type = get<1>(GetParam());
|
||||
const int ONE_SIZE = 5;
|
||||
|
||||
vector<int> sizes(dims);
|
||||
fill(sizes.begin(), sizes.end(), ONE_SIZE);
|
||||
|
||||
Mat data(sizes, CV_MAKETYPE(type, 1));
|
||||
data = 0;
|
||||
EXPECT_EQ(0, cv::countNonZero(data));
|
||||
data = Scalar::all(1);
|
||||
int expected = static_cast<int>(pow(static_cast<float>(ONE_SIZE), dims));
|
||||
EXPECT_EQ(expected, cv::countNonZero(data));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Core, CountNonZeroND,
|
||||
testing::Combine(
|
||||
testing::Range(2, 9),
|
||||
testing::Values(CV_8U, CV_8S, CV_32F)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
typedef testing::TestWithParam<tuple<int, cv::Size> > CountNonZeroBig;
|
||||
|
||||
TEST_P(CountNonZeroBig, /**/)
|
||||
{
|
||||
const int type = get<0>(GetParam());
|
||||
const Size sz = get<1>(GetParam());
|
||||
|
||||
EXPECT_EQ(0, cv::countNonZero(cv::Mat::zeros(sz, type)));
|
||||
EXPECT_EQ(sz.area(), cv::countNonZero(cv::Mat::ones(sz, type)));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Core, CountNonZeroBig,
|
||||
testing::Combine(
|
||||
testing::Values(CV_8UC1, CV_32FC1),
|
||||
testing::Values(Size(1, 524190), Size(524190, 1), Size(3840, 2160))
|
||||
)
|
||||
);
|
||||
|
||||
}} // namespace
|
21
3rdparty/opencv-4.5.4/modules/core/test/test_cuda.cpp
vendored
Executable file
21
3rdparty/opencv-4.5.4/modules/core/test/test_cuda.cpp
vendored
Executable file
@ -0,0 +1,21 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#if defined(HAVE_CUDA)
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <cuda_runtime.h>
|
||||
#include "opencv2/core/cuda.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(CUDA_Stream, construct_cudaFlags)
|
||||
{
|
||||
cv::cuda::Stream stream(cudaStreamNonBlocking);
|
||||
EXPECT_NE(stream.cudaPtr(), nullptr);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
#endif
|
106
3rdparty/opencv-4.5.4/modules/core/test/test_downhill_simplex.cpp
vendored
Normal file
106
3rdparty/opencv-4.5.4/modules/core/test/test_downhill_simplex.cpp
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static void mytest(cv::Ptr<cv::DownhillSolver> solver,cv::Ptr<cv::MinProblemSolver::Function> ptr_F,cv::Mat& x,cv::Mat& step,
|
||||
cv::Mat& etalon_x,double etalon_res){
|
||||
solver->setFunction(ptr_F);
|
||||
int ndim=MAX(step.cols,step.rows);
|
||||
solver->setInitStep(step);
|
||||
cv::Mat settedStep;
|
||||
solver->getInitStep(settedStep);
|
||||
ASSERT_TRUE(settedStep.rows==1 && settedStep.cols==ndim);
|
||||
ASSERT_TRUE(std::equal(step.begin<double>(),step.end<double>(),settedStep.begin<double>()));
|
||||
std::cout<<"step set:\n\t"<<step<<std::endl;
|
||||
double res=solver->minimize(x);
|
||||
std::cout<<"res:\n\t"<<res<<std::endl;
|
||||
std::cout<<"x:\n\t"<<x<<std::endl;
|
||||
std::cout<<"etalon_res:\n\t"<<etalon_res<<std::endl;
|
||||
std::cout<<"etalon_x:\n\t"<<etalon_x<<std::endl;
|
||||
double tol=1e-2;//solver->getTermCriteria().epsilon;
|
||||
ASSERT_TRUE(std::abs(res-etalon_res)<tol);
|
||||
/*for(cv::Mat_<double>::iterator it1=x.begin<double>(),it2=etalon_x.begin<double>();it1!=x.end<double>();it1++,it2++){
|
||||
ASSERT_TRUE(std::abs((*it1)-(*it2))<tol);
|
||||
}*/
|
||||
std::cout<<"--------------------------\n";
|
||||
}
|
||||
|
||||
class SphereF:public cv::MinProblemSolver::Function{
|
||||
public:
|
||||
int getDims() const { return 2; }
|
||||
double calc(const double* x)const{
|
||||
return x[0]*x[0]+x[1]*x[1];
|
||||
}
|
||||
};
|
||||
class RosenbrockF:public cv::MinProblemSolver::Function{
|
||||
int getDims() const { return 2; }
|
||||
double calc(const double* x)const{
|
||||
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_DownhillSolver, regression_basic){
|
||||
cv::Ptr<cv::DownhillSolver> solver=cv::DownhillSolver::create();
|
||||
#if 1
|
||||
{
|
||||
cv::Ptr<cv::MinProblemSolver::Function> ptr_F = cv::makePtr<SphereF>();
|
||||
cv::Mat x=(cv::Mat_<double>(1,2)<<1.0,1.0),
|
||||
step=(cv::Mat_<double>(2,1)<<-0.5,-0.5),
|
||||
etalon_x=(cv::Mat_<double>(1,2)<<-0.0,0.0);
|
||||
double etalon_res=0.0;
|
||||
mytest(solver,ptr_F,x,step,etalon_x,etalon_res);
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
{
|
||||
cv::Ptr<cv::MinProblemSolver::Function> ptr_F = cv::makePtr<RosenbrockF>();
|
||||
cv::Mat x=(cv::Mat_<double>(2,1)<<0.0,0.0),
|
||||
step=(cv::Mat_<double>(2,1)<<0.5,+0.5),
|
||||
etalon_x=(cv::Mat_<double>(2,1)<<1.0,1.0);
|
||||
double etalon_res=0.0;
|
||||
mytest(solver,ptr_F,x,step,etalon_x,etalon_res);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}} // namespace
|
2136
3rdparty/opencv-4.5.4/modules/core/test/test_ds.cpp
vendored
Normal file
2136
3rdparty/opencv-4.5.4/modules/core/test/test_ds.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
986
3rdparty/opencv-4.5.4/modules/core/test/test_dxt.cpp
vendored
Normal file
986
3rdparty/opencv-4.5.4/modules/core/test/test_dxt.cpp
vendored
Normal file
@ -0,0 +1,986 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static Mat initDFTWave( int n, bool inv )
|
||||
{
|
||||
int i;
|
||||
double angle = (inv ? 1 : -1)*CV_PI*2/n;
|
||||
Complexd wi, w1;
|
||||
Mat wave(1, n, CV_64FC2);
|
||||
Complexd* w = wave.ptr<Complexd>();
|
||||
|
||||
w1.re = cos(angle);
|
||||
w1.im = sin(angle);
|
||||
w[0].re = wi.re = 1.;
|
||||
w[0].im = wi.im = 0.;
|
||||
|
||||
for( i = 1; i < n; i++ )
|
||||
{
|
||||
double t = wi.re*w1.re - wi.im*w1.im;
|
||||
wi.im = wi.re*w1.im + wi.im*w1.re;
|
||||
wi.re = t;
|
||||
w[i] = wi;
|
||||
}
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
|
||||
static void DFT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat())
|
||||
{
|
||||
_dst.create(_src.size(), _src.type());
|
||||
int i, j, k, n = _dst.cols + _dst.rows - 1;
|
||||
Mat wave = _wave;
|
||||
double scale = (flags & DFT_SCALE) ? 1./n : 1.;
|
||||
size_t esz = _src.elemSize();
|
||||
size_t srcstep = esz, dststep = esz;
|
||||
const uchar* src0 = _src.ptr();
|
||||
uchar* dst0 = _dst.ptr();
|
||||
|
||||
CV_Assert( _src.cols + _src.rows - 1 == n );
|
||||
|
||||
if( wave.empty() )
|
||||
wave = initDFTWave( n, (flags & DFT_INVERSE) != 0 );
|
||||
|
||||
const Complexd* w = wave.ptr<Complexd>();
|
||||
if( !_src.isContinuous() )
|
||||
srcstep = _src.step;
|
||||
if( !_dst.isContinuous() )
|
||||
dststep = _dst.step;
|
||||
|
||||
if( _src.type() == CV_32FC2 )
|
||||
{
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Complexf* dst = (Complexf*)(dst0 + i*dststep);
|
||||
Complexd sum(0,0);
|
||||
int delta = i;
|
||||
k = 0;
|
||||
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
const Complexf* src = (const Complexf*)(src0 + j*srcstep);
|
||||
sum.re += src->re*w[k].re - src->im*w[k].im;
|
||||
sum.im += src->re*w[k].im + src->im*w[k].re;
|
||||
k += delta;
|
||||
k -= (k >= n ? n : 0);
|
||||
}
|
||||
|
||||
dst->re = (float)(sum.re*scale);
|
||||
dst->im = (float)(sum.im*scale);
|
||||
}
|
||||
}
|
||||
else if( _src.type() == CV_64FC2 )
|
||||
{
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Complexd* dst = (Complexd*)(dst0 + i*dststep);
|
||||
Complexd sum(0,0);
|
||||
int delta = i;
|
||||
k = 0;
|
||||
|
||||
for( j = 0; j < n; j++ )
|
||||
{
|
||||
const Complexd* src = (const Complexd*)(src0 + j*srcstep);
|
||||
sum.re += src->re*w[k].re - src->im*w[k].im;
|
||||
sum.im += src->re*w[k].im + src->im*w[k].re;
|
||||
k += delta;
|
||||
k -= (k >= n ? n : 0);
|
||||
}
|
||||
|
||||
dst->re = sum.re*scale;
|
||||
dst->im = sum.im*scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Error(CV_StsUnsupportedFormat, "");
|
||||
}
|
||||
|
||||
|
||||
static void DFT_2D( const Mat& src, Mat& dst, int flags )
|
||||
{
|
||||
const int cn = 2;
|
||||
int i;
|
||||
dst.create(src.size(), src.type());
|
||||
Mat tmp( src.cols, src.rows, src.type());
|
||||
Mat wave = initDFTWave( dst.cols, (flags & DFT_INVERSE) != 0 );
|
||||
|
||||
// 1. row-wise transform
|
||||
for( i = 0; i < dst.rows; i++ )
|
||||
{
|
||||
Mat srci = src.row(i).reshape(cn, src.cols), dsti = tmp.col(i);
|
||||
DFT_1D(srci, dsti, flags, wave );
|
||||
}
|
||||
|
||||
if( (flags & DFT_ROWS) == 0 )
|
||||
{
|
||||
if( dst.cols != dst.rows )
|
||||
wave = initDFTWave( dst.rows, (flags & DFT_INVERSE) != 0 );
|
||||
|
||||
// 2. column-wise transform
|
||||
for( i = 0; i < dst.cols; i++ )
|
||||
{
|
||||
Mat srci = tmp.row(i).reshape(cn, tmp.cols), dsti = dst.col(i);
|
||||
DFT_1D(srci, dsti, flags, wave );
|
||||
}
|
||||
}
|
||||
else
|
||||
cvtest::transpose(tmp, dst);
|
||||
}
|
||||
|
||||
|
||||
static Mat initDCTWave( int n, bool inv )
|
||||
{
|
||||
int i, k;
|
||||
double angle = CV_PI*0.5/n;
|
||||
Mat wave(n, n, CV_64F);
|
||||
|
||||
double scale = sqrt(1./n);
|
||||
for( k = 0; k < n; k++ )
|
||||
wave.at<double>(0, k) = scale;
|
||||
scale *= sqrt(2.);
|
||||
for( i = 1; i < n; i++ )
|
||||
for( k = 0; k < n; k++ )
|
||||
wave.at<double>(i, k) = scale*cos( angle*i*(2*k + 1) );
|
||||
|
||||
if( inv )
|
||||
cv::transpose( wave, wave );
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
|
||||
static void DCT_1D( const Mat& _src, Mat& _dst, int flags, const Mat& _wave=Mat() )
|
||||
{
|
||||
_dst.create( _src.size(), _src.type() );
|
||||
int i, j, n = _dst.cols + _dst.rows - 1;
|
||||
Mat wave = _wave;
|
||||
int srcstep = 1, dststep = 1;
|
||||
double* w;
|
||||
|
||||
CV_Assert( _src.cols + _src.rows - 1 == n);
|
||||
|
||||
if( wave.empty() )
|
||||
wave = initDCTWave( n, (flags & DFT_INVERSE) != 0 );
|
||||
w = wave.ptr<double>();
|
||||
|
||||
if( !_src.isContinuous() )
|
||||
srcstep = (int)(_src.step/_src.elemSize());
|
||||
if( !_dst.isContinuous() )
|
||||
dststep = (int)(_dst.step/_dst.elemSize());
|
||||
|
||||
if( _src.type() == CV_32FC1 )
|
||||
{
|
||||
float *dst = _dst.ptr<float>();
|
||||
|
||||
for( i = 0; i < n; i++, dst += dststep )
|
||||
{
|
||||
const float* src = _src.ptr<float>();
|
||||
double sum = 0;
|
||||
|
||||
for( j = 0; j < n; j++, src += srcstep )
|
||||
sum += src[0]*w[j];
|
||||
w += n;
|
||||
dst[0] = (float)sum;
|
||||
}
|
||||
}
|
||||
else if( _src.type() == CV_64FC1 )
|
||||
{
|
||||
double *dst = _dst.ptr<double>();
|
||||
|
||||
for( i = 0; i < n; i++, dst += dststep )
|
||||
{
|
||||
const double* src = _src.ptr<double>();
|
||||
double sum = 0;
|
||||
|
||||
for( j = 0; j < n; j++, src += srcstep )
|
||||
sum += src[0]*w[j];
|
||||
w += n;
|
||||
dst[0] = sum;
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
static void DCT_2D( const Mat& src, Mat& dst, int flags )
|
||||
{
|
||||
const int cn = 1;
|
||||
int i;
|
||||
dst.create( src.size(), src.type() );
|
||||
Mat tmp(dst.cols, dst.rows, dst.type() );
|
||||
Mat wave = initDCTWave( dst.cols, (flags & DCT_INVERSE) != 0 );
|
||||
|
||||
// 1. row-wise transform
|
||||
for( i = 0; i < dst.rows; i++ )
|
||||
{
|
||||
Mat srci = src.row(i).reshape(cn, src.cols);
|
||||
Mat dsti = tmp.col(i);
|
||||
DCT_1D(srci, dsti, flags, wave);
|
||||
}
|
||||
|
||||
if( (flags & DCT_ROWS) == 0 )
|
||||
{
|
||||
if( dst.cols != dst.rows )
|
||||
wave = initDCTWave( dst.rows, (flags & DCT_INVERSE) != 0 );
|
||||
|
||||
// 2. column-wise transform
|
||||
for( i = 0; i < dst.cols; i++ )
|
||||
{
|
||||
Mat srci = tmp.row(i).reshape(cn, tmp.cols);
|
||||
Mat dsti = dst.col(i);
|
||||
DCT_1D( srci, dsti, flags, wave );
|
||||
}
|
||||
}
|
||||
else
|
||||
cvtest::transpose( tmp, dst );
|
||||
}
|
||||
|
||||
|
||||
static void convertFromCCS( const Mat& _src0, const Mat& _src1, Mat& _dst, int flags )
|
||||
{
|
||||
if( _dst.rows > 1 && (_dst.cols > 1 || (flags & DFT_ROWS)) )
|
||||
{
|
||||
int i, count = _dst.rows, len = _dst.cols;
|
||||
bool is2d = (flags & DFT_ROWS) == 0;
|
||||
Mat src0row, src1row, dstrow;
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
int j = !is2d || i == 0 ? i : count - i;
|
||||
src0row = _src0.row(i);
|
||||
src1row = _src1.row(j);
|
||||
dstrow = _dst.row(i);
|
||||
convertFromCCS( src0row, src1row, dstrow, 0 );
|
||||
}
|
||||
|
||||
if( is2d )
|
||||
{
|
||||
src0row = _src0.col(0);
|
||||
dstrow = _dst.col(0);
|
||||
convertFromCCS( src0row, src0row, dstrow, 0 );
|
||||
if( (len & 1) == 0 )
|
||||
{
|
||||
src0row = _src0.col(_src0.cols - 1);
|
||||
dstrow = _dst.col(len/2);
|
||||
convertFromCCS( src0row, src0row, dstrow, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, n = _dst.cols + _dst.rows - 1, n2 = (n+1) >> 1;
|
||||
int cn = _src0.channels();
|
||||
int srcstep = cn, dststep = 1;
|
||||
|
||||
if( !_dst.isContinuous() )
|
||||
dststep = (int)(_dst.step/_dst.elemSize());
|
||||
|
||||
if( !_src0.isContinuous() )
|
||||
srcstep = (int)(_src0.step/_src0.elemSize1());
|
||||
|
||||
if( _dst.depth() == CV_32F )
|
||||
{
|
||||
Complexf* dst = _dst.ptr<Complexf>();
|
||||
const float* src0 = _src0.ptr<float>();
|
||||
const float* src1 = _src1.ptr<float>();
|
||||
int delta0, delta1;
|
||||
|
||||
dst->re = src0[0];
|
||||
dst->im = 0;
|
||||
|
||||
if( (n & 1) == 0 )
|
||||
{
|
||||
dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep];
|
||||
dst[n2*dststep].im = 0;
|
||||
}
|
||||
|
||||
delta0 = srcstep;
|
||||
delta1 = delta0 + (cn == 1 ? srcstep : 1);
|
||||
if( cn == 1 )
|
||||
srcstep *= 2;
|
||||
|
||||
for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep )
|
||||
{
|
||||
float t0 = src0[delta0];
|
||||
float t1 = src0[delta1];
|
||||
|
||||
dst[i*dststep].re = t0;
|
||||
dst[i*dststep].im = t1;
|
||||
|
||||
t0 = src1[delta0];
|
||||
t1 = -src1[delta1];
|
||||
|
||||
dst[(n-i)*dststep].re = t0;
|
||||
dst[(n-i)*dststep].im = t1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Complexd* dst = _dst.ptr<Complexd>();
|
||||
const double* src0 = _src0.ptr<double>();
|
||||
const double* src1 = _src1.ptr<double>();
|
||||
int delta0, delta1;
|
||||
|
||||
dst->re = src0[0];
|
||||
dst->im = 0;
|
||||
|
||||
if( (n & 1) == 0 )
|
||||
{
|
||||
dst[n2*dststep].re = src0[(cn == 1 ? n-1 : n2)*srcstep];
|
||||
dst[n2*dststep].im = 0;
|
||||
}
|
||||
|
||||
delta0 = srcstep;
|
||||
delta1 = delta0 + (cn == 1 ? srcstep : 1);
|
||||
if( cn == 1 )
|
||||
srcstep *= 2;
|
||||
|
||||
for( i = 1; i < n2; i++, delta0 += srcstep, delta1 += srcstep )
|
||||
{
|
||||
double t0 = src0[delta0];
|
||||
double t1 = src0[delta1];
|
||||
|
||||
dst[i*dststep].re = t0;
|
||||
dst[i*dststep].im = t1;
|
||||
|
||||
t0 = src1[delta0];
|
||||
t1 = -src1[delta1];
|
||||
|
||||
dst[(n-i)*dststep].re = t0;
|
||||
dst[(n-i)*dststep].im = t1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fixCCS( Mat& mat, int cols, int flags )
|
||||
{
|
||||
int i, rows = mat.rows;
|
||||
int rows2 = (flags & DFT_ROWS) ? rows : rows/2 + 1, cols2 = cols/2 + 1;
|
||||
|
||||
CV_Assert( cols2 == mat.cols );
|
||||
|
||||
if( mat.type() == CV_32FC2 )
|
||||
{
|
||||
for( i = 0; i < rows2; i++ )
|
||||
{
|
||||
Complexf* row = mat.ptr<Complexf>(i);
|
||||
if( (flags & DFT_ROWS) || i == 0 || (i == rows2 - 1 && rows % 2 == 0) )
|
||||
{
|
||||
row[0].im = 0;
|
||||
if( cols % 2 == 0 )
|
||||
row[cols2-1].im = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Complexf* row2 = mat.ptr<Complexf>(rows-i);
|
||||
row2[0].re = row[0].re;
|
||||
row2[0].im = -row[0].im;
|
||||
|
||||
if( cols % 2 == 0 )
|
||||
{
|
||||
row2[cols2-1].re = row[cols2-1].re;
|
||||
row2[cols2-1].im = -row[cols2-1].im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( mat.type() == CV_64FC2 )
|
||||
{
|
||||
for( i = 0; i < rows2; i++ )
|
||||
{
|
||||
Complexd* row = mat.ptr<Complexd>(i);
|
||||
if( (flags & DFT_ROWS) || i == 0 || (i == rows2 - 1 && rows % 2 == 0) )
|
||||
{
|
||||
row[0].im = 0;
|
||||
if( cols % 2 == 0 )
|
||||
row[cols2-1].im = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Complexd* row2 = mat.ptr<Complexd>(rows-i);
|
||||
row2[0].re = row[0].re;
|
||||
row2[0].im = -row[0].im;
|
||||
|
||||
if( cols % 2 == 0 )
|
||||
{
|
||||
row2[cols2-1].re = row[cols2-1].re;
|
||||
row2[cols2-1].im = -row[cols2-1].im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mulComplex( const Mat& src1, const Mat& src2, Mat& dst, int flags )
|
||||
{
|
||||
dst.create(src1.rows, src1.cols, src1.type());
|
||||
int i, j, depth = src1.depth(), cols = src1.cols*2;
|
||||
|
||||
CV_Assert( src1.size == src2.size && src1.type() == src2.type() &&
|
||||
(src1.type() == CV_32FC2 || src1.type() == CV_64FC2) );
|
||||
|
||||
const Mat* src1_ = &src1;
|
||||
Mat src1_tmp;
|
||||
if (dst.data == src1.data)
|
||||
{
|
||||
src1_tmp = src1.clone();
|
||||
src1_ = &src1_tmp;
|
||||
}
|
||||
const Mat* src2_ = &src2;
|
||||
Mat src2_tmp;
|
||||
if (dst.data == src2.data)
|
||||
{
|
||||
src2_tmp = src2.clone();
|
||||
src2_ = &src2_tmp;
|
||||
}
|
||||
|
||||
for( i = 0; i < dst.rows; i++ )
|
||||
{
|
||||
if( depth == CV_32F )
|
||||
{
|
||||
const float* a = src1_->ptr<float>(i);
|
||||
const float* b = src2_->ptr<float>(i);
|
||||
float* c = dst.ptr<float>(i);
|
||||
|
||||
if( !(flags & CV_DXT_MUL_CONJ) )
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = (double)a[j]*(double)b[j] - (double)a[j+1]*(double)b[j+1];
|
||||
double im = (double)a[j+1]*(double)b[j] + (double)a[j]*(double)b[j+1];
|
||||
|
||||
c[j] = (float)re;
|
||||
c[j+1] = (float)im;
|
||||
}
|
||||
else
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = (double)a[j]*(double)b[j] + (double)a[j+1]*(double)b[j+1];
|
||||
double im = (double)a[j+1]*(double)b[j] - (double)a[j]*(double)b[j+1];
|
||||
|
||||
c[j] = (float)re;
|
||||
c[j+1] = (float)im;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double* a = src1_->ptr<double>(i);
|
||||
const double* b = src2_->ptr<double>(i);
|
||||
double* c = dst.ptr<double>(i);
|
||||
|
||||
if( !(flags & CV_DXT_MUL_CONJ) )
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = a[j]*b[j] - a[j+1]*b[j+1];
|
||||
double im = a[j+1]*b[j] + a[j]*b[j+1];
|
||||
|
||||
c[j] = re;
|
||||
c[j+1] = im;
|
||||
}
|
||||
else
|
||||
for( j = 0; j < cols; j += 2 )
|
||||
{
|
||||
double re = a[j]*b[j] + a[j+1]*b[j+1];
|
||||
double im = a[j+1]*b[j] - a[j]*b[j+1];
|
||||
|
||||
c[j] = re;
|
||||
c[j+1] = im;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CxCore_DXTBaseTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
typedef cvtest::ArrayTest Base;
|
||||
CxCore_DXTBaseTest( bool _allow_complex=false, bool _allow_odd=false,
|
||||
bool _spectrum_mode=false );
|
||||
protected:
|
||||
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
|
||||
int prepare_test_case( int test_case_idx );
|
||||
double get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ );
|
||||
int flags; // transformation flags
|
||||
bool allow_complex; // whether input/output may be complex or not:
|
||||
// true for DFT and MulSpectrums, false for DCT
|
||||
bool allow_odd; // whether input/output may be have odd (!=1) dimensions:
|
||||
// true for DFT and MulSpectrums, false for DCT
|
||||
bool spectrum_mode; // (2 complex/ccs inputs, 1 complex/ccs output):
|
||||
// true for MulSpectrums, false for DFT and DCT
|
||||
bool inplace; // inplace operation (set for each individual test case)
|
||||
bool temp_dst; // use temporary destination (for real->ccs DFT and ccs MulSpectrums)
|
||||
};
|
||||
|
||||
|
||||
CxCore_DXTBaseTest::CxCore_DXTBaseTest( bool _allow_complex, bool _allow_odd, bool _spectrum_mode )
|
||||
: Base(), flags(0), allow_complex(_allow_complex), allow_odd(_allow_odd),
|
||||
spectrum_mode(_spectrum_mode), inplace(false), temp_dst(false)
|
||||
{
|
||||
test_array[INPUT].push_back(NULL);
|
||||
if( spectrum_mode )
|
||||
test_array[INPUT].push_back(NULL);
|
||||
test_array[OUTPUT].push_back(NULL);
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
test_array[TEMP].push_back(NULL);
|
||||
test_array[TEMP].push_back(NULL);
|
||||
|
||||
max_log_array_size = 9;
|
||||
element_wise_relative_error = spectrum_mode;
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DXTBaseTest::get_test_array_types_and_sizes( int test_case_idx,
|
||||
vector<vector<Size> >& sizes,
|
||||
vector<vector<int> >& types )
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int bits = cvtest::randInt(rng);
|
||||
int depth = cvtest::randInt(rng)%2 + CV_32F;
|
||||
int cn = !allow_complex || !(bits & 256) ? 1 : 2;
|
||||
Size size;
|
||||
Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
|
||||
|
||||
flags = bits & (CV_DXT_INVERSE | CV_DXT_SCALE | CV_DXT_ROWS | CV_DXT_MUL_CONJ);
|
||||
if( spectrum_mode )
|
||||
flags &= ~CV_DXT_INVERSE;
|
||||
types[TEMP][0] = types[TEMP][1] = types[INPUT][0] =
|
||||
types[OUTPUT][0] = CV_MAKETYPE(depth, cn);
|
||||
size = sizes[INPUT][0];
|
||||
|
||||
temp_dst = false;
|
||||
|
||||
if( flags & CV_DXT_ROWS && (bits&1024) )
|
||||
{
|
||||
if( bits&16 )
|
||||
size.width = 1;
|
||||
else
|
||||
size.height = 1;
|
||||
flags &= ~CV_DXT_ROWS;
|
||||
}
|
||||
|
||||
const int P2_MIN_SIZE = 32;
|
||||
if( ((bits >> 10) & 1) == 0 )
|
||||
{
|
||||
size.width = (size.width / P2_MIN_SIZE)*P2_MIN_SIZE;
|
||||
size.width = MAX(size.width, 1);
|
||||
size.height = (size.height / P2_MIN_SIZE)*P2_MIN_SIZE;
|
||||
size.height = MAX(size.height, 1);
|
||||
}
|
||||
|
||||
if( !allow_odd )
|
||||
{
|
||||
if( size.width > 1 && (size.width&1) != 0 )
|
||||
size.width = (size.width + 1) & -2;
|
||||
|
||||
if( size.height > 1 && (size.height&1) != 0 && !(flags & CV_DXT_ROWS) )
|
||||
size.height = (size.height + 1) & -2;
|
||||
}
|
||||
|
||||
sizes[INPUT][0] = sizes[OUTPUT][0] = size;
|
||||
sizes[TEMP][0] = sizes[TEMP][1] = cvSize(0,0);
|
||||
|
||||
if( spectrum_mode )
|
||||
{
|
||||
if( cn == 1 )
|
||||
{
|
||||
types[OUTPUT][0] = depth + 8;
|
||||
sizes[TEMP][0] = size;
|
||||
}
|
||||
sizes[INPUT][0] = sizes[INPUT][1] = size;
|
||||
types[INPUT][1] = types[INPUT][0];
|
||||
}
|
||||
else if( /*(cn == 2 && (bits&32)) ||*/ (cn == 1 && allow_complex) )
|
||||
{
|
||||
types[TEMP][0] = depth + 8; // CV_??FC2
|
||||
sizes[TEMP][0] = size;
|
||||
size = cvSize(size.width/2+1, size.height);
|
||||
|
||||
if( flags & CV_DXT_INVERSE )
|
||||
{
|
||||
if( cn == 2 )
|
||||
{
|
||||
types[OUTPUT][0] = depth;
|
||||
sizes[INPUT][0] = size;
|
||||
}
|
||||
types[TEMP][1] = types[TEMP][0];
|
||||
sizes[TEMP][1] = sizes[TEMP][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( allow_complex )
|
||||
types[OUTPUT][0] = depth + 8;
|
||||
|
||||
if( cn == 2 )
|
||||
{
|
||||
types[INPUT][0] = depth;
|
||||
types[TEMP][1] = types[TEMP][0];
|
||||
sizes[TEMP][1] = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
types[TEMP][1] = depth;
|
||||
sizes[TEMP][1] = sizes[TEMP][0];
|
||||
}
|
||||
temp_dst = true;
|
||||
}
|
||||
}
|
||||
|
||||
inplace = false;
|
||||
if( spectrum_mode ||
|
||||
(!temp_dst && types[INPUT][0] == types[OUTPUT][0]) ||
|
||||
(temp_dst && types[INPUT][0] == types[TEMP][1]) )
|
||||
inplace = (bits & 64) != 0;
|
||||
|
||||
types[REF_OUTPUT][0] = types[OUTPUT][0];
|
||||
sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
|
||||
}
|
||||
|
||||
|
||||
double CxCore_DXTBaseTest::get_success_error_level( int test_case_idx, int i, int j )
|
||||
{
|
||||
return Base::get_success_error_level( test_case_idx, i, j );
|
||||
}
|
||||
|
||||
|
||||
int CxCore_DXTBaseTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int code = Base::prepare_test_case( test_case_idx );
|
||||
if( code > 0 )
|
||||
{
|
||||
int in_type = test_mat[INPUT][0].type();
|
||||
int out_type = test_mat[OUTPUT][0].type();
|
||||
|
||||
if( CV_MAT_CN(in_type) == 2 && CV_MAT_CN(out_type) == 1 )
|
||||
fixCCS( test_mat[INPUT][0], test_mat[OUTPUT][0].cols, flags );
|
||||
|
||||
if( inplace )
|
||||
cvtest::copy( test_mat[INPUT][test_case_idx & (int)spectrum_mode],
|
||||
temp_dst ? test_mat[TEMP][1] :
|
||||
in_type == out_type ? test_mat[OUTPUT][0] :
|
||||
test_mat[TEMP][0] );
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// FFT ////////////////////////
|
||||
class CxCore_DFTTest : public CxCore_DXTBaseTest
|
||||
{
|
||||
public:
|
||||
CxCore_DFTTest();
|
||||
protected:
|
||||
void run_func();
|
||||
void prepare_to_validation( int test_case_idx );
|
||||
};
|
||||
|
||||
|
||||
CxCore_DFTTest::CxCore_DFTTest() : CxCore_DXTBaseTest( true, true, false )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DFTTest::run_func()
|
||||
{
|
||||
Mat& dst = temp_dst ? test_mat[TEMP][1] : test_mat[OUTPUT][0];
|
||||
const Mat& src = inplace ? dst : test_mat[INPUT][0];
|
||||
|
||||
if(!(flags & CV_DXT_INVERSE))
|
||||
cv::dft( src, dst, flags );
|
||||
else
|
||||
cv::idft(src, dst, flags & ~CV_DXT_INVERSE);
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DFTTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
Mat& src = test_mat[INPUT][0];
|
||||
Mat& dst = test_mat[REF_OUTPUT][0];
|
||||
Mat* tmp_src = &src;
|
||||
Mat* tmp_dst = &dst;
|
||||
int src_cn = src.channels();
|
||||
int dst_cn = dst.channels();
|
||||
|
||||
if( src_cn != 2 || dst_cn != 2 )
|
||||
{
|
||||
tmp_src = &test_mat[TEMP][0];
|
||||
|
||||
if( !(flags & CV_DXT_INVERSE ) )
|
||||
{
|
||||
Mat& cvdft_dst = test_mat[TEMP][1];
|
||||
convertFromCCS( cvdft_dst, cvdft_dst,
|
||||
test_mat[OUTPUT][0], flags );
|
||||
*tmp_src = Scalar::all(0);
|
||||
cvtest::insert( src, *tmp_src, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
convertFromCCS( src, src, *tmp_src, flags );
|
||||
tmp_dst = &test_mat[TEMP][1];
|
||||
}
|
||||
}
|
||||
|
||||
if( src.rows == 1 || (src.cols == 1 && !(flags & CV_DXT_ROWS)) )
|
||||
DFT_1D( *tmp_src, *tmp_dst, flags );
|
||||
else
|
||||
DFT_2D( *tmp_src, *tmp_dst, flags );
|
||||
|
||||
if( tmp_dst != &dst )
|
||||
cvtest::extract( *tmp_dst, dst, 0 );
|
||||
}
|
||||
|
||||
////////////////////// DCT ////////////////////////
|
||||
class CxCore_DCTTest : public CxCore_DXTBaseTest
|
||||
{
|
||||
public:
|
||||
CxCore_DCTTest();
|
||||
protected:
|
||||
void run_func();
|
||||
void prepare_to_validation( int test_case_idx );
|
||||
};
|
||||
|
||||
|
||||
CxCore_DCTTest::CxCore_DCTTest() : CxCore_DXTBaseTest( false, false, false )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DCTTest::run_func()
|
||||
{
|
||||
Mat& dst = test_mat[OUTPUT][0];
|
||||
const Mat& src = inplace ? dst : test_mat[INPUT][0];
|
||||
|
||||
if(!(flags & CV_DXT_INVERSE))
|
||||
cv::dct( src, dst, flags );
|
||||
else
|
||||
cv::idct( src, dst, flags & ~CV_DXT_INVERSE);
|
||||
}
|
||||
|
||||
|
||||
void CxCore_DCTTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
const Mat& src = test_mat[INPUT][0];
|
||||
Mat& dst = test_mat[REF_OUTPUT][0];
|
||||
|
||||
if( src.rows == 1 || (src.cols == 1 && !(flags & CV_DXT_ROWS)) )
|
||||
DCT_1D( src, dst, flags );
|
||||
else
|
||||
DCT_2D( src, dst, flags );
|
||||
}
|
||||
|
||||
|
||||
////////////////////// MulSpectrums ////////////////////////
|
||||
class CxCore_MulSpectrumsTest : public CxCore_DXTBaseTest
|
||||
{
|
||||
public:
|
||||
CxCore_MulSpectrumsTest();
|
||||
protected:
|
||||
void run_func();
|
||||
void prepare_to_validation( int test_case_idx );
|
||||
double get_success_error_level( int test_case_idx, int i, int j );
|
||||
};
|
||||
|
||||
|
||||
CxCore_MulSpectrumsTest::CxCore_MulSpectrumsTest() : CxCore_DXTBaseTest( true, true, true )
|
||||
{
|
||||
}
|
||||
|
||||
double CxCore_MulSpectrumsTest::get_success_error_level( int test_case_idx, int i, int j )
|
||||
{
|
||||
CV_UNUSED(test_case_idx);
|
||||
CV_Assert(i == OUTPUT);
|
||||
CV_Assert(j == 0);
|
||||
int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j]));
|
||||
CV_Assert(elem_depth == CV_32F || elem_depth == CV_64F);
|
||||
|
||||
element_wise_relative_error = false;
|
||||
double maxInputValue = 1000; // ArrayTest::get_minmax_bounds
|
||||
double err = 8 * maxInputValue; // result = A*B + C*D
|
||||
return (elem_depth == CV_32F ? FLT_EPSILON : DBL_EPSILON) * err;
|
||||
}
|
||||
|
||||
void CxCore_MulSpectrumsTest::run_func()
|
||||
{
|
||||
Mat& dst = !test_mat[TEMP].empty() && !test_mat[TEMP][0].empty() ?
|
||||
test_mat[TEMP][0] : test_mat[OUTPUT][0];
|
||||
const Mat* src1 = &test_mat[INPUT][0], *src2 = &test_mat[INPUT][1];
|
||||
|
||||
if( inplace )
|
||||
{
|
||||
if( ts->get_current_test_info()->test_case_idx & 1 )
|
||||
src2 = &dst;
|
||||
else
|
||||
src1 = &dst;
|
||||
}
|
||||
|
||||
cv::mulSpectrums( *src1, *src2, dst, flags, (flags & CV_DXT_MUL_CONJ) != 0 );
|
||||
}
|
||||
|
||||
|
||||
void CxCore_MulSpectrumsTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
{
|
||||
Mat* src1 = &test_mat[INPUT][0];
|
||||
Mat* src2 = &test_mat[INPUT][1];
|
||||
Mat& dst = test_mat[OUTPUT][0];
|
||||
Mat& dst0 = test_mat[REF_OUTPUT][0];
|
||||
int cn = src1->channels();
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
convertFromCCS( *src1, *src1, dst, flags );
|
||||
convertFromCCS( *src2, *src2, dst0, flags );
|
||||
src1 = &dst;
|
||||
src2 = &dst0;
|
||||
}
|
||||
|
||||
mulComplex( *src1, *src2, dst0, flags );
|
||||
if( cn == 1 )
|
||||
{
|
||||
Mat& temp = test_mat[TEMP][0];
|
||||
convertFromCCS( temp, temp, dst, flags );
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_DCT, accuracy) { CxCore_DCTTest test; test.safe_run(); }
|
||||
TEST(Core_DFT, accuracy) { CxCore_DFTTest test; test.safe_run(); }
|
||||
TEST(Core_MulSpectrums, accuracy) { CxCore_MulSpectrumsTest test; test.safe_run(); }
|
||||
|
||||
class Core_DFTComplexOutputTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_DFTComplexOutputTest() {}
|
||||
~Core_DFTComplexOutputTest() {}
|
||||
protected:
|
||||
void run(int)
|
||||
{
|
||||
RNG& rng = theRNG();
|
||||
for( int i = 0; i < 10; i++ )
|
||||
{
|
||||
int m = rng.uniform(2, 11);
|
||||
int n = rng.uniform(2, 11);
|
||||
int depth = rng.uniform(0, 2) + CV_32F;
|
||||
Mat src8u(m, n, depth), src(m, n, depth), dst(m, n, CV_MAKETYPE(depth, 2));
|
||||
Mat z = Mat::zeros(m, n, depth), dstz;
|
||||
randu(src8u, Scalar::all(0), Scalar::all(10));
|
||||
src8u.convertTo(src, src.type());
|
||||
dst = Scalar::all(123);
|
||||
Mat mv[] = {src, z}, srcz;
|
||||
merge(mv, 2, srcz);
|
||||
dft(srcz, dstz);
|
||||
dft(src, dst, DFT_COMPLEX_OUTPUT);
|
||||
if (cvtest::norm(dst, dstz, NORM_INF) > 1e-3)
|
||||
{
|
||||
cout << "actual:\n" << dst << endl << endl;
|
||||
cout << "reference:\n" << dstz << endl << endl;
|
||||
CV_Error(CV_StsError, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_DFT, complex_output) { Core_DFTComplexOutputTest test; test.safe_run(); }
|
||||
|
||||
TEST(Core_DFT, complex_output2)
|
||||
{
|
||||
for( int i = 0; i < 100; i++ )
|
||||
{
|
||||
int type = theRNG().uniform(0, 2) ? CV_64F : CV_32F;
|
||||
int m = theRNG().uniform(1, 10);
|
||||
int n = theRNG().uniform(1, 10);
|
||||
Mat x(m, n, type), out;
|
||||
randu(x, -1., 1.);
|
||||
dft(x, out, DFT_ROWS | DFT_COMPLEX_OUTPUT);
|
||||
double nrm = cvtest::norm(out, NORM_INF);
|
||||
double thresh = n*m*2;
|
||||
if( nrm > thresh )
|
||||
{
|
||||
cout << "x: " << x << endl;
|
||||
cout << "out: " << out << endl;
|
||||
ASSERT_LT(nrm, thresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Core_DXTReverseTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
enum Mode
|
||||
{
|
||||
ModeDFT,
|
||||
ModeDCT
|
||||
};
|
||||
Core_DXTReverseTest(Mode m) : mode(m) {}
|
||||
private:
|
||||
Mode mode;
|
||||
protected:
|
||||
void run(int)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (mode == ModeDCT && i != 0)
|
||||
continue;
|
||||
int flags = 0;
|
||||
int flags_inv = DFT_INVERSE | DFT_SCALE;
|
||||
int cn_in = 0;
|
||||
int cn_out = 0;
|
||||
switch (i)
|
||||
{
|
||||
case 0: cn_in = 1; cn_out = 1; break;
|
||||
case 1: cn_in = 1; cn_out = 2; flags |= DFT_COMPLEX_OUTPUT; flags_inv |= DFT_REAL_OUTPUT; break;
|
||||
case 2: cn_in = 2; cn_out = 2; break;
|
||||
};
|
||||
for (int j = 0; j < 100; ++j)
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
int type = rng.uniform(0, 2) ? CV_64F : CV_32F;
|
||||
int m = rng.uniform(1, 10);
|
||||
int n = rng.uniform(1, 10);
|
||||
if (mode == ModeDCT)
|
||||
{
|
||||
m *= 2;
|
||||
n *= 2;
|
||||
}
|
||||
Mat one(m, n, CV_MAKETYPE(type, cn_in));
|
||||
cvtest::randUni(rng, one, Scalar::all(-1.), Scalar::all(1.));
|
||||
Mat out;
|
||||
Mat two;
|
||||
if (mode == ModeDFT)
|
||||
{
|
||||
cv::dft(one, out, flags);
|
||||
cv::dft(out, two, flags_inv);
|
||||
}
|
||||
else if (mode == ModeDCT)
|
||||
{
|
||||
cv::dct(one, out, flags);
|
||||
cv::dct(out, two, flags_inv);
|
||||
}
|
||||
if (out.channels() != cn_out || two.channels() != cn_in || cvtest::norm(one, two, NORM_INF) > 1e-5)
|
||||
{
|
||||
cout << "Test #" << j + 1 << " - "
|
||||
<< "elements: " << m << " x " << n << ", "
|
||||
<< "channels: "
|
||||
<< one.channels() << " (" << cn_in << ")" << " -> "
|
||||
<< out.channels() << " (" << cn_out << ")" << " -> "
|
||||
<< two.channels() << " (" << cn_in << ")"
|
||||
<< endl;
|
||||
cout << "signal:\n" << one << endl << endl;
|
||||
cout << "spectrum:\n" << out << endl << endl;
|
||||
cout << "inverse:\n" << two << endl << endl;
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_DFT, reverse) { Core_DXTReverseTest test(Core_DXTReverseTest::ModeDFT); test.safe_run(); }
|
||||
TEST(Core_DCT, reverse) { Core_DXTReverseTest test(Core_DXTReverseTest::ModeDCT); test.safe_run(); }
|
||||
|
||||
}} // namespace
|
545
3rdparty/opencv-4.5.4/modules/core/test/test_eigen.cpp
vendored
Normal file
545
3rdparty/opencv-4.5.4/modules/core/test/test_eigen.cpp
vendored
Normal file
@ -0,0 +1,545 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
#define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1
|
||||
|
||||
#define CORE_EIGEN_ERROR_COUNT 1
|
||||
#define CORE_EIGEN_ERROR_SIZE 2
|
||||
#define CORE_EIGEN_ERROR_DIFF 3
|
||||
#define CORE_EIGEN_ERROR_ORTHO 4
|
||||
#define CORE_EIGEN_ERROR_ORDER 5
|
||||
|
||||
#define MESSAGE_ERROR_COUNT "Matrix of eigen values must have the same rows as source matrix and 1 column."
|
||||
#define MESSAGE_ERROR_SIZE "Source matrix and matrix of eigen vectors must have the same sizes."
|
||||
#define MESSAGE_ERROR_DIFF_1 "Accuracy of eigen values computing less than required."
|
||||
#define MESSAGE_ERROR_DIFF_2 "Accuracy of eigen vectors computing less than required."
|
||||
#define MESSAGE_ERROR_ORTHO "Matrix of eigen vectors is not orthogonal."
|
||||
#define MESSAGE_ERROR_ORDER "Eigen values are not sorted in descending order."
|
||||
|
||||
const int COUNT_NORM_TYPES = 3;
|
||||
const int NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF};
|
||||
|
||||
enum TASK_TYPE_EIGEN {VALUES, VECTORS};
|
||||
|
||||
class Core_EigenTest: public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
|
||||
Core_EigenTest();
|
||||
~Core_EigenTest();
|
||||
|
||||
protected:
|
||||
|
||||
bool test_values(const cv::Mat& src); // complex test for eigen without vectors
|
||||
bool check_full(int type); // complex test for symmetric matrix
|
||||
virtual void run (int) = 0; // main testing method
|
||||
|
||||
protected:
|
||||
|
||||
float eps_val_32, eps_vec_32;
|
||||
float eps_val_64, eps_vec_64;
|
||||
int ntests;
|
||||
|
||||
bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index = -1, int high_index = -1);
|
||||
bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index = -1, int high_index = -1);
|
||||
bool check_pairs_order(const cv::Mat& eigen_values); // checking order of eigen values & vectors (it should be none up)
|
||||
bool check_orthogonality(const cv::Mat& U); // checking is matrix of eigen vectors orthogonal
|
||||
bool test_pairs(const cv::Mat& src); // complex test for eigen with vectors
|
||||
|
||||
void print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff);
|
||||
};
|
||||
|
||||
class Core_EigenTest_Scalar : public Core_EigenTest
|
||||
{
|
||||
public:
|
||||
Core_EigenTest_Scalar() : Core_EigenTest() {}
|
||||
~Core_EigenTest_Scalar();
|
||||
|
||||
virtual void run(int) = 0;
|
||||
};
|
||||
|
||||
class Core_EigenTest_Scalar_32 : public Core_EigenTest_Scalar
|
||||
{
|
||||
public:
|
||||
Core_EigenTest_Scalar_32() : Core_EigenTest_Scalar() {}
|
||||
~Core_EigenTest_Scalar_32();
|
||||
|
||||
void run(int);
|
||||
};
|
||||
|
||||
class Core_EigenTest_Scalar_64 : public Core_EigenTest_Scalar
|
||||
{
|
||||
public:
|
||||
Core_EigenTest_Scalar_64() : Core_EigenTest_Scalar() {}
|
||||
~Core_EigenTest_Scalar_64();
|
||||
void run(int);
|
||||
};
|
||||
|
||||
class Core_EigenTest_32 : public Core_EigenTest
|
||||
{
|
||||
public:
|
||||
Core_EigenTest_32(): Core_EigenTest() {}
|
||||
~Core_EigenTest_32() {}
|
||||
void run(int);
|
||||
};
|
||||
|
||||
class Core_EigenTest_64 : public Core_EigenTest
|
||||
{
|
||||
public:
|
||||
Core_EigenTest_64(): Core_EigenTest() {}
|
||||
~Core_EigenTest_64() {}
|
||||
void run(int);
|
||||
};
|
||||
|
||||
Core_EigenTest_Scalar::~Core_EigenTest_Scalar() {}
|
||||
Core_EigenTest_Scalar_32::~Core_EigenTest_Scalar_32() {}
|
||||
Core_EigenTest_Scalar_64::~Core_EigenTest_Scalar_64() {}
|
||||
|
||||
void Core_EigenTest_Scalar_32::run(int)
|
||||
{
|
||||
for (int i = 0; i < ntests; ++i)
|
||||
{
|
||||
float value = cv::randu<float>();
|
||||
cv::Mat src(1, 1, CV_32FC1, Scalar::all((float)value));
|
||||
test_values(src);
|
||||
}
|
||||
}
|
||||
|
||||
void Core_EigenTest_Scalar_64::run(int)
|
||||
{
|
||||
for (int i = 0; i < ntests; ++i)
|
||||
{
|
||||
float value = cv::randu<float>();
|
||||
cv::Mat src(1, 1, CV_64FC1, Scalar::all((double)value));
|
||||
test_values(src);
|
||||
}
|
||||
}
|
||||
|
||||
void Core_EigenTest_32::run(int) { check_full(CV_32FC1); }
|
||||
void Core_EigenTest_64::run(int) { check_full(CV_64FC1); }
|
||||
|
||||
Core_EigenTest::Core_EigenTest()
|
||||
: eps_val_32(1e-3f), eps_vec_32(1e-3f),
|
||||
eps_val_64(1e-4f), eps_vec_64(1e-4f), ntests(100) {}
|
||||
Core_EigenTest::~Core_EigenTest() {}
|
||||
|
||||
bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index, int high_index)
|
||||
{
|
||||
int n = src.rows, s = sign(high_index);
|
||||
if (!( (evalues.rows == n - max<int>(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)))) && (evalues.cols == 1)))
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl;
|
||||
std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl;
|
||||
std::cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
|
||||
CV_Error(CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index, int high_index)
|
||||
{
|
||||
int n = src.rows, s = sign(high_index);
|
||||
int right_eigen_pair_count = n - max<int>(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)));
|
||||
|
||||
if (!(evectors.rows == right_eigen_pair_count && evectors.cols == right_eigen_pair_count))
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking sizes of eigen vectors matrix " << evectors << "..." << endl;
|
||||
std::cout << "Number of rows: " << evectors.rows << " Number of cols: " << evectors.cols << endl;
|
||||
std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
|
||||
CV_Error (CORE_EIGEN_ERROR_SIZE, MESSAGE_ERROR_SIZE);
|
||||
}
|
||||
|
||||
if (!(evalues.rows == right_eigen_pair_count && evalues.cols == 1))
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl;
|
||||
std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl;
|
||||
std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
|
||||
CV_Error (CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Core_EigenTest::print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff)
|
||||
{
|
||||
switch (NORM_TYPE[norm_idx])
|
||||
{
|
||||
case cv::NORM_L1: std::cout << "L1"; break;
|
||||
case cv::NORM_L2: std::cout << "L2"; break;
|
||||
case cv::NORM_INF: std::cout << "INF"; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
cout << "-criteria... " << endl;
|
||||
cout << "Source size: " << src.rows << " * " << src.cols << endl;
|
||||
cout << "Difference between original eigen vectors matrix and result: " << diff << endl;
|
||||
cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
bool Core_EigenTest::check_orthogonality(const cv::Mat& U)
|
||||
{
|
||||
int type = U.type();
|
||||
double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64;
|
||||
cv::Mat UUt; cv::mulTransposed(U, UUt, false);
|
||||
|
||||
cv::Mat E = Mat::eye(U.rows, U.cols, type);
|
||||
|
||||
for (int i = 0; i < COUNT_NORM_TYPES; ++i)
|
||||
{
|
||||
double diff = cvtest::norm(UUt, E, NORM_TYPE[i] | cv::NORM_RELATIVE);
|
||||
if (diff > eps_vec)
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking orthogonality of matrix " << U << ": ";
|
||||
print_information(i, U, diff, eps_vec);
|
||||
CV_Error(CORE_EIGEN_ERROR_ORTHO, MESSAGE_ERROR_ORTHO);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values)
|
||||
{
|
||||
switch (eigen_values.type())
|
||||
{
|
||||
case CV_32FC1:
|
||||
{
|
||||
for (int i = 0; i < (int)(eigen_values.total() - 1); ++i)
|
||||
if (!(eigen_values.at<float>(i, 0) > eigen_values.at<float>(i+1, 0)))
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl;
|
||||
std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
|
||||
std::cout << endl;
|
||||
CV_Error(CORE_EIGEN_ERROR_ORDER, MESSAGE_ERROR_ORDER);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CV_64FC1:
|
||||
{
|
||||
for (int i = 0; i < (int)(eigen_values.total() - 1); ++i)
|
||||
if (!(eigen_values.at<double>(i, 0) > eigen_values.at<double>(i+1, 0)))
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl;
|
||||
std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
|
||||
std::cout << endl;
|
||||
CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in descending order.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core_EigenTest::test_pairs(const cv::Mat& src)
|
||||
{
|
||||
int type = src.type();
|
||||
double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64;
|
||||
|
||||
cv::Mat eigen_values, eigen_vectors;
|
||||
|
||||
cv::eigen(src, eigen_values, eigen_vectors);
|
||||
|
||||
if (!check_pair_count(src, eigen_values, eigen_vectors))
|
||||
return false;
|
||||
|
||||
if (!check_orthogonality (eigen_vectors))
|
||||
return false;
|
||||
|
||||
if (!check_pairs_order(eigen_values))
|
||||
return false;
|
||||
|
||||
cv::Mat eigen_vectors_t; cv::transpose(eigen_vectors, eigen_vectors_t);
|
||||
|
||||
// Check:
|
||||
// src * eigenvector = eigenval * eigenvector
|
||||
cv::Mat lhs(src.rows, src.cols, type);
|
||||
cv::Mat rhs(src.rows, src.cols, type);
|
||||
|
||||
lhs = src*eigen_vectors_t;
|
||||
|
||||
for (int i = 0; i < src.cols; ++i)
|
||||
{
|
||||
double eigenval = 0;
|
||||
switch (type)
|
||||
{
|
||||
case CV_32FC1: eigenval = eigen_values.at<float>(i, 0); break;
|
||||
case CV_64FC1: eigenval = eigen_values.at<double>(i, 0); break;
|
||||
}
|
||||
cv::Mat rhs_v = eigenval * eigen_vectors_t.col(i);
|
||||
rhs_v.copyTo(rhs.col(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < COUNT_NORM_TYPES; ++i)
|
||||
{
|
||||
double diff = cvtest::norm(lhs, rhs, NORM_TYPE[i] | cv::NORM_RELATIVE);
|
||||
if (diff > eps_vec)
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": ";
|
||||
print_information(i, src, diff, eps_vec);
|
||||
CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_2);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core_EigenTest::test_values(const cv::Mat& src)
|
||||
{
|
||||
int type = src.type();
|
||||
double eps_val = type == CV_32FC1 ? eps_val_32 : eps_val_64;
|
||||
|
||||
cv::Mat eigen_values_1, eigen_values_2, eigen_vectors;
|
||||
|
||||
if (!test_pairs(src)) return false;
|
||||
|
||||
cv::eigen(src, eigen_values_1, eigen_vectors);
|
||||
cv::eigen(src, eigen_values_2);
|
||||
|
||||
if (!check_pair_count(src, eigen_values_2)) return false;
|
||||
|
||||
for (int i = 0; i < COUNT_NORM_TYPES; ++i)
|
||||
{
|
||||
double diff = cvtest::norm(eigen_values_1, eigen_values_2, NORM_TYPE[i] | cv::NORM_RELATIVE);
|
||||
if (diff > eps_val)
|
||||
{
|
||||
std::cout << endl; std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": ";
|
||||
print_information(i, src, diff, eps_val);
|
||||
CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core_EigenTest::check_full(int type)
|
||||
{
|
||||
const int MAX_DEGREE = 7;
|
||||
|
||||
RNG rng = cv::theRNG(); // fix the seed
|
||||
|
||||
for (int i = 0; i < ntests; ++i)
|
||||
{
|
||||
int src_size = (int)(std::pow(2.0, (rng.uniform(0, MAX_DEGREE) + 1.)));
|
||||
|
||||
cv::Mat src(src_size, src_size, type);
|
||||
|
||||
for (int j = 0; j < src.rows; ++j)
|
||||
for (int k = j; k < src.cols; ++k)
|
||||
if (type == CV_32FC1) src.at<float>(k, j) = src.at<float>(j, k) = cv::randu<float>();
|
||||
else src.at<double>(k, j) = src.at<double>(j, k) = cv::randu<double>();
|
||||
|
||||
if (!test_values(src)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(Core_Eigen, scalar_32) {Core_EigenTest_Scalar_32 test; test.safe_run(); }
|
||||
TEST(Core_Eigen, scalar_64) {Core_EigenTest_Scalar_64 test; test.safe_run(); }
|
||||
TEST(Core_Eigen, vector_32) { Core_EigenTest_32 test; test.safe_run(); }
|
||||
TEST(Core_Eigen, vector_64) { Core_EigenTest_64 test; test.safe_run(); }
|
||||
|
||||
template<typename T>
|
||||
static void testEigen(const Mat_<T>& src, const Mat_<T>& expected_eigenvalues, bool runSymmetric = false)
|
||||
{
|
||||
SCOPED_TRACE(runSymmetric ? "cv::eigen" : "cv::eigenNonSymmetric");
|
||||
|
||||
int type = traits::Type<T>::value;
|
||||
const T eps = src.type() == CV_32F ? 1e-4f : 1e-6f;
|
||||
|
||||
Mat eigenvalues, eigenvectors, eigenvalues0;
|
||||
|
||||
if (runSymmetric)
|
||||
{
|
||||
cv::eigen(src, eigenvalues0, noArray());
|
||||
cv::eigen(src, eigenvalues, eigenvectors);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::eigenNonSymmetric(src, eigenvalues0, noArray());
|
||||
cv::eigenNonSymmetric(src, eigenvalues, eigenvectors);
|
||||
}
|
||||
#if 0
|
||||
std::cout << "src = " << src << std::endl;
|
||||
std::cout << "eigenvalues.t() = " << eigenvalues.t() << std::endl;
|
||||
std::cout << "eigenvectors = " << eigenvectors << std::endl;
|
||||
#endif
|
||||
ASSERT_EQ(type, eigenvalues0.type());
|
||||
ASSERT_EQ(type, eigenvalues.type());
|
||||
ASSERT_EQ(type, eigenvectors.type());
|
||||
|
||||
ASSERT_EQ(src.rows, eigenvalues.rows);
|
||||
ASSERT_EQ(eigenvalues.rows, eigenvectors.rows);
|
||||
ASSERT_EQ(src.rows, eigenvectors.cols);
|
||||
|
||||
EXPECT_LT(cvtest::norm(eigenvalues, eigenvalues0, NORM_INF), eps);
|
||||
|
||||
// check definition: src*eigenvectors.row(i).t() = eigenvalues.at<srcType>(i)*eigenvectors.row(i).t()
|
||||
for (int i = 0; i < src.rows; i++)
|
||||
{
|
||||
EXPECT_NEAR(eigenvalues.at<T>(i), expected_eigenvalues(i), eps) << "i=" << i;
|
||||
Mat lhs = src*eigenvectors.row(i).t();
|
||||
Mat rhs = eigenvalues.at<T>(i)*eigenvectors.row(i).t();
|
||||
EXPECT_LT(cvtest::norm(lhs, rhs, NORM_INF), eps)
|
||||
<< "i=" << i << " eigenvalue=" << eigenvalues.at<T>(i) << std::endl
|
||||
<< "lhs=" << lhs.t() << std::endl
|
||||
<< "rhs=" << rhs.t();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void testEigenSymmetric3x3()
|
||||
{
|
||||
/*const*/ T values_[] = {
|
||||
2, -1, 0,
|
||||
-1, 2, -1,
|
||||
0, -1, 2
|
||||
};
|
||||
Mat_<T> src(3, 3, values_);
|
||||
|
||||
/*const*/ T expected_eigenvalues_[] = { 3.414213562373095f, 2, 0.585786437626905f };
|
||||
Mat_<T> expected_eigenvalues(3, 1, expected_eigenvalues_);
|
||||
|
||||
testEigen(src, expected_eigenvalues);
|
||||
testEigen(src, expected_eigenvalues, true);
|
||||
}
|
||||
TEST(Core_EigenSymmetric, float3x3) { testEigenSymmetric3x3<float>(); }
|
||||
TEST(Core_EigenSymmetric, double3x3) { testEigenSymmetric3x3<double>(); }
|
||||
|
||||
template<typename T>
|
||||
static void testEigenSymmetric5x5()
|
||||
{
|
||||
/*const*/ T values_[5*5] = {
|
||||
5, -1, 0, 2, 1,
|
||||
-1, 4, -1, 0, 0,
|
||||
0, -1, 3, 1, -1,
|
||||
2, 0, 1, 4, 0,
|
||||
1, 0, -1, 0, 1
|
||||
};
|
||||
Mat_<T> src(5, 5, values_);
|
||||
|
||||
/*const*/ T expected_eigenvalues_[] = { 7.028919644935684f, 4.406130784616501f, 3.73626552682258f, 1.438067799899037f, 0.390616243726198f };
|
||||
Mat_<T> expected_eigenvalues(5, 1, expected_eigenvalues_);
|
||||
|
||||
testEigen(src, expected_eigenvalues);
|
||||
testEigen(src, expected_eigenvalues, true);
|
||||
}
|
||||
TEST(Core_EigenSymmetric, float5x5) { testEigenSymmetric5x5<float>(); }
|
||||
TEST(Core_EigenSymmetric, double5x5) { testEigenSymmetric5x5<double>(); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
static void testEigen2x2()
|
||||
{
|
||||
/*const*/ T values_[] = { 4, 1, 6, 3 };
|
||||
Mat_<T> src(2, 2, values_);
|
||||
|
||||
/*const*/ T expected_eigenvalues_[] = { 6, 1 };
|
||||
Mat_<T> expected_eigenvalues(2, 1, expected_eigenvalues_);
|
||||
|
||||
testEigen(src, expected_eigenvalues);
|
||||
}
|
||||
TEST(Core_EigenNonSymmetric, float2x2) { testEigen2x2<float>(); }
|
||||
TEST(Core_EigenNonSymmetric, double2x2) { testEigen2x2<double>(); }
|
||||
|
||||
template<typename T>
|
||||
static void testEigen3x3()
|
||||
{
|
||||
/*const*/ T values_[3*3] = {
|
||||
3,1,0,
|
||||
0,3,1,
|
||||
0,0,3
|
||||
};
|
||||
Mat_<T> src(3, 3, values_);
|
||||
|
||||
/*const*/ T expected_eigenvalues_[] = { 3, 3, 3 };
|
||||
Mat_<T> expected_eigenvalues(3, 1, expected_eigenvalues_);
|
||||
|
||||
testEigen(src, expected_eigenvalues);
|
||||
}
|
||||
TEST(Core_EigenNonSymmetric, float3x3) { testEigen3x3<float>(); }
|
||||
TEST(Core_EigenNonSymmetric, double3x3) { testEigen3x3<double>(); }
|
||||
|
||||
typedef testing::TestWithParam<int> Core_EigenZero;
|
||||
TEST_P(Core_EigenZero, double)
|
||||
{
|
||||
int N = GetParam();
|
||||
Mat_<double> srcZero = Mat_<double>::zeros(N, N);
|
||||
Mat_<double> expected_eigenvalueZero = Mat_<double>::zeros(N, 1); // 1D Mat
|
||||
testEigen(srcZero, expected_eigenvalueZero);
|
||||
testEigen(srcZero, expected_eigenvalueZero, true);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Core_EigenZero, testing::Values(2, 3, 5));
|
||||
|
||||
TEST(Core_EigenNonSymmetric, convergence)
|
||||
{
|
||||
Matx33d m(
|
||||
0, -1, 0,
|
||||
1, 0, 1,
|
||||
0, -1, 0);
|
||||
Mat eigenvalues, eigenvectors;
|
||||
// eigen values are complex, algorithm doesn't converge
|
||||
try
|
||||
{
|
||||
cv::eigenNonSymmetric(m, eigenvalues, eigenvectors);
|
||||
std::cout << Mat(eigenvalues.t()) << std::endl;
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_EQ(Error::StsNoConv, e.code) << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unknown exception has been raised";
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
205
3rdparty/opencv-4.5.4/modules/core/test/test_hal_core.cpp
vendored
Normal file
205
3rdparty/opencv-4.5.4/modules/core/test/test_hal_core.cpp
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
enum
|
||||
{
|
||||
HAL_EXP = 0,
|
||||
HAL_LOG = 1,
|
||||
HAL_SQRT = 2
|
||||
};
|
||||
|
||||
TEST(Core_HAL, mathfuncs)
|
||||
{
|
||||
for( int hcase = 0; hcase < 6; hcase++ )
|
||||
{
|
||||
int depth = hcase % 2 == 0 ? CV_32F : CV_64F;
|
||||
double eps = depth == CV_32F ? 1e-5 : 1e-10;
|
||||
int nfunc = hcase / 2;
|
||||
int n = 100;
|
||||
|
||||
Mat src(1, n, depth), dst(1, n, depth), dst0(1, n, depth);
|
||||
randu(src, 1, 10);
|
||||
|
||||
double min_hal_t = DBL_MAX, min_ocv_t = DBL_MAX;
|
||||
|
||||
for( int iter = 0; iter < 10; iter++ )
|
||||
{
|
||||
double t = (double)getTickCount();
|
||||
switch (nfunc)
|
||||
{
|
||||
case HAL_EXP:
|
||||
if( depth == CV_32F )
|
||||
hal::exp32f(src.ptr<float>(), dst.ptr<float>(), n);
|
||||
else
|
||||
hal::exp64f(src.ptr<double>(), dst.ptr<double>(), n);
|
||||
break;
|
||||
case HAL_LOG:
|
||||
if( depth == CV_32F )
|
||||
hal::log32f(src.ptr<float>(), dst.ptr<float>(), n);
|
||||
else
|
||||
hal::log64f(src.ptr<double>(), dst.ptr<double>(), n);
|
||||
break;
|
||||
case HAL_SQRT:
|
||||
if( depth == CV_32F )
|
||||
hal::sqrt32f(src.ptr<float>(), dst.ptr<float>(), n);
|
||||
else
|
||||
hal::sqrt64f(src.ptr<double>(), dst.ptr<double>(), n);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "unknown function");
|
||||
}
|
||||
t = (double)getTickCount() - t;
|
||||
min_hal_t = std::min(min_hal_t, t);
|
||||
|
||||
t = (double)getTickCount();
|
||||
switch (nfunc)
|
||||
{
|
||||
case HAL_EXP:
|
||||
exp(src, dst0);
|
||||
break;
|
||||
case HAL_LOG:
|
||||
log(src, dst0);
|
||||
break;
|
||||
case HAL_SQRT:
|
||||
pow(src, 0.5, dst0);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "unknown function");
|
||||
}
|
||||
t = (double)getTickCount() - t;
|
||||
min_ocv_t = std::min(min_ocv_t, t);
|
||||
}
|
||||
EXPECT_LE(cvtest::norm(dst, dst0, NORM_INF | NORM_RELATIVE), eps);
|
||||
|
||||
double freq = getTickFrequency();
|
||||
printf("%s (N=%d, %s): hal time=%.2fusec, ocv time=%.2fusec\n",
|
||||
(nfunc == HAL_EXP ? "exp" : nfunc == HAL_LOG ? "log" : nfunc == HAL_SQRT ? "sqrt" : "???"),
|
||||
n, (depth == CV_32F ? "f32" : "f64"), min_hal_t*1e6/freq, min_ocv_t*1e6/freq);
|
||||
}
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
HAL_LU = 0,
|
||||
HAL_CHOL = 1
|
||||
};
|
||||
|
||||
typedef testing::TestWithParam<int> HAL;
|
||||
|
||||
TEST_P(HAL, mat_decomp)
|
||||
{
|
||||
int hcase = GetParam();
|
||||
SCOPED_TRACE(cv::format("hcase=%d", hcase));
|
||||
{
|
||||
int depth = hcase % 2 == 0 ? CV_32F : CV_64F;
|
||||
int size = (hcase / 2) % 4;
|
||||
size = size == 0 ? 3 : size == 1 ? 4 : size == 2 ? 6 : 15;
|
||||
int nfunc = (hcase / 8);
|
||||
double eps = depth == CV_32F ? 1e-5 : 1e-10;
|
||||
|
||||
if( size == 3 )
|
||||
return; // TODO ???
|
||||
|
||||
Mat a0(size, size, depth), a(size, size, depth), b(size, 1, depth), x(size, 1, depth), x0(size, 1, depth);
|
||||
randu(a0, -1, 1);
|
||||
a0 = a0*a0.t();
|
||||
randu(b, -1, 1);
|
||||
|
||||
double min_hal_t = DBL_MAX, min_ocv_t = DBL_MAX;
|
||||
size_t asize = size*size*a.elemSize();
|
||||
size_t bsize = size*b.elemSize();
|
||||
|
||||
for( int iter = 0; iter < 10; iter++ )
|
||||
{
|
||||
memcpy(x.ptr(), b.ptr(), bsize);
|
||||
memcpy(a.ptr(), a0.ptr(), asize);
|
||||
|
||||
double t = (double)getTickCount();
|
||||
switch (nfunc)
|
||||
{
|
||||
case HAL_LU:
|
||||
if( depth == CV_32F )
|
||||
hal::LU32f(a.ptr<float>(), a.step, size, x.ptr<float>(), x.step, 1);
|
||||
else
|
||||
hal::LU64f(a.ptr<double>(), a.step, size, x.ptr<double>(), x.step, 1);
|
||||
break;
|
||||
case HAL_CHOL:
|
||||
if( depth == CV_32F )
|
||||
hal::Cholesky32f(a.ptr<float>(), a.step, size, x.ptr<float>(), x.step, 1);
|
||||
else
|
||||
hal::Cholesky64f(a.ptr<double>(), a.step, size, x.ptr<double>(), x.step, 1);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "unknown function");
|
||||
}
|
||||
t = (double)getTickCount() - t;
|
||||
min_hal_t = std::min(min_hal_t, t);
|
||||
|
||||
t = (double)getTickCount();
|
||||
bool solveStatus = solve(a0, b, x0, (nfunc == HAL_LU ? DECOMP_LU : DECOMP_CHOLESKY));
|
||||
t = (double)getTickCount() - t;
|
||||
EXPECT_TRUE(solveStatus);
|
||||
min_ocv_t = std::min(min_ocv_t, t);
|
||||
}
|
||||
//std::cout << "x: " << Mat(x.t()) << std::endl;
|
||||
//std::cout << "x0: " << Mat(x0.t()) << std::endl;
|
||||
|
||||
EXPECT_LE(cvtest::norm(x, x0, NORM_INF | NORM_RELATIVE), eps)
|
||||
<< "x: " << Mat(x.t())
|
||||
<< "\nx0: " << Mat(x0.t())
|
||||
<< "\na0: " << a0
|
||||
<< "\nb: " << b;
|
||||
|
||||
double freq = getTickFrequency();
|
||||
printf("%s (%d x %d, %s): hal time=%.2fusec, ocv time=%.2fusec\n",
|
||||
(nfunc == HAL_LU ? "LU" : nfunc == HAL_CHOL ? "Cholesky" : "???"),
|
||||
size, size,
|
||||
(depth == CV_32F ? "f32" : "f64"),
|
||||
min_hal_t*1e6/freq, min_ocv_t*1e6/freq);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Core, HAL, testing::Range(0, 16));
|
||||
|
||||
}} // namespace
|
156
3rdparty/opencv-4.5.4/modules/core/test/test_intrin.cpp
vendored
Normal file
156
3rdparty/opencv-4.5.4/modules/core/test/test_intrin.cpp
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#include "test_intrin128.simd.hpp"
|
||||
|
||||
// see "test_intrin_emulator.cpp"
|
||||
// see "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
|
||||
#define CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
#undef CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
#undef CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
#define CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN namespace opt_EMULATOR_CPP {
|
||||
#define CV_CPU_OPTIMIZATION_NAMESPACE_END }
|
||||
#include "test_intrin128.simd.hpp"
|
||||
#undef CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
#undef CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
#undef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
#include "test_intrin128.simd_declarations.hpp"
|
||||
|
||||
#undef CV_CPU_DISPATCH_MODES_ALL
|
||||
#include "opencv2/core/cv_cpu_dispatch.h"
|
||||
#include "test_intrin256.simd.hpp"
|
||||
#include "test_intrin256.simd_declarations.hpp"
|
||||
|
||||
#undef CV_CPU_DISPATCH_MODES_ALL
|
||||
#include "opencv2/core/cv_cpu_dispatch.h"
|
||||
#include "test_intrin512.simd.hpp"
|
||||
#include "test_intrin512.simd_declarations.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable:4702) // unreachable code
|
||||
#endif
|
||||
|
||||
namespace opencv_test { namespace hal {
|
||||
|
||||
#define CV_CPU_CALL_CPP_EMULATOR_(fn, args) return (opt_EMULATOR_CPP::fn args)
|
||||
|
||||
#define CV_CPU_CALL_BASELINE_(fn, args) CV_CPU_CALL_BASELINE(fn, args)
|
||||
|
||||
#define DISPATCH_SIMD128(fn, cpu_opt) do { \
|
||||
CV_CPU_CALL_ ## cpu_opt ## _(fn, ()); \
|
||||
throw SkipTestException("SIMD128 (" #cpu_opt ") is not available or disabled"); \
|
||||
} while(0)
|
||||
|
||||
#define DISPATCH_SIMD256(fn, cpu_opt) do { \
|
||||
CV_CPU_CALL_ ## cpu_opt ## _(fn, ()); \
|
||||
throw SkipTestException("SIMD256 (" #cpu_opt ") is not available or disabled"); \
|
||||
} while(0)
|
||||
|
||||
#define DISPATCH_SIMD512(fn, cpu_opt) do { \
|
||||
CV_CPU_CALL_ ## cpu_opt ## _(fn, ()); \
|
||||
throw SkipTestException("SIMD512 (" #cpu_opt ") is not available or disabled"); \
|
||||
} while(0)
|
||||
|
||||
#define DEFINE_SIMD_TESTS(simd_size, cpu_opt) \
|
||||
TEST(hal_intrin ## simd_size, uint8x16_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint8, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, int8x16_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int8, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, uint16x8_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint16, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, int16x8_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int16, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, int32x4_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int32, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, uint32x4_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint32, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, uint64x2_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint64, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, int64x2_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int64, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, float32x4_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_float32, cpu_opt); } \
|
||||
TEST(hal_intrin ## simd_size, float64x2_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_float64, cpu_opt); } \
|
||||
|
||||
namespace intrin128 {
|
||||
|
||||
DEFINE_SIMD_TESTS(128, CPP_EMULATOR)
|
||||
|
||||
DEFINE_SIMD_TESTS(128, BASELINE)
|
||||
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_SSE2 || defined CV_CPU_BASELINE_COMPILE_SSE2
|
||||
DEFINE_SIMD_TESTS(128, SSE2)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_SSE3 || defined CV_CPU_BASELINE_COMPILE_SSE3
|
||||
DEFINE_SIMD_TESTS(128, SSE3)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_SSSE3 || defined CV_CPU_BASELINE_COMPILE_SSSE3
|
||||
DEFINE_SIMD_TESTS(128, SSSE3)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_SSE4_1 || defined CV_CPU_BASELINE_COMPILE_SSE4_1
|
||||
DEFINE_SIMD_TESTS(128, SSE4_1)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_SSE4_2 || defined CV_CPU_BASELINE_COMPILE_SSE4_2
|
||||
DEFINE_SIMD_TESTS(128, SSE4_2)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_AVX || defined CV_CPU_BASELINE_COMPILE_AVX
|
||||
DEFINE_SIMD_TESTS(128, AVX)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_AVX2 || defined CV_CPU_BASELINE_COMPILE_AVX2
|
||||
DEFINE_SIMD_TESTS(128, AVX2)
|
||||
#endif
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_AVX512_SKX || defined CV_CPU_BASELINE_COMPILE_AVX512_SKX
|
||||
DEFINE_SIMD_TESTS(128, AVX512_SKX)
|
||||
#endif
|
||||
|
||||
TEST(hal_intrin128, float16x8_FP16)
|
||||
{
|
||||
CV_CPU_CALL_FP16_(test_hal_intrin_float16, ());
|
||||
throw SkipTestException("Unsupported hardware: FP16 is not available");
|
||||
}
|
||||
|
||||
} // namespace intrin128
|
||||
|
||||
|
||||
namespace intrin256 {
|
||||
|
||||
|
||||
// Not available due missing C++ backend for SIMD256
|
||||
//DEFINE_SIMD_TESTS(256, BASELINE)
|
||||
|
||||
//#if defined CV_CPU_DISPATCH_COMPILE_AVX
|
||||
//DEFINE_SIMD_TESTS(256, AVX)
|
||||
//#endif
|
||||
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_AVX2 || defined CV_CPU_BASELINE_COMPILE_AVX2
|
||||
DEFINE_SIMD_TESTS(256, AVX2)
|
||||
#endif
|
||||
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_AVX512_SKX || defined CV_CPU_BASELINE_COMPILE_AVX512_SKX
|
||||
DEFINE_SIMD_TESTS(256, AVX512_SKX)
|
||||
#endif
|
||||
|
||||
TEST(hal_intrin256, float16x16_FP16)
|
||||
{
|
||||
#if CV_TRY_FP16
|
||||
//CV_CPU_CALL_FP16_(test_hal_intrin_float16, ());
|
||||
CV_CPU_CALL_AVX2_(test_hal_intrin_float16, ());
|
||||
#endif
|
||||
throw SkipTestException("Unsupported: FP16 is not available");
|
||||
}
|
||||
|
||||
|
||||
} // namespace intrin256
|
||||
|
||||
namespace intrin512 {
|
||||
|
||||
#if defined CV_CPU_DISPATCH_COMPILE_AVX512_SKX || defined CV_CPU_BASELINE_COMPILE_AVX512_SKX
|
||||
DEFINE_SIMD_TESTS(512, AVX512_SKX)
|
||||
#endif
|
||||
|
||||
TEST(hal_intrin512, float16x32_FP16)
|
||||
{
|
||||
#if CV_TRY_FP16
|
||||
CV_CPU_CALL_AVX512_SKX_(test_hal_intrin_float16, ());
|
||||
#endif
|
||||
throw SkipTestException("Unsupported: FP16 is not available");
|
||||
}
|
||||
|
||||
|
||||
} // namespace intrin512
|
||||
|
||||
}} // namespace
|
22
3rdparty/opencv-4.5.4/modules/core/test/test_intrin128.simd.hpp
vendored
Normal file
22
3rdparty/opencv-4.5.4/modules/core/test/test_intrin128.simd.hpp
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
#define CV__SIMD_FORCE_WIDTH 128
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#undef CV__SIMD_FORCE_WIDTH
|
||||
|
||||
#if CV_SIMD_WIDTH != 16
|
||||
#error "Invalid build configuration"
|
||||
#endif
|
||||
|
||||
#endif // CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
namespace opencv_test { namespace hal { namespace intrin128 {
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
|
||||
#include "test_intrin_utils.hpp"
|
||||
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
}}} //namespace
|
23
3rdparty/opencv-4.5.4/modules/core/test/test_intrin256.simd.hpp
vendored
Normal file
23
3rdparty/opencv-4.5.4/modules/core/test/test_intrin256.simd.hpp
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#if !defined CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY && \
|
||||
!defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS // TODO? C++ fallback implementation for SIMD256
|
||||
|
||||
#define CV__SIMD_FORCE_WIDTH 256
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#undef CV__SIMD_FORCE_WIDTH
|
||||
|
||||
#if CV_SIMD_WIDTH != 32
|
||||
#error "Invalid build configuration"
|
||||
#endif
|
||||
|
||||
#endif // CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
namespace opencv_test { namespace hal { namespace intrin256 {
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
|
||||
#include "test_intrin_utils.hpp"
|
||||
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
}}} //namespace
|
23
3rdparty/opencv-4.5.4/modules/core/test/test_intrin512.simd.hpp
vendored
Normal file
23
3rdparty/opencv-4.5.4/modules/core/test/test_intrin512.simd.hpp
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#if !defined CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY && \
|
||||
!defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS // TODO? C++ fallback implementation for SIMD512
|
||||
|
||||
#define CV__SIMD_FORCE_WIDTH 512
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#undef CV__SIMD_FORCE_WIDTH
|
||||
|
||||
#if CV_SIMD_WIDTH != 64
|
||||
#error "Invalid build configuration"
|
||||
#endif
|
||||
|
||||
#endif // CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
namespace opencv_test { namespace hal { namespace intrin512 {
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
|
||||
#include "test_intrin_utils.hpp"
|
||||
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
}}} //namespace
|
16
3rdparty/opencv-4.5.4/modules/core/test/test_intrin_emulator.cpp
vendored
Normal file
16
3rdparty/opencv-4.5.4/modules/core/test/test_intrin_emulator.cpp
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
// see "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
|
||||
//#define CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
#undef CV_FORCE_SIMD128_CPP
|
||||
#define CV_FORCE_SIMD128_CPP 1
|
||||
#undef CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
#undef CV_CPU_OPTIMIZATION_NAMESPACE_END
|
||||
#define CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN namespace opt_EMULATOR_CPP {
|
||||
#define CV_CPU_OPTIMIZATION_NAMESPACE_END }
|
||||
#include "test_intrin128.simd.hpp"
|
||||
|
||||
// tests implementation is in test_intrin_utils.hpp
|
1955
3rdparty/opencv-4.5.4/modules/core/test/test_intrin_utils.hpp
vendored
Normal file
1955
3rdparty/opencv-4.5.4/modules/core/test/test_intrin_utils.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1922
3rdparty/opencv-4.5.4/modules/core/test/test_io.cpp
vendored
Normal file
1922
3rdparty/opencv-4.5.4/modules/core/test/test_io.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
281
3rdparty/opencv-4.5.4/modules/core/test/test_logtagconfigparser.cpp
vendored
Normal file
281
3rdparty/opencv-4.5.4/modules/core/test/test_logtagconfigparser.cpp
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
#include "../src/utils/logtagmanager.hpp"
|
||||
#include "../src/utils/logtagconfigparser.hpp"
|
||||
|
||||
// Because "LogTagConfigParser" isn't exported from "opencv_core", the only way
|
||||
// to perform test is to compile the source code into "opencv_test_core".
|
||||
// This workaround may cause step debugger breakpoints to work unreliably.
|
||||
#if 1
|
||||
#include "../src/utils/logtagconfigparser.cpp"
|
||||
#endif
|
||||
|
||||
using cv::utils::logging::LogTagConfigParser;
|
||||
|
||||
namespace opencv_test {
|
||||
namespace {
|
||||
|
||||
typedef testing::TestWithParam<tuple<std::string, cv::utils::logging::LogLevel>> GlobalShouldSucceedTests;
|
||||
|
||||
TEST_P(GlobalShouldSucceedTests, globalCases)
|
||||
{
|
||||
const std::string input = get<0>(GetParam());
|
||||
const cv::utils::logging::LogLevel expectedLevel = get<1>(GetParam());
|
||||
LogTagConfigParser parser;
|
||||
parser.parse(input);
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u) << "Malformed list should be empty";
|
||||
EXPECT_TRUE(parser.getGlobalConfig().isGlobal);
|
||||
EXPECT_EQ(parser.getGlobalConfig().level, expectedLevel);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u) << "Specifying global log level should not emit full names";
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u) << "Specifying global log level should not emit first name part result";
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u) << "Specifying global log level should not emit any name part result";
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Core_LogTagConfigParser, GlobalShouldSucceedTests,
|
||||
testing::Values(
|
||||
// Following test cases omit the name part
|
||||
std::make_tuple("S", cv::utils::logging::LOG_LEVEL_SILENT),
|
||||
std::make_tuple("SILENT", cv::utils::logging::LOG_LEVEL_SILENT),
|
||||
std::make_tuple("F", cv::utils::logging::LOG_LEVEL_FATAL),
|
||||
std::make_tuple("FATAL", cv::utils::logging::LOG_LEVEL_FATAL),
|
||||
std::make_tuple("E", cv::utils::logging::LOG_LEVEL_ERROR),
|
||||
std::make_tuple("ERROR", cv::utils::logging::LOG_LEVEL_ERROR),
|
||||
std::make_tuple("W", cv::utils::logging::LOG_LEVEL_WARNING),
|
||||
std::make_tuple("WARN", cv::utils::logging::LOG_LEVEL_WARNING),
|
||||
std::make_tuple("WARNING", cv::utils::logging::LOG_LEVEL_WARNING),
|
||||
std::make_tuple("I", cv::utils::logging::LOG_LEVEL_INFO),
|
||||
std::make_tuple("INFO", cv::utils::logging::LOG_LEVEL_INFO),
|
||||
std::make_tuple("D", cv::utils::logging::LOG_LEVEL_DEBUG),
|
||||
std::make_tuple("DEBUG", cv::utils::logging::LOG_LEVEL_DEBUG),
|
||||
std::make_tuple("V", cv::utils::logging::LOG_LEVEL_VERBOSE),
|
||||
std::make_tuple("VERBOSE", cv::utils::logging::LOG_LEVEL_VERBOSE),
|
||||
// Following test cases uses a single asterisk as name
|
||||
std::make_tuple("*:S", cv::utils::logging::LOG_LEVEL_SILENT),
|
||||
std::make_tuple("*:SILENT", cv::utils::logging::LOG_LEVEL_SILENT),
|
||||
std::make_tuple("*:V", cv::utils::logging::LOG_LEVEL_VERBOSE),
|
||||
std::make_tuple("*:VERBOSE", cv::utils::logging::LOG_LEVEL_VERBOSE)
|
||||
)
|
||||
);
|
||||
|
||||
// GlobalShouldSucceedPairedTests, globalNameHandling
|
||||
//
|
||||
// The following tests use a strategy of performing two tests as a pair, and require the pair
|
||||
// to succeed, in order to avoid false negatives due to default settings.
|
||||
// The first input string is supposed to set global to SILENT, the second input string VERBOSE.
|
||||
|
||||
typedef testing::TestWithParam<tuple<std::string, std::string>> GlobalShouldSucceedPairedTests;
|
||||
|
||||
TEST_P(GlobalShouldSucceedPairedTests, globalNameHandling)
|
||||
{
|
||||
const auto firstExpected = cv::utils::logging::LOG_LEVEL_SILENT;
|
||||
const auto secondExpected = cv::utils::logging::LOG_LEVEL_VERBOSE;
|
||||
//
|
||||
const std::string firstInput = get<0>(GetParam());
|
||||
LogTagConfigParser firstParser;
|
||||
firstParser.parse(firstInput);
|
||||
ASSERT_FALSE(firstParser.hasMalformed());
|
||||
ASSERT_EQ(firstParser.getMalformed().size(), 0u) << "Malformed list should be empty";
|
||||
ASSERT_TRUE(firstParser.getGlobalConfig().isGlobal);
|
||||
ASSERT_EQ(firstParser.getFullNameConfigs().size(), 0u) << "Specifying global log level should not emit full names";
|
||||
ASSERT_EQ(firstParser.getFirstPartConfigs().size(), 0u) << "Specifying global log level should not emit first name part result";
|
||||
ASSERT_EQ(firstParser.getAnyPartConfigs().size(), 0u) << "Specifying global log level should not emit any name part result";
|
||||
const cv::utils::logging::LogLevel firstActual = firstParser.getGlobalConfig().level;
|
||||
//
|
||||
const std::string secondInput = get<1>(GetParam());
|
||||
LogTagConfigParser secondParser;
|
||||
secondParser.parse(secondInput);
|
||||
ASSERT_FALSE(secondParser.hasMalformed());
|
||||
ASSERT_EQ(secondParser.getMalformed().size(), 0u) << "Malformed list should be empty";
|
||||
ASSERT_TRUE(secondParser.getGlobalConfig().isGlobal);
|
||||
ASSERT_EQ(secondParser.getFullNameConfigs().size(), 0u) << "Specifying global log level should not emit full names";
|
||||
ASSERT_EQ(secondParser.getFirstPartConfigs().size(), 0u) << "Specifying global log level should not emit first name part result";
|
||||
ASSERT_EQ(secondParser.getAnyPartConfigs().size(), 0u) << "Specifying global log level should not emit any name part result";
|
||||
const cv::utils::logging::LogLevel secondActual = secondParser.getGlobalConfig().level;
|
||||
//
|
||||
EXPECT_EQ(firstActual, firstExpected);
|
||||
EXPECT_EQ(secondActual, secondExpected);
|
||||
}
|
||||
|
||||
// Following test cases uses lowercase "global" as name
|
||||
INSTANTIATE_TEST_CASE_P(Core_LogTagConfigParser, GlobalShouldSucceedPairedTests,
|
||||
testing::Values(
|
||||
std::make_tuple("global:S", "global:V"),
|
||||
std::make_tuple("global:SILENT", "global:VERBOSE")
|
||||
)
|
||||
);
|
||||
|
||||
// In the next few smoke tests, the use of EXPECT versus ASSERT is as follows.
|
||||
// Each test will try to read the first element from one of the vector results.
|
||||
// Prior to that, the vector need to be ASSERT'ed to have at least one element.
|
||||
// All remaining assertions in the test body would use EXPECT instead.
|
||||
|
||||
TEST(Core_LogTagConfigParser, FullNameSmokeTest)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
ASSERT_EQ(parser.getFullNameConfigs().size(), 1u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
EXPECT_STREQ(parser.getFullNameConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, FirstPartSmokeTest_NoPeriod)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something*:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getFirstPartConfigs().size(), 1u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
EXPECT_STREQ(parser.getFirstPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, FirstPartSmokeTest_WithPeriod)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something.*:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getFirstPartConfigs().size(), 1u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
EXPECT_STREQ(parser.getFirstPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, AnyPartSmokeTest_PrecedeAsterisk_NoPeriod)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("*something:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getAnyPartConfigs().size(), 1u);
|
||||
EXPECT_STREQ(parser.getAnyPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, AnyPartSmokeTest_PrecedeAsterisk_WithPeriod)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("*.something:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getAnyPartConfigs().size(), 1u);
|
||||
EXPECT_STREQ(parser.getAnyPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, AnyPartSmokeTest_PrecedeFollowAsterisks_NoPeriod)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("*something*:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getAnyPartConfigs().size(), 1u);
|
||||
EXPECT_STREQ(parser.getAnyPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, AnyPartSmokeTest_PrecedeFollowAsterisks_WithPeriod)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("*.something.*:S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getAnyPartConfigs().size(), 1u);
|
||||
EXPECT_STREQ(parser.getAnyPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, FullName_EqualSign_ShouldSucceed)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something=S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
ASSERT_EQ(parser.getFullNameConfigs().size(), 1u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
EXPECT_STREQ(parser.getFullNameConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, FirstPart_EqualSign_ShouldSucceed)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something*=S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getFirstPartConfigs().size(), 1u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
EXPECT_STREQ(parser.getFirstPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, AnyPart_EqualSign_ShouldSucceed)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("*something*=S");
|
||||
EXPECT_FALSE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 0u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
ASSERT_EQ(parser.getAnyPartConfigs().size(), 1u);
|
||||
EXPECT_STREQ(parser.getAnyPartConfigs().at(0u).namePart.c_str(), "something");
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, DuplicateColon_ShouldFail)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something::S");
|
||||
EXPECT_TRUE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 1u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, DuplicateEqual_ShouldFail)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something==S");
|
||||
EXPECT_TRUE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 1u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, DuplicateColonAndEqual_ShouldFail)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something:=S");
|
||||
EXPECT_TRUE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 1u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
}
|
||||
|
||||
TEST(Core_LogTagConfigParser, DuplicateEqualAndColon_ShouldFail)
|
||||
{
|
||||
LogTagConfigParser parser;
|
||||
parser.parse("something=:S");
|
||||
EXPECT_TRUE(parser.hasMalformed());
|
||||
EXPECT_EQ(parser.getMalformed().size(), 1u);
|
||||
EXPECT_EQ(parser.getFullNameConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getFirstPartConfigs().size(), 0u);
|
||||
EXPECT_EQ(parser.getAnyPartConfigs().size(), 0u);
|
||||
}
|
||||
|
||||
}} // namespace
|
668
3rdparty/opencv-4.5.4/modules/core/test/test_logtagmanager.cpp
vendored
Normal file
668
3rdparty/opencv-4.5.4/modules/core/test/test_logtagmanager.cpp
vendored
Normal file
@ -0,0 +1,668 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include "../src/utils/logtagmanager.hpp"
|
||||
#include "../src/utils/logtagconfigparser.hpp"
|
||||
|
||||
// Because "LogTagManager" isn't exported from "opencv_core", the only way
|
||||
// to perform test is to compile the source code into "opencv_test_core".
|
||||
// This workaround may cause step debugger breakpoints to work unreliably.
|
||||
#if 1
|
||||
#include "../src/utils/logtagmanager.cpp"
|
||||
#endif
|
||||
|
||||
namespace opencv_test {
|
||||
namespace {
|
||||
|
||||
using LogLevel = cv::utils::logging::LogLevel;
|
||||
using LogTag = cv::utils::logging::LogTag;
|
||||
using LogTagManager = cv::utils::logging::LogTagManager;
|
||||
|
||||
// Value to initialize log tag constructors
|
||||
static const LogLevel constTestLevelBegin = cv::utils::logging::LOG_LEVEL_SILENT;
|
||||
|
||||
// Value to be set as part of test (to simulate runtime changes)
|
||||
static const LogLevel constTestLevelChanged = cv::utils::logging::LOG_LEVEL_VERBOSE;
|
||||
|
||||
// An alternate value to initialize log tag constructors,
|
||||
// for test cases where two distinct initialization values are needed.
|
||||
static const LogLevel constTestLevelAltBegin = cv::utils::logging::LOG_LEVEL_FATAL;
|
||||
|
||||
// An alternate value to be set as part of test (to simulate runtime changes),
|
||||
// for test cases where two distinct runtime set values are needed.
|
||||
static const LogLevel constTestLevelAltChanged = cv::utils::logging::LOG_LEVEL_DEBUG;
|
||||
|
||||
// Enums for specifying which LogTagManager method to call.
|
||||
// Used in parameterized tests.
|
||||
enum class ByWhat
|
||||
{
|
||||
ByFullName = 0,
|
||||
ByFirstPart = 1,
|
||||
ByAnyPart = 2
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& strm, ByWhat byWhat)
|
||||
{
|
||||
switch (byWhat)
|
||||
{
|
||||
case ByWhat::ByFullName:
|
||||
strm << "ByFullName";
|
||||
break;
|
||||
case ByWhat::ByFirstPart:
|
||||
strm << "ByFirstPart";
|
||||
break;
|
||||
case ByWhat::ByAnyPart:
|
||||
strm << "ByAnyPart";
|
||||
break;
|
||||
default:
|
||||
strm << "(invalid ByWhat enum" << (int)byWhat << ")";
|
||||
break;
|
||||
}
|
||||
return strm;
|
||||
}
|
||||
|
||||
// Enums for describing relative timing.
|
||||
// Used in parameterized tests.
|
||||
enum class Timing
|
||||
{
|
||||
Never = 0,
|
||||
Before = 1,
|
||||
After = 2
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& strm, Timing timing)
|
||||
{
|
||||
switch (timing)
|
||||
{
|
||||
case Timing::Never:
|
||||
strm << "Never";
|
||||
break;
|
||||
case Timing::Before:
|
||||
strm << "Before";
|
||||
break;
|
||||
case Timing::After:
|
||||
strm << "After";
|
||||
break;
|
||||
default:
|
||||
strm << "(invalid Timing enum" << (int)timing << ")";
|
||||
break;
|
||||
}
|
||||
return strm;
|
||||
}
|
||||
|
||||
// Enums for selecting the substrings used in substring confusion tests.
|
||||
enum class SubstringType
|
||||
{
|
||||
Prefix = 0,
|
||||
Midstring = 1,
|
||||
Suffix = 2,
|
||||
Straddle = 3
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& strm, SubstringType substringType)
|
||||
{
|
||||
switch (substringType)
|
||||
{
|
||||
case SubstringType::Prefix:
|
||||
strm << "Prefix";
|
||||
break;
|
||||
case SubstringType::Midstring:
|
||||
strm << "Midstring";
|
||||
break;
|
||||
case SubstringType::Suffix:
|
||||
strm << "Suffix";
|
||||
break;
|
||||
case SubstringType::Straddle:
|
||||
strm << "Straddle";
|
||||
break;
|
||||
default:
|
||||
strm << "(invalid SubstringType enum: " << (int)substringType << ")";
|
||||
break;
|
||||
}
|
||||
return strm;
|
||||
}
|
||||
|
||||
// A base fixture consisting of the LogTagManager.
|
||||
// Note that an instance of LogTagManager contains its own instance of "global" log tag.
|
||||
class LogTagManagerTestFixture
|
||||
: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
LogTagManager m_logTagManager;
|
||||
|
||||
public:
|
||||
LogTagManagerTestFixture(LogLevel initGlobalLogLevel)
|
||||
: m_logTagManager(initGlobalLogLevel)
|
||||
{
|
||||
}
|
||||
|
||||
~LogTagManagerTestFixture()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// LogTagManagerGlobalSmokeTest verifies that the "global" log tag works as intended.
|
||||
class LogTagManagerGlobalSmokeTest
|
||||
: public LogTagManagerTestFixture
|
||||
{
|
||||
protected:
|
||||
LogTag* m_actualGlobalLogTag;
|
||||
|
||||
protected:
|
||||
static const char* const m_globalTagName;
|
||||
|
||||
public:
|
||||
LogTagManagerGlobalSmokeTest()
|
||||
: LogTagManagerTestFixture(constTestLevelBegin)
|
||||
, m_actualGlobalLogTag(nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
const char* const LogTagManagerGlobalSmokeTest::m_globalTagName = "global";
|
||||
|
||||
|
||||
TEST_F(LogTagManagerGlobalSmokeTest, AfterCtorCanGetGlobalWithoutAssign)
|
||||
{
|
||||
EXPECT_NE(m_logTagManager.get(m_globalTagName), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerGlobalSmokeTest, AfterCtorGetGlobalHasDefaultLevel)
|
||||
{
|
||||
auto globalLogTag = m_logTagManager.get(m_globalTagName);
|
||||
ASSERT_NE(globalLogTag, nullptr);
|
||||
EXPECT_EQ(globalLogTag->level, constTestLevelBegin);
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerGlobalSmokeTest, AfterCtorCanSetGlobalByFullName)
|
||||
{
|
||||
m_logTagManager.setLevelByFullName(m_globalTagName, constTestLevelChanged);
|
||||
auto globalLogTag = m_logTagManager.get(m_globalTagName);
|
||||
ASSERT_NE(globalLogTag, nullptr);
|
||||
EXPECT_EQ(globalLogTag->level, constTestLevelChanged);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// "global" level is not supposed to be settable by name-parts.
|
||||
// Therefore this test code is supposed to fail.
|
||||
TEST_F(LogTagManagerGlobalSmokeTest, DISABLED_AfterCtorCanSetGlobalByFirstPart)
|
||||
{
|
||||
m_logTagManager.setLevelByFirstPart(m_globalTagName, constTestLevelChanged);
|
||||
auto globalLogTag = m_logTagManager.get(m_globalTagName);
|
||||
ASSERT_NE(globalLogTag, nullptr);
|
||||
EXPECT_EQ(globalLogTag->level, constTestLevelChanged);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// "global" level is not supposed to be settable by name-parts.
|
||||
// Therefore this test code is supposed to fail.
|
||||
TEST_F(LogTagManagerGlobalSmokeTest, DISABLED_AfterCtorCanSetGlobalByAnyPart)
|
||||
{
|
||||
m_logTagManager.setLevelByAnyPart(m_globalTagName, constTestLevelChanged);
|
||||
auto globalLogTag = m_logTagManager.get(m_globalTagName);
|
||||
ASSERT_NE(globalLogTag, nullptr);
|
||||
EXPECT_EQ(globalLogTag->level, constTestLevelChanged);
|
||||
}
|
||||
#endif
|
||||
|
||||
// LogTagManagerNonGlobalSmokeTest performs basic smoke tests to verify that
|
||||
// a log tag (that is not the "global" log tag) can be assigned, and its
|
||||
// log level can be configured.
|
||||
class LogTagManagerNonGlobalSmokeTest
|
||||
: public LogTagManagerTestFixture
|
||||
{
|
||||
protected:
|
||||
LogTag m_something;
|
||||
|
||||
protected:
|
||||
static const char* const m_somethingTagName;
|
||||
|
||||
public:
|
||||
LogTagManagerNonGlobalSmokeTest()
|
||||
: LogTagManagerTestFixture(constTestLevelAltBegin)
|
||||
, m_something(m_somethingTagName, constTestLevelBegin)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
const char* const LogTagManagerNonGlobalSmokeTest::m_somethingTagName = "something";
|
||||
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanAssignTagAndThenGet)
|
||||
{
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanAssignTagAndThenGetAndShouldHaveDefaultLevel)
|
||||
{
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin);
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanSetLevelByFullNameBeforeAssignTag)
|
||||
{
|
||||
m_logTagManager.setLevelByFullName(m_somethingTagName, constTestLevelChanged);
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelChanged);
|
||||
EXPECT_NE(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin) << "Should not be left unchanged (default value)";
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanSetLevelByFirstPartBeforeAssignTag)
|
||||
{
|
||||
m_logTagManager.setLevelByFirstPart(m_somethingTagName, constTestLevelChanged);
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelChanged);
|
||||
EXPECT_NE(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin) << "Should not be left unchanged (default value)";
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanSetLevelByAnyPartBeforeAssignTag)
|
||||
{
|
||||
m_logTagManager.setLevelByAnyPart(m_somethingTagName, constTestLevelChanged);
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelChanged);
|
||||
EXPECT_NE(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin) << "Should not be left unchanged (default value)";
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanSetLevelByFullNameAfterAssignTag)
|
||||
{
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
m_logTagManager.setLevelByFullName(m_somethingTagName, constTestLevelChanged);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelChanged);
|
||||
EXPECT_NE(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin) << "Should not be left unchanged (default value)";
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanSetLevelByFirstPartAfterAssignTag)
|
||||
{
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
m_logTagManager.setLevelByFirstPart(m_somethingTagName, constTestLevelChanged);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelChanged);
|
||||
EXPECT_NE(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin) << "Should not be left unchanged (default value)";
|
||||
}
|
||||
|
||||
TEST_F(LogTagManagerNonGlobalSmokeTest, CanSetLevelByAnyPartAfterAssignTag)
|
||||
{
|
||||
m_logTagManager.assign(m_something.name, &m_something);
|
||||
m_logTagManager.setLevelByAnyPart(m_somethingTagName, constTestLevelChanged);
|
||||
ASSERT_EQ(m_logTagManager.get(m_somethingTagName), &m_something);
|
||||
EXPECT_EQ(m_logTagManager.get(m_somethingTagName)->level, constTestLevelChanged);
|
||||
EXPECT_NE(m_logTagManager.get(m_somethingTagName)->level, constTestLevelBegin) << "Should not be left unchanged (default value)";
|
||||
}
|
||||
|
||||
// Non-confusion tests use two or more (non-global) log tags with chosen names to verify
|
||||
// that LogTagManager does not accidentally apply log levels to log tags other than the
|
||||
// ones intended.
|
||||
|
||||
|
||||
// LogTagManagerSubstrNonConfusionSmokeTest are non-confusion tests that focus on
|
||||
// substrings. Keep in mind string matching in LogTagManager must be aligned to
|
||||
// the period delimiter; substrings are not considered for matching.
|
||||
class LogTagManagerSubstrNonConfusionFixture
|
||||
: public LogTagManagerTestFixture
|
||||
, public ::testing::WithParamInterface<std::tuple<SubstringType, bool, Timing, ByWhat>>
|
||||
{
|
||||
public:
|
||||
struct MyTestParam
|
||||
{
|
||||
const SubstringType detractorNameSelector;
|
||||
const bool initTargetTagWithCall;
|
||||
const Timing whenToAssignDetractorTag;
|
||||
const ByWhat howToSetDetractorLevel;
|
||||
MyTestParam(const std::tuple<SubstringType, bool, Timing, ByWhat>& args)
|
||||
: detractorNameSelector(std::get<0u>(args))
|
||||
, initTargetTagWithCall(std::get<1u>(args))
|
||||
, whenToAssignDetractorTag(std::get<2u>(args))
|
||||
, howToSetDetractorLevel(std::get<3u>(args))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// The following substrings are all derived from "soursop".
|
||||
// In particular, "ours" is a substring of "soursop".
|
||||
protected:
|
||||
LogTag tagSour;
|
||||
LogTag tagSop;
|
||||
LogTag tagSoursop;
|
||||
LogTag tagSourDotSop;
|
||||
LogTag tagOurs;
|
||||
|
||||
protected:
|
||||
static const char* const strSour; // = "sour";
|
||||
static const char* const strSop; // = "sop";
|
||||
static const char* const strSoursop; // = "soursop";
|
||||
static const char* const strSourDotSop; // = "sour.sop";
|
||||
static const char* const strOurs; // = "ours";
|
||||
|
||||
public:
|
||||
LogTagManagerSubstrNonConfusionFixture()
|
||||
: LogTagManagerTestFixture(constTestLevelAltBegin)
|
||||
, tagSour(strSour, constTestLevelBegin)
|
||||
, tagSop(strSop, constTestLevelBegin)
|
||||
, tagSoursop(strSoursop, constTestLevelBegin)
|
||||
, tagSourDotSop(strSourDotSop, constTestLevelBegin)
|
||||
, tagOurs(strOurs, constTestLevelBegin)
|
||||
{
|
||||
}
|
||||
|
||||
const char* selectDetractorName(const MyTestParam& myTestParam)
|
||||
{
|
||||
switch (myTestParam.detractorNameSelector)
|
||||
{
|
||||
case SubstringType::Prefix:
|
||||
return strSour;
|
||||
case SubstringType::Midstring:
|
||||
return strOurs;
|
||||
case SubstringType::Suffix:
|
||||
return strSop;
|
||||
case SubstringType::Straddle:
|
||||
return strSourDotSop;
|
||||
default:
|
||||
throw std::logic_error("LogTagManagerSubstrNonConfusionTest::selectDetractorName");
|
||||
}
|
||||
}
|
||||
|
||||
LogTag& selectDetractorTag(const MyTestParam& myTestParam)
|
||||
{
|
||||
switch (myTestParam.detractorNameSelector)
|
||||
{
|
||||
case SubstringType::Prefix:
|
||||
return tagSour;
|
||||
case SubstringType::Midstring:
|
||||
return tagOurs;
|
||||
case SubstringType::Suffix:
|
||||
return tagSop;
|
||||
case SubstringType::Straddle:
|
||||
return tagSourDotSop;
|
||||
default:
|
||||
throw std::logic_error("LogTagManagerSubstrNonConfusionTest::selectDetractorName");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const char* const LogTagManagerSubstrNonConfusionFixture::strSour = "sour";
|
||||
const char* const LogTagManagerSubstrNonConfusionFixture::strSop = "sop";
|
||||
const char* const LogTagManagerSubstrNonConfusionFixture::strSoursop = "soursop";
|
||||
const char* const LogTagManagerSubstrNonConfusionFixture::strSourDotSop = "sour.sop";
|
||||
const char* const LogTagManagerSubstrNonConfusionFixture::strOurs = "ours";
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
LogTagManagerSubstrNonConfusionTest,
|
||||
LogTagManagerSubstrNonConfusionFixture,
|
||||
::testing::Combine(
|
||||
::testing::Values(SubstringType::Prefix, SubstringType::Midstring, SubstringType::Suffix, SubstringType::Straddle),
|
||||
::testing::Values(false, true),
|
||||
::testing::Values(Timing::Never, Timing::Before, Timing::After),
|
||||
::testing::Values(ByWhat::ByFullName, ByWhat::ByFirstPart, ByWhat::ByAnyPart)
|
||||
)
|
||||
);
|
||||
|
||||
TEST_P(LogTagManagerSubstrNonConfusionFixture, ParameterizedTestFunc)
|
||||
{
|
||||
const auto myTestParam = MyTestParam(GetParam());
|
||||
const char* detractorName = selectDetractorName(myTestParam);
|
||||
LogTag& detractorTag = selectDetractorTag(myTestParam);
|
||||
// Target tag is assigned
|
||||
m_logTagManager.assign(tagSoursop.name, &tagSoursop);
|
||||
// If detractor tag is to be assigned "before"
|
||||
if (myTestParam.whenToAssignDetractorTag == Timing::Before)
|
||||
{
|
||||
m_logTagManager.assign(detractorName, &detractorTag);
|
||||
}
|
||||
// Initialize target tag to constTestLevelChanged
|
||||
if (myTestParam.initTargetTagWithCall)
|
||||
{
|
||||
m_logTagManager.setLevelByFullName(strSoursop, constTestLevelChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
tagSoursop.level = constTestLevelChanged;
|
||||
}
|
||||
// If detractor tag is to be assigned "after"
|
||||
if (myTestParam.whenToAssignDetractorTag == Timing::After)
|
||||
{
|
||||
m_logTagManager.assign(detractorName, &detractorTag);
|
||||
}
|
||||
// Set the log level using the detractor name
|
||||
switch (myTestParam.howToSetDetractorLevel)
|
||||
{
|
||||
case ByWhat::ByFullName:
|
||||
m_logTagManager.setLevelByFullName(detractorName, constTestLevelAltChanged);
|
||||
break;
|
||||
case ByWhat::ByFirstPart:
|
||||
m_logTagManager.setLevelByFirstPart(detractorName, constTestLevelAltChanged);
|
||||
break;
|
||||
case ByWhat::ByAnyPart:
|
||||
m_logTagManager.setLevelByAnyPart(detractorName, constTestLevelAltChanged);
|
||||
break;
|
||||
default:
|
||||
FAIL() << "Invalid parameterized test value, check test case.";
|
||||
}
|
||||
// Verifies that the target tag is not disturbed by changes made using detractor name
|
||||
ASSERT_EQ(m_logTagManager.get(strSoursop), &tagSoursop);
|
||||
EXPECT_EQ(tagSoursop.level, constTestLevelChanged);
|
||||
EXPECT_NE(tagSoursop.level, constTestLevelAltChanged) << "Should not be changed unless confusion bug exists";
|
||||
}
|
||||
|
||||
// LogTagManagerNamePartNonConfusionFixture are non-confusion tests that assumes
|
||||
// no substring confusions are happening, and proceed to test matching by name parts.
|
||||
// In particular, setLevelByFirstPart() and setLevelByAnyPart() are the focus of these tests.
|
||||
class LogTagManagerNamePartNonConfusionFixture
|
||||
: public LogTagManagerTestFixture
|
||||
, public ::testing::WithParamInterface<std::tuple<int, ByWhat, int, Timing, Timing>>
|
||||
{
|
||||
public:
|
||||
struct MyTestParam
|
||||
{
|
||||
// Config tag name can only specify either full name or exactly one name part.
|
||||
// When specifying exactly one name part, there is a choice of matching the
|
||||
// first name part of a tag, or matching any name part that appears in a tag
|
||||
// name regardless of its position.
|
||||
const int configTagIndex;
|
||||
const ByWhat configMatchBy;
|
||||
const int targetTagIndex;
|
||||
const Timing whenToAssignTargetTag;
|
||||
const Timing whenToAssignConfigTag;
|
||||
MyTestParam(const std::tuple<int, ByWhat, int, Timing, Timing>& args)
|
||||
: configTagIndex(std::get<0u>(args))
|
||||
, configMatchBy(std::get<1u>(args))
|
||||
, targetTagIndex(std::get<2u>(args))
|
||||
, whenToAssignTargetTag(std::get<3u>(args))
|
||||
, whenToAssignConfigTag(std::get<4u>(args))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
LogTag m_apple;
|
||||
LogTag m_banana;
|
||||
LogTag m_coconut;
|
||||
LogTag m_orange;
|
||||
LogTag m_pineapple;
|
||||
LogTag m_bananaDotOrange;
|
||||
LogTag m_bananaDotPineapple;
|
||||
LogTag m_coconutDotPineapple;
|
||||
|
||||
protected:
|
||||
static const char* const strApple; // = "apple";
|
||||
static const char* const strBanana; // = "banana";
|
||||
static const char* const strCoconut; // = "coconut";
|
||||
static const char* const strOrange; // = "orange";
|
||||
static const char* const strPineapple; // = "pineapple";
|
||||
static const char* const strBananaDotOrange; // = "banana.orange";
|
||||
static const char* const strBananaDotPineapple; // = "banana.pineapple";
|
||||
static const char* const strCoconutDotPineapple; // = "coconut.pineapple";
|
||||
|
||||
public:
|
||||
LogTagManagerNamePartNonConfusionFixture()
|
||||
: LogTagManagerTestFixture(constTestLevelAltBegin)
|
||||
, m_apple(strApple, constTestLevelBegin)
|
||||
, m_banana(strBanana, constTestLevelBegin)
|
||||
, m_coconut(strCoconut, constTestLevelBegin)
|
||||
, m_orange(strOrange, constTestLevelBegin)
|
||||
, m_pineapple(strPineapple, constTestLevelBegin)
|
||||
, m_bananaDotOrange(strBananaDotOrange, constTestLevelBegin)
|
||||
, m_bananaDotPineapple(strBananaDotPineapple, constTestLevelBegin)
|
||||
, m_coconutDotPineapple(strCoconutDotPineapple, constTestLevelBegin)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
LogTag* getLogTagByIndex(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return &m_apple;
|
||||
case 1:
|
||||
return &m_banana;
|
||||
case 2:
|
||||
return &m_coconut;
|
||||
case 3:
|
||||
return &m_orange;
|
||||
case 4:
|
||||
return &m_pineapple;
|
||||
case 5:
|
||||
return &m_bananaDotOrange;
|
||||
case 6:
|
||||
return &m_bananaDotPineapple;
|
||||
case 7:
|
||||
return &m_coconutDotPineapple;
|
||||
default:
|
||||
ADD_FAILURE() << "Invalid parameterized test value, check test case. "
|
||||
<< "Function LogTagManagerNamePartNonConfusionFixture::getLogTagByIndex.";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// findTabulatedExpectedResult returns the hard-coded expected results for parameterized
|
||||
// test cases. The tables need updated if the index, name, or ordering of test tags are
|
||||
// changed.
|
||||
bool findTabulatedExpectedResult(const MyTestParam& myTestParam) const
|
||||
{
|
||||
// expectedResultUsingFirstPart:
|
||||
// Each row ("config") specifies the tag name specifier used to call setLevelByFirstPart().
|
||||
// Each column ("target") specifies whether an actual tag with the "target"
|
||||
// name would have its log level changed because of the call to setLevelByFirstPart().
|
||||
static const bool expectedResultUsingFirstPart[5][8] =
|
||||
{
|
||||
/*byFirstPart(apple)*/ { true, false, false, false, false, false, false, false },
|
||||
/*byFirstPart(banana)*/ { false, true, false, false, false, true, true, false },
|
||||
/*byFirstPart(coconut)*/ { false, false, true, false, false, false, false, true },
|
||||
/*byFirstPart(orange)*/ { false, false, false, true, false, false, false, false },
|
||||
/*byFirstPart(pineapple)*/ { false, false, false, false, true, false, false, false },
|
||||
};
|
||||
|
||||
// expectedResultUsingAnyPart:
|
||||
// Each row ("config") specifies the tag name specifier used to call setLevelByAnyPart().
|
||||
// Each column ("target") specifies whether an actual tag with the "target"
|
||||
// name would have its log level changed because of the call to setLevelByAnyPart().
|
||||
static const bool expectedResultUsingAnyPart[5][8] =
|
||||
{
|
||||
/*byAnyPart(apple)*/ { true, false, false, false, false, false, false, false },
|
||||
/*byAnyPart(banana)*/ { false, true, false, false, false, true, true, false },
|
||||
/*byAnyPart(coconut)*/ { false, false, true, false, false, false, false, true },
|
||||
/*byAnyPart(orange)*/ { false, false, false, true, false, true, false, false },
|
||||
/*byAnyPart(pineapple)*/ { false, false, false, false, true, false, true, true },
|
||||
};
|
||||
|
||||
switch (myTestParam.configMatchBy)
|
||||
{
|
||||
case ByWhat::ByFirstPart:
|
||||
return expectedResultUsingFirstPart[myTestParam.configTagIndex][myTestParam.targetTagIndex];
|
||||
case ByWhat::ByAnyPart:
|
||||
return expectedResultUsingAnyPart[myTestParam.configTagIndex][myTestParam.targetTagIndex];
|
||||
default:
|
||||
ADD_FAILURE() << "Invalid parameterized test value, check test case. "
|
||||
<< "Function LogTagManagerNamePartNonConfusionFixture::getLogTagByIndex.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strApple = "apple";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strBanana = "banana";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strCoconut = "coconut";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strOrange = "orange";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strPineapple = "pineapple";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strBananaDotOrange = "banana.orange";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strBananaDotPineapple = "banana.pineapple";
|
||||
const char* const LogTagManagerNamePartNonConfusionFixture::strCoconutDotPineapple = "coconut.pineapple";
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
LogTagManagerNamePartNonConfusionTest,
|
||||
LogTagManagerNamePartNonConfusionFixture,
|
||||
::testing::Combine(
|
||||
::testing::Values(0, 1, 2, 3, 4),
|
||||
::testing::Values(ByWhat::ByFirstPart, ByWhat::ByAnyPart),
|
||||
::testing::Values(0, 1, 2, 3, 4, 5, 6, 7),
|
||||
::testing::Values(Timing::Before, Timing::After),
|
||||
::testing::Values(Timing::Before, Timing::After, Timing::Never)
|
||||
)
|
||||
);
|
||||
|
||||
TEST_P(LogTagManagerNamePartNonConfusionFixture, NamePartTestFunc)
|
||||
{
|
||||
const auto myTestParam = MyTestParam(GetParam());
|
||||
LogTag* configTag = getLogTagByIndex(myTestParam.configTagIndex);
|
||||
LogTag* targetTag = getLogTagByIndex(myTestParam.targetTagIndex);
|
||||
ASSERT_NE(configTag, nullptr) << "Invalid parameterized test value, check value of myTestParam.configTagIndex.";
|
||||
ASSERT_NE(targetTag, nullptr) << "Invalid parameterized test value, check value of myTestParam.targetTagIndex.";
|
||||
if (myTestParam.whenToAssignConfigTag == Timing::Before)
|
||||
{
|
||||
m_logTagManager.assign(configTag->name, configTag);
|
||||
}
|
||||
if (myTestParam.whenToAssignTargetTag == Timing::Before)
|
||||
{
|
||||
m_logTagManager.assign(targetTag->name, targetTag);
|
||||
}
|
||||
switch (myTestParam.configMatchBy)
|
||||
{
|
||||
case ByWhat::ByFirstPart:
|
||||
m_logTagManager.setLevelByFirstPart(configTag->name, constTestLevelChanged);
|
||||
break;
|
||||
case ByWhat::ByAnyPart:
|
||||
m_logTagManager.setLevelByAnyPart(configTag->name, constTestLevelChanged);
|
||||
break;
|
||||
default:
|
||||
FAIL() << "Invalid parameterized test value, check test case. "
|
||||
<< "Fixture LogTagManagerNamePartNonConfusionFixture, Case NamePartTestFunc.";
|
||||
}
|
||||
if (myTestParam.whenToAssignConfigTag == Timing::After)
|
||||
{
|
||||
m_logTagManager.assign(configTag->name, configTag);
|
||||
}
|
||||
if (myTestParam.whenToAssignTargetTag == Timing::After)
|
||||
{
|
||||
m_logTagManager.assign(targetTag->name, targetTag);
|
||||
}
|
||||
// Verifies the registration of the log tag pointer. If fail, cannot proceed
|
||||
// because it is not certain whether the returned pointer is valid to dereference
|
||||
ASSERT_EQ(m_logTagManager.get(targetTag->name), targetTag);
|
||||
// Verifies the log level of target tag
|
||||
const bool isChangeExpected = findTabulatedExpectedResult(myTestParam);
|
||||
if (isChangeExpected)
|
||||
{
|
||||
EXPECT_EQ(targetTag->level, constTestLevelChanged);
|
||||
EXPECT_NE(targetTag->level, constTestLevelBegin);
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_EQ(targetTag->level, constTestLevelBegin);
|
||||
EXPECT_NE(targetTag->level, constTestLevelChanged);
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
154
3rdparty/opencv-4.5.4/modules/core/test/test_lpsolver.cpp
vendored
Normal file
154
3rdparty/opencv-4.5.4/modules/core/test/test_lpsolver.cpp
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(Core_LPSolver, regression_basic){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//cormen's example #1
|
||||
A=(cv::Mat_<double>(3,1)<<3,1,2);
|
||||
B=(cv::Mat_<double>(3,4)<<1,1,3,30,2,2,5,24,4,1,2,36);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(3,1)<<8,4,0);
|
||||
ASSERT_LT(cvtest::norm(z, etalon_z, cv::NORM_L1), 1e-12);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
//cormen's example #2
|
||||
A=(cv::Mat_<double>(1,2)<<18,12.5);
|
||||
B=(cv::Mat_<double>(3,3)<<1,1,20,1,0,20,0,1,16);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(2,1)<<20,0);
|
||||
ASSERT_LT(cvtest::norm(z, etalon_z, cv::NORM_L1), 1e-12);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
//cormen's example #3
|
||||
A=(cv::Mat_<double>(1,2)<<5,-3);
|
||||
B=(cv::Mat_<double>(2,3)<<1,-1,1,2,1,2);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(2,1)<<1,0);
|
||||
ASSERT_LT(cvtest::norm(z, etalon_z, cv::NORM_L1), 1e-12);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Core_LPSolver, regression_init_unfeasible){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//cormen's example #4 - unfeasible
|
||||
A=(cv::Mat_<double>(1,3)<<-1,-1,-1);
|
||||
B=(cv::Mat_<double>(2,4)<<-2,-7.5,-3,-10000,-20,-5,-10,-30000);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(3,1)<<1250,1000,0);
|
||||
ASSERT_LT(cvtest::norm(z, etalon_z, cv::NORM_L1), 1e-12);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(DISABLED_Core_LPSolver, regression_absolutely_unfeasible){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//trivial absolutely unfeasible example
|
||||
A=(cv::Mat_<double>(1,1)<<1);
|
||||
B=(cv::Mat_<double>(2,2)<<1,-1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::solveLP(A,B,z);
|
||||
ASSERT_EQ(res,-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Core_LPSolver, regression_multiple_solutions){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//trivial example with multiple solutions
|
||||
A=(cv::Mat_<double>(2,1)<<1,1);
|
||||
B=(cv::Mat_<double>(1,3)<<1,1,1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_EQ(res,1);
|
||||
ASSERT_LT(fabs(z.dot(A) - 1), DBL_EPSILON);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Core_LPSolver, regression_cycling){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//example with cycling from http://people.orie.cornell.edu/miketodd/or630/SimplexCyclingExample.pdf
|
||||
A=(cv::Mat_<double>(4,1)<<10,-57,-9,-24);
|
||||
B=(cv::Mat_<double>(3,5)<<0.5,-5.5,-2.5,9,0,0.5,-1.5,-0.5,1,0,1,0,0,0,1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_LT(fabs(z.dot(A) - 1), DBL_EPSILON);
|
||||
//ASSERT_EQ(res,1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Core_LPSolver, issue_12337)
|
||||
{
|
||||
Mat A=(cv::Mat_<double>(3,1)<<3,1,2);
|
||||
Mat B=(cv::Mat_<double>(3,4)<<1,1,3,30,2,2,5,24,4,1,2,36);
|
||||
Mat1f z_float; cv::solveLP(A, B, z_float);
|
||||
Mat1d z_double; cv::solveLP(A, B, z_double);
|
||||
Mat1i z_int; cv::solveLP(A, B, z_int);
|
||||
EXPECT_ANY_THROW(Mat1b z_8u; cv::solveLP(A, B, z_8u));
|
||||
}
|
||||
|
||||
}} // namespace
|
10
3rdparty/opencv-4.5.4/modules/core/test/test_main.cpp
vendored
Normal file
10
3rdparty/opencv-4.5.4/modules/core/test/test_main.cpp
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#if defined(HAVE_HPX)
|
||||
#include <hpx/hpx_main.hpp>
|
||||
#endif
|
||||
|
||||
CV_TEST_MAIN("cv")
|
2452
3rdparty/opencv-4.5.4/modules/core/test/test_mat.cpp
vendored
Normal file
2452
3rdparty/opencv-4.5.4/modules/core/test/test_mat.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4009
3rdparty/opencv-4.5.4/modules/core/test/test_math.cpp
vendored
Normal file
4009
3rdparty/opencv-4.5.4/modules/core/test/test_math.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
824
3rdparty/opencv-4.5.4/modules/core/test/test_misc.cpp
vendored
Normal file
824
3rdparty/opencv-4.5.4/modules/core/test/test_misc.cpp
vendored
Normal file
@ -0,0 +1,824 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(Core_OutputArrayCreate, _1997)
|
||||
{
|
||||
struct local {
|
||||
static void create(OutputArray arr, Size submatSize, int type)
|
||||
{
|
||||
int sizes[] = {submatSize.width, submatSize.height};
|
||||
arr.create(sizeof(sizes)/sizeof(sizes[0]), sizes, type);
|
||||
}
|
||||
};
|
||||
|
||||
Mat mat(Size(512, 512), CV_8U);
|
||||
Size submatSize = Size(256, 256);
|
||||
|
||||
ASSERT_NO_THROW(local::create( mat(Rect(Point(), submatSize)), submatSize, mat.type() ));
|
||||
}
|
||||
|
||||
TEST(Core_SaturateCast, NegativeNotClipped)
|
||||
{
|
||||
double d = -1.0;
|
||||
unsigned int val = cv::saturate_cast<unsigned int>(d);
|
||||
|
||||
ASSERT_EQ(0xffffffff, val);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
static double maxAbsDiff(const T &t, const U &u)
|
||||
{
|
||||
Mat_<double> d;
|
||||
absdiff(t, u, d);
|
||||
double ret;
|
||||
minMaxLoc(d, NULL, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayAssign, _Matxd_Matd)
|
||||
{
|
||||
Mat expected = (Mat_<double>(2,3) << 1, 2, 3, .1, .2, .3);
|
||||
Matx23d actualx;
|
||||
|
||||
{
|
||||
OutputArray oa(actualx);
|
||||
oa.assign(expected);
|
||||
}
|
||||
|
||||
Mat actual = (Mat) actualx;
|
||||
|
||||
EXPECT_LE(maxAbsDiff(expected, actual), 0.0);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayAssign, _Matxd_Matf)
|
||||
{
|
||||
Mat expected = (Mat_<float>(2,3) << 1, 2, 3, .1, .2, .3);
|
||||
Matx23d actualx;
|
||||
|
||||
{
|
||||
OutputArray oa(actualx);
|
||||
oa.assign(expected);
|
||||
}
|
||||
|
||||
Mat actual = (Mat) actualx;
|
||||
|
||||
EXPECT_LE(maxAbsDiff(expected, actual), FLT_EPSILON);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayAssign, _Matxf_Matd)
|
||||
{
|
||||
Mat expected = (Mat_<double>(2,3) << 1, 2, 3, .1, .2, .3);
|
||||
Matx23f actualx;
|
||||
|
||||
{
|
||||
OutputArray oa(actualx);
|
||||
oa.assign(expected);
|
||||
}
|
||||
|
||||
Mat actual = (Mat) actualx;
|
||||
|
||||
EXPECT_LE(maxAbsDiff(expected, actual), FLT_EPSILON);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayAssign, _Matxd_UMatd)
|
||||
{
|
||||
Mat expected = (Mat_<double>(2,3) << 1, 2, 3, .1, .2, .3);
|
||||
UMat uexpected = expected.getUMat(ACCESS_READ);
|
||||
Matx23d actualx;
|
||||
|
||||
{
|
||||
OutputArray oa(actualx);
|
||||
oa.assign(uexpected);
|
||||
}
|
||||
|
||||
Mat actual = (Mat) actualx;
|
||||
|
||||
EXPECT_LE(maxAbsDiff(expected, actual), 0.0);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayAssign, _Matxd_UMatf)
|
||||
{
|
||||
Mat expected = (Mat_<float>(2,3) << 1, 2, 3, .1, .2, .3);
|
||||
UMat uexpected = expected.getUMat(ACCESS_READ);
|
||||
Matx23d actualx;
|
||||
|
||||
{
|
||||
OutputArray oa(actualx);
|
||||
oa.assign(uexpected);
|
||||
}
|
||||
|
||||
Mat actual = (Mat) actualx;
|
||||
|
||||
EXPECT_LE(maxAbsDiff(expected, actual), FLT_EPSILON);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayAssign, _Matxf_UMatd)
|
||||
{
|
||||
Mat expected = (Mat_<double>(2,3) << 1, 2, 3, .1, .2, .3);
|
||||
UMat uexpected = expected.getUMat(ACCESS_READ);
|
||||
Matx23f actualx;
|
||||
|
||||
{
|
||||
OutputArray oa(actualx);
|
||||
oa.assign(uexpected);
|
||||
}
|
||||
|
||||
Mat actual = (Mat) actualx;
|
||||
|
||||
EXPECT_LE(maxAbsDiff(expected, actual), FLT_EPSILON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int fixedType_handler(OutputArray dst)
|
||||
{
|
||||
int type = CV_32FC2; // return points only {x, y}
|
||||
if (dst.fixedType())
|
||||
{
|
||||
type = dst.type();
|
||||
CV_Assert(type == CV_32FC2 || type == CV_32FC3); // allow points + confidence level: {x, y, confidence}
|
||||
}
|
||||
const int N = 100;
|
||||
dst.create(Size(1, N), type);
|
||||
Mat m = dst.getMat();
|
||||
if (m.type() == CV_32FC2)
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
m.at<Vec2f>(i) = Vec2f((float)i, (float)(i*2));
|
||||
}
|
||||
else if (m.type() == CV_32FC3)
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
m.at<Vec3f>(i) = Vec3f((float)i, (float)(i*2), 1.0f / (i + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(0 && "Internal error");
|
||||
}
|
||||
return CV_MAT_CN(type);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArray, FixedType)
|
||||
{
|
||||
Mat_<Vec2f> pointsOnly;
|
||||
int num_pointsOnly = fixedType_handler(pointsOnly);
|
||||
EXPECT_EQ(2, num_pointsOnly);
|
||||
|
||||
Mat_<Vec3f> pointsWithConfidence;
|
||||
int num_pointsWithConfidence = fixedType_handler(pointsWithConfidence);
|
||||
EXPECT_EQ(3, num_pointsWithConfidence);
|
||||
|
||||
Mat defaultResult;
|
||||
int num_defaultResult = fixedType_handler(defaultResult);
|
||||
EXPECT_EQ(2, num_defaultResult);
|
||||
}
|
||||
|
||||
TEST(Core_OutputArrayCreate, _13772)
|
||||
{
|
||||
cv::Mat1d mat;
|
||||
cv::OutputArray o(mat);
|
||||
ASSERT_NO_THROW(o.create(3, 5, CV_64F, -1, true));
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST(Core_String, find_last_of__with__empty_string)
|
||||
{
|
||||
cv::String s;
|
||||
size_t p = s.find_last_of('q', 0);
|
||||
// npos is not exported: EXPECT_EQ(cv::String::npos, p);
|
||||
EXPECT_EQ(std::string::npos, p);
|
||||
}
|
||||
|
||||
TEST(Core_String, end_method_regression)
|
||||
{
|
||||
cv::String old_string = "012345";
|
||||
cv::String new_string(old_string.begin(), old_string.end());
|
||||
EXPECT_EQ(6u, new_string.size());
|
||||
}
|
||||
|
||||
TEST(Core_Copy, repeat_regression_8972)
|
||||
{
|
||||
Mat src = (Mat_<int>(1, 4) << 1, 2, 3, 4);
|
||||
|
||||
ASSERT_ANY_THROW({
|
||||
repeat(src, 5, 1, src);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
class ThrowErrorParallelLoopBody : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ThrowErrorParallelLoopBody(cv::Mat& dst, int i) : dst_(dst), i_(i) {}
|
||||
~ThrowErrorParallelLoopBody() {}
|
||||
void operator()(const cv::Range& r) const
|
||||
{
|
||||
for (int i = r.start; i < r.end; i++)
|
||||
{
|
||||
CV_Assert(i != i_);
|
||||
dst_.row(i).setTo(1);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
Mat dst_;
|
||||
int i_;
|
||||
};
|
||||
|
||||
TEST(Core_Parallel, propagate_exceptions)
|
||||
{
|
||||
Mat dst1(1000, 100, CV_8SC1, Scalar::all(0));
|
||||
ASSERT_NO_THROW({
|
||||
parallel_for_(cv::Range(0, dst1.rows), ThrowErrorParallelLoopBody(dst1, -1));
|
||||
});
|
||||
|
||||
Mat dst2(1000, 100, CV_8SC1, Scalar::all(0));
|
||||
ASSERT_THROW({
|
||||
parallel_for_(cv::Range(0, dst2.rows), ThrowErrorParallelLoopBody(dst2, dst2.rows / 2));
|
||||
}, cv::Exception);
|
||||
}
|
||||
|
||||
TEST(Core_Version, consistency)
|
||||
{
|
||||
// this test verifies that OpenCV version loaded in runtime
|
||||
// is the same this test has been built with
|
||||
EXPECT_EQ(CV_VERSION_MAJOR, cv::getVersionMajor());
|
||||
EXPECT_EQ(CV_VERSION_MINOR, cv::getVersionMinor());
|
||||
EXPECT_EQ(CV_VERSION_REVISION, cv::getVersionRevision());
|
||||
EXPECT_EQ(String(CV_VERSION), cv::getVersionString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Test core/check.hpp macros
|
||||
//
|
||||
|
||||
void test_check_eq_1(int value_1, int value_2)
|
||||
{
|
||||
CV_CheckEQ(value_1, value_2, "Validation check failed");
|
||||
}
|
||||
TEST(Core_Check, testEQ_int_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_eq_1(123, 5678);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation check failed (expected: 'value_1 == value_2'), where\n"
|
||||
"> 'value_1' is 123\n"
|
||||
"> must be equal to\n"
|
||||
"> 'value_2' is 5678\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testEQ_int_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_eq_1(1234, 1234);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void test_check_eq_2(float value_1, float value_2)
|
||||
{
|
||||
CV_CheckEQ(value_1, value_2, "Validation check failed (float)");
|
||||
}
|
||||
TEST(Core_Check, testEQ_float_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_eq_2(1234.5f, 1234.55f);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation check failed (float) (expected: 'value_1 == value_2'), where\n"
|
||||
"> 'value_1' is 1234.5\n" // TODO Locale handling (use LC_ALL=C on Linux)
|
||||
"> must be equal to\n"
|
||||
"> 'value_2' is 1234.55\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testEQ_float_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_eq_2(1234.6f, 1234.6f);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void test_check_eq_3(double value_1, double value_2)
|
||||
{
|
||||
CV_CheckEQ(value_1, value_2, "Validation check failed (double)");
|
||||
}
|
||||
TEST(Core_Check, testEQ_double_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_eq_3(1234.5, 1234.56);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation check failed (double) (expected: 'value_1 == value_2'), where\n"
|
||||
"> 'value_1' is 1234.5\n" // TODO Locale handling (use LC_ALL=C on Linux)
|
||||
"> must be equal to\n"
|
||||
"> 'value_2' is 1234.56\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testEQ_double_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_eq_3(1234.0f, 1234.0f);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void test_check_ne_1(int value_1, int value_2)
|
||||
{
|
||||
CV_CheckNE(value_1, value_2, "Validation NE check failed");
|
||||
}
|
||||
TEST(Core_Check, testNE_int_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_ne_1(123, 123);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation NE check failed (expected: 'value_1 != value_2'), where\n"
|
||||
"> 'value_1' is 123\n"
|
||||
"> must be not equal to\n"
|
||||
"> 'value_2' is 123\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testNE_int_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_ne_1(123, 1234);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void test_check_le_1(int value_1, int value_2)
|
||||
{
|
||||
CV_CheckLE(value_1, value_2, "Validation LE check failed");
|
||||
}
|
||||
TEST(Core_Check, testLE_int_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_le_1(1234, 123);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation LE check failed (expected: 'value_1 <= value_2'), where\n"
|
||||
"> 'value_1' is 1234\n"
|
||||
"> must be less than or equal to\n"
|
||||
"> 'value_2' is 123\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testLE_int_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_le_1(1234, 1234);
|
||||
});
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_le_1(123, 1234);
|
||||
});
|
||||
}
|
||||
|
||||
void test_check_lt_1(int value_1, int value_2)
|
||||
{
|
||||
CV_CheckLT(value_1, value_2, "Validation LT check failed");
|
||||
}
|
||||
TEST(Core_Check, testLT_int_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_lt_1(1234, 123);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation LT check failed (expected: 'value_1 < value_2'), where\n"
|
||||
"> 'value_1' is 1234\n"
|
||||
"> must be less than\n"
|
||||
"> 'value_2' is 123\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testLT_int_fail_eq)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_lt_1(123, 123);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation LT check failed (expected: 'value_1 < value_2'), where\n"
|
||||
"> 'value_1' is 123\n"
|
||||
"> must be less than\n"
|
||||
"> 'value_2' is 123\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testLT_int_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_lt_1(123, 1234);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void test_check_ge_1(int value_1, int value_2)
|
||||
{
|
||||
CV_CheckGE(value_1, value_2, "Validation GE check failed");
|
||||
}
|
||||
TEST(Core_Check, testGE_int_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_ge_1(123, 1234);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation GE check failed (expected: 'value_1 >= value_2'), where\n"
|
||||
"> 'value_1' is 123\n"
|
||||
"> must be greater than or equal to\n"
|
||||
"> 'value_2' is 1234\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testGE_int_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_ge_1(1234, 1234);
|
||||
});
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_ge_1(1234, 123);
|
||||
});
|
||||
}
|
||||
|
||||
void test_check_gt_1(int value_1, int value_2)
|
||||
{
|
||||
CV_CheckGT(value_1, value_2, "Validation GT check failed");
|
||||
}
|
||||
TEST(Core_Check, testGT_int_fail)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_gt_1(123, 1234);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation GT check failed (expected: 'value_1 > value_2'), where\n"
|
||||
"> 'value_1' is 123\n"
|
||||
"> must be greater than\n"
|
||||
"> 'value_2' is 1234\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testGT_int_fail_eq)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_gt_1(123, 123);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Validation GT check failed (expected: 'value_1 > value_2'), where\n"
|
||||
"> 'value_1' is 123\n"
|
||||
"> must be greater than\n"
|
||||
"> 'value_2' is 123\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
TEST(Core_Check, testGT_int_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_gt_1(1234, 123);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void test_check_MatType_1(int src_type)
|
||||
{
|
||||
CV_CheckTypeEQ(src_type, CV_32FC1, "Unsupported source type");
|
||||
}
|
||||
TEST(Core_Check, testMatType_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_MatType_1(CV_MAKE_TYPE(CV_32F, 1));
|
||||
});
|
||||
}
|
||||
TEST(Core_Check, testMatType_fail_1)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_MatType_1(CV_8UC1);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Unsupported source type (expected: 'src_type == CV_32FC1'), where\n"
|
||||
"> 'src_type' is 0 (CV_8UC1)\n"
|
||||
"> must be equal to\n"
|
||||
"> 'CV_32FC1' is 5 (CV_32FC1)\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
|
||||
void test_check_MatType_2(int src_type)
|
||||
{
|
||||
CV_CheckType(src_type, src_type == CV_32FC1 || src_type == CV_32FC3, "Unsupported src");
|
||||
}
|
||||
TEST(Core_Check, testMatType_fail_2)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_MatType_2(CV_8UC1);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Unsupported src:\n"
|
||||
"> 'src_type == CV_32FC1 || src_type == CV_32FC3'\n"
|
||||
"> where\n"
|
||||
"> 'src_type' is 0 (CV_8UC1)\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
|
||||
void test_check_MatDepth_1(int src_depth)
|
||||
{
|
||||
CV_CheckDepthEQ(src_depth, CV_32F, "Unsupported source depth");
|
||||
}
|
||||
TEST(Core_Check, testMatDepth_pass)
|
||||
{
|
||||
EXPECT_NO_THROW(
|
||||
{
|
||||
test_check_MatDepth_1(CV_MAKE_TYPE(CV_32F, 1));
|
||||
});
|
||||
}
|
||||
TEST(Core_Check, testMatDepth_fail_1)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_MatDepth_1(CV_8U);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Unsupported source depth (expected: 'src_depth == CV_32F'), where\n"
|
||||
"> 'src_depth' is 0 (CV_8U)\n"
|
||||
"> must be equal to\n"
|
||||
"> 'CV_32F' is 5 (CV_32F)\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
|
||||
void test_check_MatDepth_2(int src_depth)
|
||||
{
|
||||
CV_CheckDepth(src_depth, src_depth == CV_32F || src_depth == CV_64F, "Unsupported src");
|
||||
}
|
||||
TEST(Core_Check, testMatDepth_fail_2)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_MatDepth_2(CV_8U);
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Unsupported src:\n"
|
||||
"> 'src_depth == CV_32F || src_depth == CV_64F'\n"
|
||||
"> where\n"
|
||||
"> 'src_depth' is 0 (CV_8U)\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test_check_Size_1(const Size& srcSz)
|
||||
{
|
||||
CV_Check(srcSz, srcSz == Size(4, 3), "Unsupported src size");
|
||||
}
|
||||
TEST(Core_Check, testSize_1)
|
||||
{
|
||||
try
|
||||
{
|
||||
test_check_Size_1(Size(2, 1));
|
||||
FAIL() << "Unreachable code called";
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_STREQ(e.err.c_str(),
|
||||
"> Unsupported src size:\n"
|
||||
"> 'srcSz == Size(4, 3)'\n"
|
||||
"> where\n"
|
||||
"> 'srcSz' is [2 x 1]\n"
|
||||
);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
FAIL() << "Unexpected C++ exception: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unexpected unknown exception";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_Allocation, alignedAllocation)
|
||||
{
|
||||
// iterate from size=1 to approximate byte size of 8K 32bpp image buffer
|
||||
for (int i = 0; i < 200; i++) {
|
||||
const size_t size = static_cast<size_t>(std::pow(1.091, (double)i));
|
||||
void * const buf = cv::fastMalloc(size);
|
||||
ASSERT_NE((uintptr_t)0, (uintptr_t)buf)
|
||||
<< "failed to allocate memory";
|
||||
ASSERT_EQ((uintptr_t)0, (uintptr_t)buf % CV_MALLOC_ALIGN)
|
||||
<< "memory not aligned to " << CV_MALLOC_ALIGN;
|
||||
cv::fastFree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !(defined(__GNUC__) && __GNUC__ < 5) // GCC 4.8 emits: 'is_trivially_copyable' is not a member of 'std'
|
||||
TEST(Core_Types, trivially_copyable)
|
||||
{
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Complexd>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Point>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Point3f>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Size>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Range>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Rect>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::RotatedRect>::value);
|
||||
//EXPECT_TRUE(std::is_trivially_copyable<cv::Scalar>::value); // derived from Vec (Matx)
|
||||
}
|
||||
|
||||
TEST(Core_Types, trivially_copyable_extra)
|
||||
{
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::KeyPoint>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::DMatch>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::TermCriteria>::value);
|
||||
EXPECT_TRUE(std::is_trivially_copyable<cv::Moments>::value);
|
||||
}
|
||||
#endif
|
||||
|
||||
}} // namespace
|
238
3rdparty/opencv-4.5.4/modules/core/test/test_opencl.cpp
vendored
Normal file
238
3rdparty/opencv-4.5.4/modules/core/test/test_opencl.cpp
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
|
||||
namespace opencv_test {
|
||||
namespace ocl {
|
||||
|
||||
static
|
||||
testing::internal::ParamGenerator<std::string> getOpenCLTestConfigurations()
|
||||
{
|
||||
if (!cv::ocl::useOpenCL())
|
||||
{
|
||||
return testing::ValuesIn(std::vector<std::string>());
|
||||
}
|
||||
|
||||
std::vector<std::string> configurations = {
|
||||
":GPU:0",
|
||||
":GPU:1",
|
||||
":CPU:0",
|
||||
};
|
||||
return testing::ValuesIn(configurations);
|
||||
}
|
||||
|
||||
|
||||
static void executeUMatCall(bool requireOpenCL = true)
|
||||
{
|
||||
UMat a(100, 100, CV_8UC1, Scalar::all(0));
|
||||
UMat b;
|
||||
cv::add(a, Scalar::all(1), b);
|
||||
Mat b_cpu = b.getMat(ACCESS_READ);
|
||||
EXPECT_EQ(0, cv::norm(b_cpu - 1, NORM_INF));
|
||||
|
||||
if (requireOpenCL)
|
||||
{
|
||||
EXPECT_TRUE(cv::ocl::useOpenCL());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OCL_Context, createFromDevice)
|
||||
{
|
||||
bool useOCL = cv::ocl::useOpenCL();
|
||||
|
||||
OpenCLExecutionContext ctx = OpenCLExecutionContext::getCurrent();
|
||||
|
||||
if (!useOCL)
|
||||
{
|
||||
ASSERT_TRUE(ctx.empty()); // Other tests should not broke global state
|
||||
throw SkipTestException("OpenCL is not available / disabled");
|
||||
}
|
||||
|
||||
ASSERT_FALSE(ctx.empty());
|
||||
|
||||
ocl::Device device = ctx.getDevice();
|
||||
ASSERT_FALSE(device.empty());
|
||||
|
||||
ocl::Context context = ocl::Context::fromDevice(device);
|
||||
ocl::Context context2 = ocl::Context::fromDevice(device);
|
||||
|
||||
EXPECT_TRUE(context.getImpl() == context2.getImpl()) << "Broken cache for OpenCL context (device)";
|
||||
}
|
||||
|
||||
TEST(OCL_OpenCLExecutionContextDefault, basic)
|
||||
{
|
||||
bool useOCL = cv::ocl::useOpenCL();
|
||||
|
||||
OpenCLExecutionContext ctx = OpenCLExecutionContext::getCurrent();
|
||||
|
||||
if (!useOCL)
|
||||
{
|
||||
ASSERT_TRUE(ctx.empty()); // Other tests should not broke global state
|
||||
throw SkipTestException("OpenCL is not available / disabled");
|
||||
}
|
||||
|
||||
ASSERT_FALSE(ctx.empty());
|
||||
|
||||
ocl::Context context = ctx.getContext();
|
||||
ocl::Context context2 = ocl::Context::getDefault();
|
||||
EXPECT_TRUE(context.getImpl() == context2.getImpl());
|
||||
|
||||
ocl::Device device = ctx.getDevice();
|
||||
ocl::Device device2 = ocl::Device::getDefault();
|
||||
EXPECT_TRUE(device.getImpl() == device2.getImpl());
|
||||
|
||||
ocl::Queue queue = ctx.getQueue();
|
||||
ocl::Queue queue2 = ocl::Queue::getDefault();
|
||||
EXPECT_TRUE(queue.getImpl() == queue2.getImpl());
|
||||
}
|
||||
|
||||
TEST(OCL_OpenCLExecutionContextDefault, createAndBind)
|
||||
{
|
||||
bool useOCL = cv::ocl::useOpenCL();
|
||||
|
||||
OpenCLExecutionContext ctx = OpenCLExecutionContext::getCurrent();
|
||||
|
||||
if (!useOCL)
|
||||
{
|
||||
ASSERT_TRUE(ctx.empty()); // Other tests should not broke global state
|
||||
throw SkipTestException("OpenCL is not available / disabled");
|
||||
}
|
||||
|
||||
ASSERT_FALSE(ctx.empty());
|
||||
|
||||
ocl::Context context = ctx.getContext();
|
||||
ocl::Device device = ctx.getDevice();
|
||||
|
||||
OpenCLExecutionContext ctx2 = OpenCLExecutionContext::create(context, device);
|
||||
ASSERT_FALSE(ctx2.empty());
|
||||
|
||||
try
|
||||
{
|
||||
ctx2.bind();
|
||||
executeUMatCall();
|
||||
ctx.bind();
|
||||
executeUMatCall();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ctx.bind(); // restore
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<std::string> OCL_OpenCLExecutionContext_P;
|
||||
|
||||
TEST_P(OCL_OpenCLExecutionContext_P, multipleBindAndExecute)
|
||||
{
|
||||
bool useOCL = cv::ocl::useOpenCL();
|
||||
|
||||
OpenCLExecutionContext ctx = OpenCLExecutionContext::getCurrent();
|
||||
|
||||
if (!useOCL)
|
||||
{
|
||||
ASSERT_TRUE(ctx.empty()); // Other tests should not broke global state
|
||||
throw SkipTestException("OpenCL is not available / disabled");
|
||||
}
|
||||
|
||||
ASSERT_FALSE(ctx.empty());
|
||||
|
||||
std::string opencl_device = GetParam();
|
||||
ocl::Context context = ocl::Context::create(opencl_device);
|
||||
if (context.empty())
|
||||
{
|
||||
throw SkipTestException(std::string("OpenCL device is not available: '") + opencl_device + "'");
|
||||
}
|
||||
|
||||
ocl::Device device = context.device(0);
|
||||
|
||||
OpenCLExecutionContext ctx2 = OpenCLExecutionContext::create(context, device);
|
||||
ASSERT_FALSE(ctx2.empty());
|
||||
|
||||
try
|
||||
{
|
||||
std::cout << "ctx2..." << std::endl;
|
||||
ctx2.bind();
|
||||
executeUMatCall();
|
||||
std::cout << "ctx..." << std::endl;
|
||||
ctx.bind();
|
||||
executeUMatCall();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ctx.bind(); // restore
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(OCL_OpenCLExecutionContext_P, ScopeTest)
|
||||
{
|
||||
bool useOCL = cv::ocl::useOpenCL();
|
||||
|
||||
OpenCLExecutionContext ctx = OpenCLExecutionContext::getCurrent();
|
||||
|
||||
if (!useOCL)
|
||||
{
|
||||
ASSERT_TRUE(ctx.empty()); // Other tests should not broke global state
|
||||
throw SkipTestException("OpenCL is not available / disabled");
|
||||
}
|
||||
|
||||
ASSERT_FALSE(ctx.empty());
|
||||
|
||||
std::string opencl_device = GetParam();
|
||||
ocl::Context context = ocl::Context::create(opencl_device);
|
||||
if (context.empty())
|
||||
{
|
||||
throw SkipTestException(std::string("OpenCL device is not available: '") + opencl_device + "'");
|
||||
}
|
||||
|
||||
ocl::Device device = context.device(0);
|
||||
|
||||
OpenCLExecutionContext ctx2 = OpenCLExecutionContext::create(context, device);
|
||||
ASSERT_FALSE(ctx2.empty());
|
||||
|
||||
try
|
||||
{
|
||||
OpenCLExecutionContextScope ctx_scope(ctx2);
|
||||
executeUMatCall();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ctx.bind(); // restore
|
||||
throw;
|
||||
}
|
||||
|
||||
executeUMatCall();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, OCL_OpenCLExecutionContext_P, getOpenCLTestConfigurations());
|
||||
|
||||
|
||||
typedef testing::TestWithParam<UMatUsageFlags> UsageFlagsFixture;
|
||||
OCL_TEST_P(UsageFlagsFixture, UsageFlagsRetained)
|
||||
{
|
||||
if (!cv::ocl::useOpenCL())
|
||||
{
|
||||
throw SkipTestException("OpenCL is not available / disabled");
|
||||
}
|
||||
|
||||
const UMatUsageFlags usage = GetParam();
|
||||
cv::UMat flip_in(10, 10, CV_32F, usage);
|
||||
cv::UMat flip_out(usage);
|
||||
cv::flip(flip_in, flip_out, 1);
|
||||
cv::ocl::finish();
|
||||
|
||||
ASSERT_EQ(usage, flip_in.usageFlags);
|
||||
ASSERT_EQ(usage, flip_out.usageFlags);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
/*nothing*/,
|
||||
UsageFlagsFixture,
|
||||
testing::Values(USAGE_DEFAULT, USAGE_ALLOCATE_HOST_MEMORY, USAGE_ALLOCATE_DEVICE_MEMORY)
|
||||
);
|
||||
|
||||
|
||||
} } // namespace opencv_test::ocl
|
1564
3rdparty/opencv-4.5.4/modules/core/test/test_operations.cpp
vendored
Normal file
1564
3rdparty/opencv-4.5.4/modules/core/test/test_operations.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
15
3rdparty/opencv-4.5.4/modules/core/test/test_precomp.hpp
vendored
Normal file
15
3rdparty/opencv-4.5.4/modules/core/test/test_precomp.hpp
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef __OPENCV_TEST_PRECOMP_HPP__
|
||||
#define __OPENCV_TEST_PRECOMP_HPP__
|
||||
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/ts/ocl_test.hpp"
|
||||
#include "opencv2/core/core_c.h"
|
||||
|
||||
#include "opencv2/core/cvdef.h"
|
||||
#include "opencv2/core/private.hpp"
|
||||
#include "opencv2/core/hal/hal.hpp"
|
||||
|
||||
#endif
|
417
3rdparty/opencv-4.5.4/modules/core/test/test_ptr.cpp
vendored
Normal file
417
3rdparty/opencv-4.5.4/modules/core/test/test_ptr.cpp
vendored
Normal file
@ -0,0 +1,417 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
#ifdef GTEST_CAN_COMPARE_NULL
|
||||
# define EXPECT_NULL(ptr) EXPECT_EQ(NULL, ptr)
|
||||
#else
|
||||
# define EXPECT_NULL(ptr) EXPECT_TRUE(ptr == NULL)
|
||||
#endif
|
||||
|
||||
using namespace cv;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Reporter {
|
||||
Reporter(bool* deleted) : deleted_(deleted)
|
||||
{ *deleted_ = false; }
|
||||
|
||||
// the destructor is virtual, so that we can test dynamic_cast later
|
||||
virtual ~Reporter()
|
||||
{ *deleted_ = true; }
|
||||
|
||||
private:
|
||||
bool* deleted_;
|
||||
|
||||
Reporter(const Reporter&);
|
||||
Reporter& operator = (const Reporter&);
|
||||
};
|
||||
|
||||
struct ReportingDeleter {
|
||||
ReportingDeleter(bool* deleted) : deleted_(deleted)
|
||||
{ *deleted_ = false; }
|
||||
|
||||
void operator()(void*)
|
||||
{ *deleted_ = true; }
|
||||
|
||||
private:
|
||||
bool* deleted_;
|
||||
};
|
||||
|
||||
int dummyObject;
|
||||
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, default_ctor)
|
||||
{
|
||||
Ptr<int> p;
|
||||
EXPECT_NULL(p.get());
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, owning_ctor)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
Reporter* r = new Reporter(&deleted);
|
||||
Ptr<void> p(r);
|
||||
EXPECT_EQ(r, p.get());
|
||||
}
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<int> p(&dummyObject, ReportingDeleter(&deleted));
|
||||
EXPECT_EQ(&dummyObject, p.get());
|
||||
}
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<void> p((void*)0, ReportingDeleter(&deleted));
|
||||
EXPECT_NULL(p.get());
|
||||
}
|
||||
EXPECT_TRUE(deleted); // Differ from OpenCV 3.4 (but conformant to std::shared_ptr, see below)
|
||||
|
||||
{
|
||||
std::shared_ptr<void> p((void*)0, ReportingDeleter(&deleted));
|
||||
EXPECT_NULL(p.get());
|
||||
}
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, sharing_ctor)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<Reporter> p2(p1);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<void> p2(p1);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<int> p2(p1, &dummyObject);
|
||||
EXPECT_EQ(&dummyObject, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, assignment)
|
||||
{
|
||||
bool deleted1 = false, deleted2 = false;
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted1));
|
||||
p1 = *&p1;
|
||||
EXPECT_FALSE(deleted1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted1));
|
||||
Ptr<Reporter> p2(new Reporter(&deleted2));
|
||||
p2 = p1;
|
||||
EXPECT_TRUE(deleted2);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted1));
|
||||
Ptr<void> p2(new Reporter(&deleted2));
|
||||
p2 = p1;
|
||||
EXPECT_TRUE(deleted2);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, release)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted);
|
||||
EXPECT_NULL(p1.get());
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, reset)
|
||||
{
|
||||
bool deleted_old = false, deleted_new = false;
|
||||
|
||||
{
|
||||
Ptr<void> p(new Reporter(&deleted_old));
|
||||
Reporter* r = new Reporter(&deleted_new);
|
||||
p.reset(r);
|
||||
EXPECT_TRUE(deleted_old);
|
||||
EXPECT_EQ(r, p.get());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted_new);
|
||||
|
||||
{
|
||||
Ptr<void> p(new Reporter(&deleted_old));
|
||||
p.reset(&dummyObject, ReportingDeleter(&deleted_new));
|
||||
EXPECT_TRUE(deleted_old);
|
||||
EXPECT_EQ(&dummyObject, p.get());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted_new);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, swap)
|
||||
{
|
||||
bool deleted1 = false, deleted2 = false;
|
||||
|
||||
{
|
||||
Reporter* r1 = new Reporter(&deleted1);
|
||||
Reporter* r2 = new Reporter(&deleted2);
|
||||
Ptr<Reporter> p1(r1), p2(r2);
|
||||
p1.swap(p2);
|
||||
EXPECT_EQ(r1, p2.get());
|
||||
EXPECT_EQ(r2, p1.get());
|
||||
EXPECT_FALSE(deleted1);
|
||||
EXPECT_FALSE(deleted2);
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted2);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
|
||||
{
|
||||
Reporter* r1 = new Reporter(&deleted1);
|
||||
Reporter* r2 = new Reporter(&deleted2);
|
||||
Ptr<Reporter> p1(r1), p2(r2);
|
||||
swap(p1, p2);
|
||||
EXPECT_EQ(r1, p2.get());
|
||||
EXPECT_EQ(r2, p1.get());
|
||||
EXPECT_FALSE(deleted1);
|
||||
EXPECT_FALSE(deleted2);
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted2);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, accessors)
|
||||
{
|
||||
{
|
||||
Ptr<int> p;
|
||||
EXPECT_NULL(static_cast<int*>(p));
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
|
||||
{
|
||||
Size* s = new Size();
|
||||
Ptr<Size> p(s);
|
||||
EXPECT_EQ(s, static_cast<Size*>(p));
|
||||
EXPECT_EQ(s, &*p);
|
||||
EXPECT_EQ(&s->width, &p->width);
|
||||
EXPECT_FALSE(p.empty());
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct SubReporterBase {
|
||||
virtual ~SubReporterBase() {}
|
||||
int padding;
|
||||
};
|
||||
|
||||
/* multiple inheritance, so that casts do something interesting */
|
||||
struct SubReporter : SubReporterBase, Reporter
|
||||
{
|
||||
SubReporter(bool* deleted) : Reporter(deleted)
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, casts)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
Ptr<const Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<Reporter> p2 = p1.constCast<Reporter>();
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
SubReporter* sr = new SubReporter(&deleted);
|
||||
Ptr<Reporter> p1(sr);
|
||||
// This next check isn't really for Ptr itself; it checks that Reporter
|
||||
// is at a non-zero offset within SubReporter, so that the next
|
||||
// check will give us more confidence that the cast actually did something.
|
||||
EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
|
||||
Ptr<SubReporter> p2 = p1.staticCast<SubReporter>();
|
||||
EXPECT_EQ(sr, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
SubReporter* sr = new SubReporter(&deleted);
|
||||
Ptr<Reporter> p1(sr);
|
||||
EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
|
||||
Ptr<void> p2 = p1.dynamicCast<void>();
|
||||
EXPECT_EQ(sr, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<SubReporter> p2 = p1.dynamicCast<SubReporter>();
|
||||
EXPECT_NULL(p2.get());
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, comparisons)
|
||||
{
|
||||
Ptr<int> p1, p2(new int), p3(new int);
|
||||
Ptr<int> p4(p2, p3.get());
|
||||
|
||||
// Not using EXPECT_EQ here, since none of them are really "expected" or "actual".
|
||||
EXPECT_TRUE(p1 == p1);
|
||||
EXPECT_TRUE(p2 == p2);
|
||||
EXPECT_TRUE(p2 != p3);
|
||||
EXPECT_TRUE(p2 != p4);
|
||||
EXPECT_TRUE(p3 == p4);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, make)
|
||||
{
|
||||
bool deleted = true;
|
||||
|
||||
{
|
||||
Ptr<void> p = makePtr<Reporter>(&deleted);
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
namespace {
|
||||
|
||||
struct SpeciallyDeletable
|
||||
{
|
||||
SpeciallyDeletable() : deleted(false)
|
||||
{}
|
||||
bool deleted;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cv {
|
||||
template<> struct DefaultDeleter<SpeciallyDeletable>
|
||||
{
|
||||
void operator()(SpeciallyDeletable * obj) const { obj->deleted = true; }
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
TEST(Core_Ptr, specialized_deleter)
|
||||
{
|
||||
SpeciallyDeletable sd;
|
||||
|
||||
{ Ptr<void> p(&sd); }
|
||||
|
||||
ASSERT_TRUE(sd.deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, specialized_deleter_via_reset)
|
||||
{
|
||||
SpeciallyDeletable sd;
|
||||
|
||||
{
|
||||
Ptr<SpeciallyDeletable> p;
|
||||
p.reset(&sd);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(sd.deleted);
|
||||
}
|
||||
|
||||
}} // namespace
|
492
3rdparty/opencv-4.5.4/modules/core/test/test_quaternion.cpp
vendored
Normal file
492
3rdparty/opencv-4.5.4/modules/core/test/test_quaternion.cpp
vendored
Normal file
@ -0,0 +1,492 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/ts/cuda_test.hpp> // EXPECT_MAT_NEAR
|
||||
|
||||
#include <opencv2/core/quaternion.hpp>
|
||||
#include <opencv2/core/dualquaternion.hpp>
|
||||
|
||||
namespace opencv_test{ namespace {
|
||||
|
||||
class QuatTest: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
q1 = {1,2,3,4};
|
||||
q2 = {2.5,-2,3.5,4};
|
||||
q1Unit = {1 / sqrt(30), sqrt(2) /sqrt(15), sqrt(3) / sqrt(10), 2 * sqrt(2) / sqrt(15)};
|
||||
q1Inv = {1.0 / 30, -1.0 / 15, -1.0 / 10, -2.0 / 15};
|
||||
}
|
||||
double scalar = 2.5;
|
||||
double angle = CV_PI;
|
||||
double qNorm2 = 2;
|
||||
Vec<double, 3> axis{1, 1, 1};
|
||||
Vec<double, 3> unAxis{0, 0, 0};
|
||||
Vec<double, 3> unitAxis{1.0 / sqrt(3), 1.0 / sqrt(3), 1.0 / sqrt(3)};
|
||||
Quatd q3 = Quatd::createFromAngleAxis(angle, axis);
|
||||
Quatd q3UnitAxis = Quatd::createFromAngleAxis(angle, unitAxis);
|
||||
Quat<double> q3Norm2 = q3 * qNorm2;
|
||||
|
||||
Quat<double> q1Inv;
|
||||
Quat<double> q1;
|
||||
Quat<double> q2;
|
||||
Quat<double> q1Unit;
|
||||
|
||||
Quatd qNull{0, 0, 0, 0};
|
||||
Quatd qIdentity{1, 0, 0, 0};
|
||||
QuatAssumeType assumeUnit = QUAT_ASSUME_UNIT;
|
||||
|
||||
};
|
||||
|
||||
TEST_F(QuatTest, constructor)
|
||||
{
|
||||
Vec<double, 4> coeff{1, 2, 3, 4};
|
||||
EXPECT_EQ(Quat<double> (coeff), q1);
|
||||
EXPECT_EQ(q3, q3UnitAxis);
|
||||
EXPECT_ANY_THROW(Quatd::createFromAngleAxis(angle, unAxis));
|
||||
Matx33d R1{
|
||||
-1.0 / 3, 2.0 / 3 , 2.0 / 3,
|
||||
2.0 / 3 , -1.0 / 3, 2.0 / 3,
|
||||
2.0 / 3 , 2.0 / 3 , -1.0 / 3
|
||||
};
|
||||
Matx33d R2{
|
||||
-2.0 / 3, -2.0 / 3, -1.0 / 3,
|
||||
-2.0 / 3, 1.0 / 3, 2.0 / 3,
|
||||
-1.0 / 3, 2.0 / 3, -2.0 / 3
|
||||
};
|
||||
Matx33d R3{
|
||||
0.818181818181, 0.181818181818, 0.54545455454,
|
||||
0.545454545545, -0.54545454545, -0.6363636364,
|
||||
0.181818181818, 0.818181818182, -0.5454545455
|
||||
};
|
||||
Matx33d R4{
|
||||
0.818181818181, -0.181818181818, 0.54545455454,
|
||||
0.545454545545, 0.54545454545, -0.6363636364,
|
||||
-0.181818181818, 0.818181818182, 0.5454545455
|
||||
};
|
||||
Quatd qMat = Quatd::createFromRotMat(R1);
|
||||
Quatd qMat2 = Quatd::createFromRotMat(R2);
|
||||
Quatd qMat3 = Quatd::createFromRotMat(R3);
|
||||
Quatd qMat4 = Quatd::createFromRotMat(R4);
|
||||
EXPECT_EQ(qMat2, Quatd(0, -0.408248290463, 0.816496580927, 0.408248904638));
|
||||
EXPECT_EQ(qMat3, Quatd(-0.426401432711,-0.852802865422, -0.213200716355, -0.2132007163));
|
||||
EXPECT_EQ(qMat, q3);
|
||||
EXPECT_EQ(qMat4, -Quatd(0.852802865422, 0.426401432711221, 0.2132007163556, 0.2132007163));
|
||||
|
||||
Vec3d rot{angle / sqrt(3),angle / sqrt(3), angle / sqrt(3)};
|
||||
Quatd rotQuad{0, 1.0 / sqrt(3), 1. / sqrt(3), 1. / sqrt(3)};
|
||||
Quatd qRot = Quatd::createFromRvec(rot);
|
||||
EXPECT_EQ(qRot, rotQuad);
|
||||
EXPECT_EQ(Quatd::createFromRvec(Vec3d(0, 0, 0)), qIdentity);
|
||||
}
|
||||
|
||||
TEST_F(QuatTest, basicfuns)
|
||||
{
|
||||
Quat<double> q1Conj{1, -2, -3, -4};
|
||||
EXPECT_EQ(q3Norm2.normalize(), q3);
|
||||
EXPECT_EQ(q1.norm(), sqrt(30));
|
||||
EXPECT_EQ(q1.normalize(), q1Unit);
|
||||
EXPECT_ANY_THROW(qNull.normalize());
|
||||
EXPECT_EQ(q1.conjugate(), q1Conj);
|
||||
EXPECT_EQ(q1.inv(), q1Inv);
|
||||
EXPECT_EQ(inv(q1), q1Inv);
|
||||
EXPECT_EQ(q3.inv(assumeUnit) * q3, qIdentity);
|
||||
EXPECT_EQ(q1.inv() * q1, qIdentity);
|
||||
EXPECT_ANY_THROW(inv(qNull));
|
||||
EXPECT_NO_THROW(q1.at(0));
|
||||
EXPECT_ANY_THROW(q1.at(4));
|
||||
|
||||
Matx33d R{
|
||||
-2.0 / 3, 2.0 / 15 , 11.0 / 15,
|
||||
2.0 / 3 , -1.0 / 3 , 2.0 / 3 ,
|
||||
1.0 / 3 , 14.0 / 15, 2.0 / 15
|
||||
};
|
||||
Matx33d q1RotMat = q1.toRotMat3x3();
|
||||
EXPECT_MAT_NEAR(q1RotMat, R, 1e-6);
|
||||
Vec3d z_axis{0,0,1};
|
||||
Quatd q_unit1 = Quatd::createFromAngleAxis(angle, z_axis);
|
||||
Mat pointsA = (Mat_<double>(2, 3) << 1,0,0,1,0,1);
|
||||
pointsA = pointsA.t();
|
||||
Mat new_point = q_unit1.toRotMat3x3() * pointsA;
|
||||
Mat afterRo = (Mat_<double>(3, 2) << -1,-1,0,0,0,1);
|
||||
EXPECT_MAT_NEAR(afterRo, new_point, 1e-6);
|
||||
EXPECT_ANY_THROW(qNull.toRotVec());
|
||||
Vec3d rodVec{CV_PI/sqrt(3), CV_PI/sqrt(3), CV_PI/sqrt(3)};
|
||||
Vec3d q3Rod = q3.toRotVec();
|
||||
EXPECT_NEAR(q3Rod[0], rodVec[0], 1e-6);
|
||||
EXPECT_NEAR(q3Rod[1], rodVec[1], 1e-6);
|
||||
EXPECT_NEAR(q3Rod[2], rodVec[2], 1e-6);
|
||||
|
||||
EXPECT_EQ(log(q1Unit, assumeUnit), log(q1Unit));
|
||||
EXPECT_EQ(log(qIdentity, assumeUnit), qNull);
|
||||
EXPECT_EQ(log(q3), Quatd(0, angle * unitAxis[0] / 2, angle * unitAxis[1] / 2, angle * unitAxis[2] / 2));
|
||||
EXPECT_ANY_THROW(log(qNull));
|
||||
EXPECT_EQ(log(Quatd(exp(1), 0, 0, 0)), qIdentity);
|
||||
|
||||
EXPECT_EQ(exp(qIdentity), Quatd(exp(1), 0, 0, 0));
|
||||
EXPECT_EQ(exp(qNull), qIdentity);
|
||||
EXPECT_EQ(exp(Quatd(0, angle * unitAxis[0] / 2, angle * unitAxis[1] / 2, angle * unitAxis[2] / 2)), q3);
|
||||
|
||||
EXPECT_EQ(power(q3, 2.0), Quatd::createFromAngleAxis(2*angle, axis));
|
||||
EXPECT_EQ(power(Quatd(0.5, 0.5, 0.5, 0.5), 2.0, assumeUnit), Quatd(-0.5,0.5,0.5,0.5));
|
||||
EXPECT_EQ(power(Quatd(0.5, 0.5, 0.5, 0.5), -2.0), Quatd(-0.5,-0.5,-0.5,-0.5));
|
||||
EXPECT_EQ(sqrt(q1), power(q1, 0.5));
|
||||
EXPECT_EQ(exp(q3 * log(q1)), power(q1, q3));
|
||||
EXPECT_EQ(exp(q1 * log(q3)), power(q3, q1, assumeUnit));
|
||||
EXPECT_EQ(crossProduct(q1, q3), (q1 * q3 - q3 * q1) / 2);
|
||||
EXPECT_EQ(sinh(qNull), qNull);
|
||||
EXPECT_EQ(sinh(q1), (exp(q1) - exp(-q1)) / 2);
|
||||
EXPECT_EQ(sinh(qIdentity), Quatd(sinh(1), 0, 0, 0));
|
||||
EXPECT_EQ(sinh(q1), Quatd(0.73233760604, -0.44820744998, -0.67231117497, -0.8964148999610843));
|
||||
EXPECT_EQ(cosh(qNull), qIdentity);
|
||||
EXPECT_EQ(cosh(q1), Quatd(0.961585117636, -0.34135217456, -0.51202826184, -0.682704349122));
|
||||
EXPECT_EQ(tanh(q1), sinh(q1) * inv(cosh(q1)));
|
||||
EXPECT_EQ(sin(qNull), qNull);
|
||||
EXPECT_EQ(sin(q1), Quatd(91.78371578403, 21.88648685303, 32.829730279543, 43.772973706058));
|
||||
EXPECT_EQ(cos(qNull), qIdentity);
|
||||
EXPECT_EQ(cos(q1), Quatd(58.9336461679, -34.0861836904, -51.12927553569, -68.17236738093));
|
||||
EXPECT_EQ(tan(q1), sin(q1)/cos(q1));
|
||||
EXPECT_EQ(sinh(asinh(q1)), q1);
|
||||
Quatd c1 = asinh(sinh(q1));
|
||||
EXPECT_EQ(sinh(c1), sinh(q1));
|
||||
EXPECT_EQ(cosh(acosh(q1)), q1);
|
||||
c1 = acosh(cosh(q1));
|
||||
EXPECT_EQ(cosh(c1), cosh(q1));
|
||||
EXPECT_EQ(tanh(atanh(q1)), q1);
|
||||
c1 = atanh(tanh(q1));
|
||||
EXPECT_EQ(tanh(q1), tanh(c1));
|
||||
EXPECT_EQ(asin(sin(q1)), q1);
|
||||
EXPECT_EQ(sin(asin(q1)), q1);
|
||||
EXPECT_EQ(acos(cos(q1)), q1);
|
||||
EXPECT_EQ(cos(acos(q1)), q1);
|
||||
EXPECT_EQ(atan(tan(q3)), q3);
|
||||
EXPECT_EQ(tan(atan(q1)), q1);
|
||||
}
|
||||
|
||||
TEST_F(QuatTest, test_operator)
|
||||
{
|
||||
Quatd minusQ{-1, -2, -3, -4};
|
||||
Quatd qAdd{3.5, 0, 6.5, 8};
|
||||
Quatd qMinus{-1.5, 4, -0.5, 0};
|
||||
Quatd qMultq{-20, 1, -5, 27};
|
||||
Quatd qMults{2.5, 5.0, 7.5, 10.0};
|
||||
Quatd qDvss{1.0 / 2.5, 2.0 / 2.5, 3.0 / 2.5, 4.0 / 2.5};
|
||||
Quatd qOrigin(q1);
|
||||
|
||||
EXPECT_EQ(-q1, minusQ);
|
||||
EXPECT_EQ(q1 + q2, qAdd);
|
||||
EXPECT_EQ(q1 + scalar, Quatd(3.5, 2, 3, 4));
|
||||
EXPECT_EQ(scalar + q1, Quatd(3.5, 2, 3, 4));
|
||||
EXPECT_EQ(q1 + 2.0, Quatd(3, 2, 3, 4));
|
||||
EXPECT_EQ(2.0 + q1, Quatd(3, 2, 3, 4));
|
||||
EXPECT_EQ(q1 - q2, qMinus);
|
||||
EXPECT_EQ(q1 - scalar, Quatd(-1.5, 2, 3, 4));
|
||||
EXPECT_EQ(scalar - q1, Quatd(1.5, -2, -3, -4));
|
||||
EXPECT_EQ(q1 - 2.0, Quatd(-1, 2, 3, 4));
|
||||
EXPECT_EQ(2.0 - q1, Quatd(1, -2, -3, -4));
|
||||
EXPECT_EQ(q1 * q2, qMultq);
|
||||
EXPECT_EQ(q1 * scalar, qMults);
|
||||
EXPECT_EQ(scalar * q1, qMults);
|
||||
EXPECT_EQ(q1 / q1, qIdentity);
|
||||
EXPECT_EQ(q1 / scalar, qDvss);
|
||||
q1 += q2;
|
||||
EXPECT_EQ(q1, qAdd);
|
||||
q1 -= q2;
|
||||
EXPECT_EQ(q1, qOrigin);
|
||||
q1 *= q2;
|
||||
EXPECT_EQ(q1, qMultq);
|
||||
q1 /= q2;
|
||||
EXPECT_EQ(q1, qOrigin);
|
||||
q1 *= scalar;
|
||||
EXPECT_EQ(q1, qMults);
|
||||
q1 /= scalar;
|
||||
EXPECT_EQ(q1, qOrigin);
|
||||
EXPECT_NO_THROW(q1[0]);
|
||||
EXPECT_NO_THROW(q1.at(0));
|
||||
EXPECT_ANY_THROW(q1[4]);
|
||||
EXPECT_ANY_THROW(q1.at(4));
|
||||
}
|
||||
|
||||
TEST_F(QuatTest, quatAttrs)
|
||||
{
|
||||
double angleQ1 = 2 * acos(1.0 / sqrt(30));
|
||||
Vec3d axis1{0.3713906763541037, 0.557086014, 0.742781352};
|
||||
Vec<double, 3> q1axis1 = q1.getAxis();
|
||||
|
||||
EXPECT_EQ(angleQ1, q1.getAngle());
|
||||
EXPECT_EQ(angleQ1, q1Unit.getAngle());
|
||||
EXPECT_EQ(angleQ1, q1Unit.getAngle(assumeUnit));
|
||||
EXPECT_EQ(0, qIdentity.getAngle());
|
||||
EXPECT_ANY_THROW(qNull.getAxis());
|
||||
EXPECT_NEAR(axis1[0], q1axis1[0], 1e-6);
|
||||
EXPECT_NEAR(axis1[1], q1axis1[1], 1e-6);
|
||||
EXPECT_NEAR(axis1[2], q1axis1[2], 1e-6);
|
||||
EXPECT_NEAR(q3Norm2.norm(), qNorm2, 1e-6);
|
||||
EXPECT_EQ(q3Norm2.getAngle(), angle);
|
||||
EXPECT_NEAR(axis1[0], axis1[0], 1e-6);
|
||||
EXPECT_NEAR(axis1[1], axis1[1], 1e-6);
|
||||
EXPECT_NEAR(axis1[2], axis1[2], 1e-6);
|
||||
}
|
||||
|
||||
TEST_F(QuatTest, interpolation)
|
||||
{
|
||||
Quatd qNoRot = Quatd::createFromAngleAxis(0, axis);
|
||||
Quatd qLerpInter(1.0 / 2, sqrt(3) / 6, sqrt(3) / 6, sqrt(3) / 6);
|
||||
EXPECT_EQ(Quatd::lerp(qNoRot, q3, 0), qNoRot);
|
||||
EXPECT_EQ(Quatd::lerp(qNoRot, q3, 1), q3);
|
||||
EXPECT_EQ(Quatd::lerp(qNoRot, q3, 0.5), qLerpInter);
|
||||
Quatd q3NrNn2 = qNoRot * qNorm2;
|
||||
EXPECT_EQ(Quatd::nlerp(q3NrNn2, q3Norm2, 0), qNoRot);
|
||||
EXPECT_EQ(Quatd::nlerp(q3NrNn2, q3Norm2, 1), q3);
|
||||
EXPECT_EQ(Quatd::nlerp(q3NrNn2, q3Norm2, 0.5), qLerpInter.normalize());
|
||||
EXPECT_EQ(Quatd::nlerp(qNoRot, q3, 0, assumeUnit), qNoRot);
|
||||
EXPECT_EQ(Quatd::nlerp(qNoRot, q3, 1, assumeUnit), q3);
|
||||
EXPECT_EQ(Quatd::nlerp(qNoRot, q3, 0.5, assumeUnit), qLerpInter.normalize());
|
||||
Quatd q3Minus(-q3);
|
||||
EXPECT_EQ(Quatd::nlerp(qNoRot, q3, 0.4), -Quatd::nlerp(qNoRot, q3Minus, 0.4));
|
||||
EXPECT_EQ(Quatd::slerp(qNoRot, q3, 0, assumeUnit), qNoRot);
|
||||
EXPECT_EQ(Quatd::slerp(qNoRot, q3, 1, assumeUnit), q3);
|
||||
EXPECT_EQ(Quatd::slerp(qNoRot, q3, 0.5, assumeUnit), -Quatd::nlerp(qNoRot, -q3, 0.5, assumeUnit));
|
||||
EXPECT_EQ(Quatd::slerp(qNoRot, q1, 0.5), Quatd(0.76895194, 0.2374325, 0.35614876, 0.47486501));
|
||||
EXPECT_EQ(Quatd::slerp(-qNoRot, q1, 0.5), Quatd(0.76895194, 0.2374325, 0.35614876, 0.47486501));
|
||||
EXPECT_EQ(Quatd::slerp(qNoRot, -q1, 0.5), -Quatd::slerp(-qNoRot, q1, 0.5));
|
||||
|
||||
Quat<double> tr1 = Quatd::createFromAngleAxis(0, axis);
|
||||
Quat<double> tr2 = Quatd::createFromAngleAxis(angle / 2, axis);
|
||||
Quat<double> tr3 = Quatd::createFromAngleAxis(angle, axis);
|
||||
Quat<double> tr4 = Quatd::createFromAngleAxis(angle, Vec3d{-1/sqrt(2),0,1/(sqrt(2))});
|
||||
EXPECT_ANY_THROW(Quatd::spline(qNull, tr1, tr2, tr3, 0));
|
||||
EXPECT_EQ(Quatd::spline(tr1, tr2, tr3, tr4, 0), tr2);
|
||||
EXPECT_EQ(Quatd::spline(tr1, tr2, tr3, tr4, 1), tr3);
|
||||
EXPECT_EQ(Quatd::spline(tr1, tr2, tr3, tr4, 0.6, assumeUnit), Quatd::spline(tr1, tr2, tr3, tr4, 0.6));
|
||||
EXPECT_EQ(Quatd::spline(tr1, tr2, tr3, tr3, 0.5), Quatd::spline(tr1, -tr2, tr3, tr3, 0.5));
|
||||
EXPECT_EQ(Quatd::spline(tr1, tr2, tr3, tr3, 0.5), -Quatd::spline(-tr1, -tr2, -tr3, tr3, 0.5));
|
||||
EXPECT_EQ(Quatd::spline(tr1, tr2, tr3, tr3, 0.5), Quatd(0.336889853392, 0.543600719487, 0.543600719487, 0.543600719487));
|
||||
}
|
||||
|
||||
static const Quatd qEuler[24] = {
|
||||
Quatd(0.7233214, 0.3919013, 0.2005605, 0.5319728), //INT_XYZ
|
||||
Quatd(0.8223654, 0.0222635, 0.3604221, 0.4396766), //INT_XZY
|
||||
Quatd(0.822365, 0.439677, 0.0222635, 0.360422), //INT_YXZ
|
||||
Quatd(0.723321, 0.531973, 0.391901, 0.20056), //INT_YZX
|
||||
Quatd(0.723321, 0.20056, 0.531973, 0.391901), //INT_ZXY
|
||||
Quatd(0.822365, 0.360422, 0.439677, 0.0222635), //INT_ZYX
|
||||
Quatd(0.653285, 0.65328, 0.369641, -0.0990435), //INT_XYX
|
||||
Quatd(0.653285, 0.65328, 0.0990435, 0.369641), //INT_XZX
|
||||
Quatd(0.653285, 0.369641, 0.65328, 0.0990435), //INT_YXY
|
||||
Quatd(0.653285, -0.0990435, 0.65328, 0.369641), //INT_YZY
|
||||
Quatd(0.653285, 0.369641, -0.0990435, 0.65328), //INT_ZXZ
|
||||
Quatd(0.653285, 0.0990435, 0.369641, 0.65328), //INT_ZYZ
|
||||
|
||||
Quatd(0.822365, 0.0222635, 0.439677, 0.360422), //EXT_XYZ
|
||||
Quatd(0.723321, 0.391901, 0.531973, 0.20056), //EXT_XZY
|
||||
Quatd(0.723321, 0.20056, 0.391901, 0.531973), //EXT_YXZ
|
||||
Quatd(0.822365, 0.360422, 0.0222635, 0.439677), //EXT_YZX
|
||||
Quatd(0.822365, 0.439677, 0.360422, 0.0222635), //EXT_ZXY
|
||||
Quatd(0.723321, 0.531973, 0.20056, 0.391901), //EXT_ZYX
|
||||
Quatd(0.653285, 0.65328, 0.369641, 0.0990435), //EXT_XYX
|
||||
Quatd(0.653285, 0.65328, -0.0990435, 0.369641), //EXT_XZX
|
||||
Quatd(0.653285, 0.369641, 0.65328, -0.0990435), //EXT_YXY
|
||||
Quatd(0.653285, 0.0990435, 0.65328, 0.369641), //EXT_YZY
|
||||
Quatd(0.653285, 0.369641, 0.0990435, 0.65328), //EXT_ZXZ
|
||||
Quatd(0.653285, -0.0990435, 0.369641, 0.65328) //EXT_ZYZ
|
||||
};
|
||||
|
||||
TEST_F(QuatTest, EulerAngles)
|
||||
{
|
||||
Vec3d test_angle = {0.523598, 0.78539, 1.04719};
|
||||
for (QuatEnum::EulerAnglesType i = QuatEnum::EulerAnglesType::INT_XYZ; i <= QuatEnum::EulerAnglesType::EXT_ZYZ; i = (QuatEnum::EulerAnglesType)(i + 1))
|
||||
{
|
||||
SCOPED_TRACE(cv::format("EulerAnglesType=%d", i));
|
||||
Quatd q = Quatd::createFromEulerAngles(test_angle, i);
|
||||
EXPECT_EQ(q, qEuler[i]);
|
||||
Vec3d Euler_Angles = q.toEulerAngles(i);
|
||||
EXPECT_NEAR(Euler_Angles[0], test_angle[0], 1e-6);
|
||||
EXPECT_NEAR(Euler_Angles[1], test_angle[1], 1e-6);
|
||||
EXPECT_NEAR(Euler_Angles[2], test_angle[2], 1e-6);
|
||||
}
|
||||
Quatd qEuler0 = {0, 0, 0, 0};
|
||||
EXPECT_ANY_THROW(qEuler0.toEulerAngles(QuatEnum::INT_XYZ));
|
||||
|
||||
Quatd qEulerLock1 = {0.5612665, 0.43042, 0.5607083, 0.4304935};
|
||||
Vec3d test_angle_lock1 = {1.3089878, CV_PI * 0.5, 0};
|
||||
Vec3d Euler_Angles_solute_1 = qEulerLock1.toEulerAngles(QuatEnum::INT_XYZ);
|
||||
EXPECT_NEAR(Euler_Angles_solute_1[0], test_angle_lock1[0], 1e-6);
|
||||
EXPECT_NEAR(Euler_Angles_solute_1[1], test_angle_lock1[1], 1e-6);
|
||||
EXPECT_NEAR(Euler_Angles_solute_1[2], test_angle_lock1[2], 1e-6);
|
||||
|
||||
Quatd qEulerLock2 = {0.7010574, 0.0922963, 0.7010573, -0.0922961};
|
||||
Vec3d test_angle_lock2 = {-0.2618, CV_PI * 0.5, 0};
|
||||
Vec3d Euler_Angles_solute_2 = qEulerLock2.toEulerAngles(QuatEnum::INT_ZYX);
|
||||
EXPECT_NEAR(Euler_Angles_solute_2[0], test_angle_lock2[0], 1e-6);
|
||||
EXPECT_NEAR(Euler_Angles_solute_2[1], test_angle_lock2[1], 1e-6);
|
||||
EXPECT_NEAR(Euler_Angles_solute_2[2], test_angle_lock2[2], 1e-6);
|
||||
|
||||
Vec3d test_angle6 = {CV_PI * 0.25, CV_PI * 0.5, CV_PI * 0.25};
|
||||
Vec3d test_angle7 = {CV_PI * 0.5, CV_PI * 0.5, 0};
|
||||
EXPECT_EQ(Quatd::createFromEulerAngles(test_angle6, QuatEnum::INT_ZXY), Quatd::createFromEulerAngles(test_angle7, QuatEnum::INT_ZXY));
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DualQuatTest: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
double scalar = 2.5;
|
||||
double angle = CV_PI;
|
||||
Vec<double, 3> axis{1, 1, 1};
|
||||
Vec<double, 3> unAxis{0, 0, 0};
|
||||
Vec<double, 3> unitAxis{1.0 / sqrt(3), 1.0 / sqrt(3), 1.0 / sqrt(3)};
|
||||
DualQuatd dq1{1, 2, 3, 4, 5, 6, 7, 8};
|
||||
Vec3d trans{0, 0, 5};
|
||||
double rotation_angle = 2.0 / 3 * CV_PI;
|
||||
DualQuatd dq2 = DualQuatd::createFromAngleAxisTrans(rotation_angle, axis, trans);
|
||||
DualQuatd dqAllOne{1, 1, 1, 1, 1, 1, 1, 1};
|
||||
DualQuatd dqAllZero{0, 0, 0, 0, 0, 0, 0, 0};
|
||||
DualQuatd dqIdentity{1, 0, 0, 0, 0, 0, 0, 0};
|
||||
DualQuatd dqTrans{1, 0, 0, 0, 0, 2, 3, 4};
|
||||
DualQuatd dqOnlyTrans{0, 0, 0, 0, 0, 2, 3, 4};
|
||||
DualQuatd dualNumber1{-3,0,0,0,-31.1,0,0,0};
|
||||
DualQuatd dualNumber2{4,0,0,0,5.1,0,0,0};
|
||||
};
|
||||
|
||||
TEST_F(DualQuatTest, constructor)
|
||||
{
|
||||
EXPECT_EQ(dq1, DualQuatd::createFromQuat(Quatd(1, 2, 3, 4), Quatd(5, 6, 7, 8)));
|
||||
EXPECT_EQ(dq2 * dq2.conjugate(), dqIdentity);
|
||||
EXPECT_NEAR(dq2.getRotation(QUAT_ASSUME_UNIT).norm(), 1, 1e-6);
|
||||
EXPECT_NEAR(dq2.getRealPart().dot(dq2.getDualPart()), 0, 1e-6);
|
||||
EXPECT_MAT_NEAR(dq2.getTranslation(QUAT_ASSUME_UNIT), trans, 1e-6);
|
||||
DualQuatd q_conj = DualQuatd::createFromQuat(dq2.getRealPart().conjugate(), -dq2.getDualPart().conjugate());
|
||||
DualQuatd q{1,0,0,0,0,3,0,0};
|
||||
EXPECT_EQ(dq2 * q * q_conj, DualQuatd(1,0,0,0,0,0,3,5));
|
||||
Matx44d R1 = dq2.toMat();
|
||||
DualQuatd dq3 = DualQuatd::createFromMat(R1);
|
||||
EXPECT_EQ(dq3, dq2);
|
||||
axis = axis / std::sqrt(axis.dot(axis));
|
||||
Vec3d moment = 1.0 / 2 * (trans.cross(axis) + axis.cross(trans.cross(axis)) *
|
||||
std::cos(rotation_angle / 2) / std::sin(rotation_angle / 2));
|
||||
double d = trans.dot(axis);
|
||||
DualQuatd dq4 = DualQuatd::createFromPitch(rotation_angle, d, axis, moment);
|
||||
EXPECT_EQ(dq4, dq3);
|
||||
EXPECT_EQ(dq2, DualQuatd::createFromAffine3(dq2.toAffine3()));
|
||||
EXPECT_EQ(dq1.normalize(), DualQuatd::createFromAffine3(dq1.toAffine3()));
|
||||
}
|
||||
|
||||
TEST_F(DualQuatTest, test_operator)
|
||||
{
|
||||
DualQuatd dq_origin{1, 2, 3, 4, 5, 6, 7, 8};
|
||||
EXPECT_EQ(dq1 - dqAllOne, DualQuatd(0, 1, 2, 3, 4, 5, 6, 7));
|
||||
EXPECT_EQ(-dq1, DualQuatd(-1, -2, -3, -4, -5, -6, -7, -8));
|
||||
EXPECT_EQ(dq1 + dqAllOne, DualQuatd(2, 3, 4, 5, 6, 7, 8, 9));
|
||||
EXPECT_EQ(dq1 / dq1, dqIdentity);
|
||||
DualQuatd dq3{-4, 1, 3, 2, -15.5, 0, -3, 8.5};
|
||||
EXPECT_EQ(dq1 * dq2, dq3);
|
||||
EXPECT_EQ(dq3 / dq2, dq1);
|
||||
DualQuatd dq12{2, 4, 6, 8, 10, 12, 14, 16};
|
||||
EXPECT_EQ(dq1 * 2.0, dq12);
|
||||
EXPECT_EQ(2.0 * dq1, dq12);
|
||||
EXPECT_EQ(dq1 - 1.0, DualQuatd(0, 2, 3, 4, 5, 6, 7, 8));
|
||||
EXPECT_EQ(1.0 - dq1, DualQuatd(0, -2, -3, -4, -5, -6, -7, -8));
|
||||
EXPECT_EQ(dq1 + 1.0, DualQuatd(2, 2, 3, 4, 5, 6, 7, 8));
|
||||
EXPECT_EQ(1.0 + dq1, DualQuatd(2, 2, 3, 4, 5, 6, 7, 8));
|
||||
dq1 += dq2;
|
||||
EXPECT_EQ(dq1, dq_origin + dq2);
|
||||
dq1 -= dq2;
|
||||
EXPECT_EQ(dq1, dq_origin);
|
||||
dq1 *= dq2;
|
||||
EXPECT_EQ(dq1, dq_origin * dq2);
|
||||
dq1 /= dq2;
|
||||
EXPECT_EQ(dq1, dq_origin);
|
||||
}
|
||||
|
||||
TEST_F(DualQuatTest, basic_ops)
|
||||
{
|
||||
EXPECT_EQ(dq1.getRealPart(), Quatd(1, 2, 3, 4));
|
||||
EXPECT_EQ(dq1.getDualPart(), Quatd(5, 6, 7, 8));
|
||||
EXPECT_EQ((dq1 * dq2).conjugate(), conjugate(dq1 * dq2));
|
||||
EXPECT_EQ(dq1.conjugate(), DualQuatd::createFromQuat(dq1.getRealPart().conjugate(), dq1.getDualPart().conjugate()));
|
||||
EXPECT_EQ((dq2 * dq1).conjugate(), dq1.conjugate() * dq2.conjugate());
|
||||
EXPECT_EQ(dq1.conjugate() * dq1, dq1.norm() * dq1.norm());
|
||||
EXPECT_EQ(dq1.conjugate() * dq1, dq1.norm().power(2.0));
|
||||
EXPECT_EQ(dualNumber2.power(2.0), DualQuatd(16, 0, 0, 0, 40.8, 0, 0, 0));
|
||||
EXPECT_EQ(dq1.power(2.0), (2.0 * dq1.log()).exp());
|
||||
EXPECT_EQ(power(dq1, 2.0), (exp(2.0 * log(dq1))));
|
||||
EXPECT_EQ(dq2.power(3.0 / 2, QUAT_ASSUME_UNIT).power(4.0 / 3, QUAT_ASSUME_UNIT), dq2 * dq2);
|
||||
EXPECT_EQ(dq2.power(-0.5).power(2.0), dq2.inv());
|
||||
EXPECT_EQ(power(dq1, dq2), exp(dq2 * log(dq1)));
|
||||
EXPECT_EQ(power(dq2, dq1, QUAT_ASSUME_UNIT), exp(dq1 * log(dq2)));
|
||||
EXPECT_EQ((dq2.norm() * dq1).power(2.0), dq1.power(2.0) * dq2.norm().power(2.0));
|
||||
DualQuatd q1norm = dq1.normalize();
|
||||
EXPECT_EQ(dq2.norm(), dqIdentity);
|
||||
EXPECT_NEAR(q1norm.getRealPart().norm(), 1, 1e-6);
|
||||
EXPECT_NEAR(q1norm.getRealPart().dot(q1norm.getDualPart()), 0, 1e-6);
|
||||
EXPECT_NEAR(dq1.getRotation().norm(), 1, 1e-6);
|
||||
EXPECT_NEAR(dq2.getRotation(QUAT_ASSUME_UNIT).norm(), 1, 1e-6);
|
||||
EXPECT_NEAR(dq2.getRotation(QUAT_ASSUME_UNIT).norm(), 1, 1e-6);
|
||||
EXPECT_MAT_NEAR(Mat(dq2.getTranslation()), Mat(trans), 1e-6);
|
||||
EXPECT_MAT_NEAR(Mat(q1norm.getTranslation(QUAT_ASSUME_UNIT)), Mat(dq1.getTranslation()), 1e-6);
|
||||
EXPECT_EQ(dq2.getTranslation(), dq2.getTranslation(QUAT_ASSUME_UNIT));
|
||||
EXPECT_EQ(dq1.inv() * dq1, dqIdentity);
|
||||
EXPECT_EQ(inv(dq1) * dq1, dqIdentity);
|
||||
EXPECT_EQ(dq2.inv(QUAT_ASSUME_UNIT) * dq2, dqIdentity);
|
||||
EXPECT_EQ(inv(dq2, QUAT_ASSUME_UNIT) * dq2, dqIdentity);
|
||||
EXPECT_EQ(dq2.inv(), dq2.conjugate());
|
||||
EXPECT_EQ(dqIdentity.inv(), dqIdentity);
|
||||
EXPECT_ANY_THROW(dqAllZero.inv());
|
||||
EXPECT_EQ(dqAllZero.exp(), dqIdentity);
|
||||
EXPECT_EQ(exp(dqAllZero), dqIdentity);
|
||||
EXPECT_ANY_THROW(log(dqAllZero));
|
||||
EXPECT_EQ(log(dqIdentity), dqAllZero);
|
||||
EXPECT_EQ(dqIdentity.log(), dqAllZero);
|
||||
EXPECT_EQ(dualNumber1 * dualNumber2, dualNumber2 * dualNumber1);
|
||||
EXPECT_EQ(dualNumber2.exp().log(), dualNumber2);
|
||||
EXPECT_EQ(dq2.log(QUAT_ASSUME_UNIT).exp(), dq2);
|
||||
EXPECT_EQ(exp(log(dq2, QUAT_ASSUME_UNIT)), dq2);
|
||||
EXPECT_EQ(dqIdentity.log(QUAT_ASSUME_UNIT).exp(), dqIdentity);
|
||||
EXPECT_EQ(dq1.log().exp(), dq1);
|
||||
EXPECT_EQ(dqTrans.log().exp(), dqTrans);
|
||||
EXPECT_MAT_NEAR(q1norm.toMat(QUAT_ASSUME_UNIT), dq1.toMat(), 1e-6);
|
||||
Matx44d R1 = dq2.toMat();
|
||||
Mat point = (Mat_<double>(4, 1) << 3, 0, 0, 1);
|
||||
Mat new_point = R1 * point;
|
||||
Mat after = (Mat_<double>(4, 1) << 0, 3, 5 ,1);
|
||||
EXPECT_MAT_NEAR(new_point, after, 1e-6);
|
||||
Vec<double, 8> vec = dq1.toVec();
|
||||
EXPECT_EQ(DualQuatd(vec), dq1);
|
||||
Affine3d afd = q1norm.toAffine3(QUAT_ASSUME_UNIT);
|
||||
EXPECT_MAT_NEAR(Mat(afd.translation()), Mat(q1norm.getTranslation(QUAT_ASSUME_UNIT)), 1e-6);
|
||||
Affine3d dq1_afd = dq1.toAffine3();
|
||||
EXPECT_MAT_NEAR(dq1_afd.matrix, afd.matrix, 1e-6);
|
||||
EXPECT_ANY_THROW(dqAllZero.toAffine3());
|
||||
}
|
||||
|
||||
TEST_F(DualQuatTest, interpolation)
|
||||
{
|
||||
DualQuatd dq = DualQuatd::createFromAngleAxisTrans(8 * CV_PI / 5, Vec3d{0, 0, 1}, Vec3d{0, 0, 10});
|
||||
EXPECT_EQ(DualQuatd::sclerp(dqIdentity, dq, 0.5), DualQuatd::sclerp(-dqIdentity, dq, 0.5, false));
|
||||
EXPECT_EQ(DualQuatd::sclerp(dqIdentity, dq, 0), -dqIdentity);
|
||||
EXPECT_EQ(DualQuatd::sclerp(dqIdentity, dq2, 1), dq2);
|
||||
EXPECT_EQ(DualQuatd::sclerp(dqIdentity, dq2, 0.4, false, QUAT_ASSUME_UNIT), DualQuatd(0.91354546, 0.23482951, 0.23482951, 0.23482951, -0.23482951, -0.47824988, 0.69589767, 0.69589767));
|
||||
EXPECT_EQ(DualQuatd::dqblend(dqIdentity, dq1.normalize(), 0.2, QUAT_ASSUME_UNIT), DualQuatd::dqblend(dqIdentity, -dq1, 0.2));
|
||||
EXPECT_EQ(DualQuatd::dqblend(dqIdentity, dq2, 0.4), DualQuatd(0.91766294, 0.22941573, 0.22941573, 0.22941573, -0.21130397, -0.48298049, 0.66409818, 0.66409818));
|
||||
DualQuatd gdb = DualQuatd::gdqblend(Vec<DualQuatd, 3>{dqIdentity, dq, dq2}, Vec3d{0.4, 0, 0.6}, QUAT_ASSUME_UNIT);
|
||||
EXPECT_EQ(gdb, DualQuatd::dqblend(dqIdentity, dq2, 0.6));
|
||||
EXPECT_ANY_THROW(DualQuatd::gdqblend(Vec<DualQuatd, 1>{dq2}, Vec2d{0.5, 0.5}));
|
||||
Mat gdqb_d(1, 2, CV_64FC(7));
|
||||
gdqb_d.at<Vec<double, 7>>(0, 0) = Vec<double, 7>{1,2,3,4,5,6,7};
|
||||
gdqb_d.at<Vec<double, 7>>(0, 1) = Vec<double, 7>{1,2,3,4,5,6,7};
|
||||
EXPECT_ANY_THROW(DualQuatd::gdqblend(gdqb_d, Vec2d{0.5, 0.5}));
|
||||
Mat gdqb_f(1, 2, CV_32FC(8));
|
||||
gdqb_f.at<Vec<float, 8>>(0, 0) = Vec<float, 8>{1.f,2.f,3.f,4.f,5.f,6.f,7.f,8.f};
|
||||
gdqb_f.at<Vec<float, 8>>(0, 1) = Vec<float, 8>{1.f,2.f,3.f,4.f,5.f,6.f,7.f,8.f};
|
||||
EXPECT_ANY_THROW(DualQuatd::gdqblend(gdqb_f, Vec2d{0.5, 0.5}));
|
||||
EXPECT_ANY_THROW(DualQuatd::gdqblend(Vec<DualQuatd, 3>{dqIdentity, dq, dq2}, Vec3f{0.4f, 0.f, 0.6f}, QUAT_ASSUME_UNIT));
|
||||
EXPECT_EQ(gdb, DualQuatd::gdqblend(Vec<DualQuatd, 3>{dqIdentity, dq * dualNumber1, -dq2}, Vec3d{0.4, 0, 0.6}));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace
|
423
3rdparty/opencv-4.5.4/modules/core/test/test_rand.cpp
vendored
Normal file
423
3rdparty/opencv-4.5.4/modules/core/test/test_rand.cpp
vendored
Normal file
@ -0,0 +1,423 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
class Core_RandTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_RandTest();
|
||||
protected:
|
||||
void run(int);
|
||||
bool check_pdf(const Mat& hist, double scale, int dist_type,
|
||||
double& refval, double& realval);
|
||||
};
|
||||
|
||||
|
||||
Core_RandTest::Core_RandTest()
|
||||
{
|
||||
}
|
||||
|
||||
static double chi2_p95(int n)
|
||||
{
|
||||
static float chi2_tab95[] = {
|
||||
3.841f, 5.991f, 7.815f, 9.488f, 11.07f, 12.59f, 14.07f, 15.51f,
|
||||
16.92f, 18.31f, 19.68f, 21.03f, 21.03f, 22.36f, 23.69f, 25.00f,
|
||||
26.30f, 27.59f, 28.87f, 30.14f, 31.41f, 32.67f, 33.92f, 35.17f,
|
||||
36.42f, 37.65f, 38.89f, 40.11f, 41.34f, 42.56f, 43.77f };
|
||||
static const double xp = 1.64;
|
||||
CV_Assert(n >= 1);
|
||||
|
||||
if( n <= 30 )
|
||||
return chi2_tab95[n-1];
|
||||
return n + sqrt((double)2*n)*xp + 0.6666666666666*(xp*xp - 1);
|
||||
}
|
||||
|
||||
bool Core_RandTest::check_pdf(const Mat& hist, double scale,
|
||||
int dist_type, double& refval, double& realval)
|
||||
{
|
||||
Mat hist0(hist.size(), CV_32F);
|
||||
const int* H = hist.ptr<int>();
|
||||
float* H0 = hist0.ptr<float>();
|
||||
int i, hsz = hist.cols;
|
||||
|
||||
double sum = 0;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
sum += H[i];
|
||||
CV_Assert( fabs(1./sum - scale) < FLT_EPSILON );
|
||||
|
||||
if( dist_type == CV_RAND_UNI )
|
||||
{
|
||||
float scale0 = (float)(1./hsz);
|
||||
for( i = 0; i < hsz; i++ )
|
||||
H0[i] = scale0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double sum2 = 0, r = (hsz-1.)/2;
|
||||
double alpha = 2*sqrt(2.)/r, beta = -alpha*r;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
{
|
||||
double x = i*alpha + beta;
|
||||
H0[i] = (float)exp(-x*x);
|
||||
sum2 += H0[i];
|
||||
}
|
||||
sum2 = 1./sum2;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
H0[i] = (float)(H0[i]*sum2);
|
||||
}
|
||||
|
||||
double chi2 = 0;
|
||||
for( i = 0; i < hsz; i++ )
|
||||
{
|
||||
double a = H0[i];
|
||||
double b = H[i]*scale;
|
||||
if( a > DBL_EPSILON )
|
||||
chi2 += (a - b)*(a - b)/(a + b);
|
||||
}
|
||||
realval = chi2;
|
||||
|
||||
double chi2_pval = chi2_p95(hsz - 1 - (dist_type == CV_RAND_NORMAL ? 2 : 0));
|
||||
refval = chi2_pval*0.01;
|
||||
return realval <= refval;
|
||||
}
|
||||
|
||||
void Core_RandTest::run( int )
|
||||
{
|
||||
static int _ranges[][2] =
|
||||
{{ 0, 256 }, { -128, 128 }, { 0, 65536 }, { -32768, 32768 },
|
||||
{ -1000000, 1000000 }, { -1000, 1000 }, { -1000, 1000 }};
|
||||
|
||||
const int MAX_SDIM = 10;
|
||||
const int N = 2000000;
|
||||
const int maxSlice = 1000;
|
||||
const int MAX_HIST_SIZE = 1000;
|
||||
int progress = 0;
|
||||
|
||||
RNG& rng = ts->get_rng();
|
||||
RNG tested_rng = theRNG();
|
||||
test_case_count = 200;
|
||||
|
||||
for( int idx = 0; idx < test_case_count; idx++ )
|
||||
{
|
||||
progress = update_progress( progress, idx, test_case_count, 0 );
|
||||
ts->update_context( this, idx, false );
|
||||
|
||||
int depth = cvtest::randInt(rng) % (CV_64F+1);
|
||||
int c, cn = (cvtest::randInt(rng) % 4) + 1;
|
||||
int type = CV_MAKETYPE(depth, cn);
|
||||
int dist_type = cvtest::randInt(rng) % (CV_RAND_NORMAL+1);
|
||||
int i, k, SZ = N/cn;
|
||||
Scalar A, B;
|
||||
|
||||
double eps = 1.e-4;
|
||||
if (depth == CV_64F)
|
||||
eps = 1.e-7;
|
||||
|
||||
bool do_sphere_test = dist_type == CV_RAND_UNI;
|
||||
Mat arr[2], hist[4];
|
||||
int W[] = {0,0,0,0};
|
||||
|
||||
arr[0].create(1, SZ, type);
|
||||
arr[1].create(1, SZ, type);
|
||||
bool fast_algo = dist_type == CV_RAND_UNI && depth < CV_32F;
|
||||
|
||||
for( c = 0; c < cn; c++ )
|
||||
{
|
||||
int a, b, hsz;
|
||||
if( dist_type == CV_RAND_UNI )
|
||||
{
|
||||
a = (int)(cvtest::randInt(rng) % (_ranges[depth][1] -
|
||||
_ranges[depth][0])) + _ranges[depth][0];
|
||||
do
|
||||
{
|
||||
b = (int)(cvtest::randInt(rng) % (_ranges[depth][1] -
|
||||
_ranges[depth][0])) + _ranges[depth][0];
|
||||
}
|
||||
while( abs(a-b) <= 1 );
|
||||
if( a > b )
|
||||
std::swap(a, b);
|
||||
|
||||
unsigned r = (unsigned)(b - a);
|
||||
fast_algo = fast_algo && r <= 256 && (r & (r-1)) == 0;
|
||||
hsz = min((unsigned)(b - a), (unsigned)MAX_HIST_SIZE);
|
||||
do_sphere_test = do_sphere_test && b - a >= 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
int vrange = _ranges[depth][1] - _ranges[depth][0];
|
||||
int meanrange = vrange/16;
|
||||
int mindiv = MAX(vrange/20, 5);
|
||||
int maxdiv = MIN(vrange/8, 10000);
|
||||
|
||||
a = cvtest::randInt(rng) % meanrange - meanrange/2 +
|
||||
(_ranges[depth][0] + _ranges[depth][1])/2;
|
||||
b = cvtest::randInt(rng) % (maxdiv - mindiv) + mindiv;
|
||||
hsz = min((unsigned)b*9, (unsigned)MAX_HIST_SIZE);
|
||||
}
|
||||
A[c] = a;
|
||||
B[c] = b;
|
||||
hist[c].create(1, hsz, CV_32S);
|
||||
}
|
||||
|
||||
cv::RNG saved_rng = tested_rng;
|
||||
int maxk = fast_algo ? 0 : 1;
|
||||
for( k = 0; k <= maxk; k++ )
|
||||
{
|
||||
tested_rng = saved_rng;
|
||||
int sz = 0, dsz = 0, slice;
|
||||
for( slice = 0; slice < maxSlice && sz < SZ; slice++, sz += dsz )
|
||||
{
|
||||
dsz = slice+1 < maxSlice ? (int)(cvtest::randInt(rng) % (SZ - sz) + 1) : SZ - sz;
|
||||
Mat aslice = arr[k].colRange(sz, sz + dsz);
|
||||
tested_rng.fill(aslice, dist_type, A, B);
|
||||
}
|
||||
}
|
||||
|
||||
if( maxk >= 1 && cvtest::norm(arr[0], arr[1], NORM_INF) > eps)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "RNG output depends on the array lengths (some generated numbers get lost?)" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
|
||||
for( c = 0; c < cn; c++ )
|
||||
{
|
||||
const uchar* data = arr[0].ptr();
|
||||
int* H = hist[c].ptr<int>();
|
||||
int HSZ = hist[c].cols;
|
||||
double minVal = dist_type == CV_RAND_UNI ? A[c] : A[c] - B[c]*4;
|
||||
double maxVal = dist_type == CV_RAND_UNI ? B[c] : A[c] + B[c]*4;
|
||||
double scale = HSZ/(maxVal - minVal);
|
||||
double delta = -minVal*scale;
|
||||
|
||||
hist[c] = Scalar::all(0);
|
||||
|
||||
for( i = c; i < SZ*cn; i += cn )
|
||||
{
|
||||
double val = depth == CV_8U ? ((const uchar*)data)[i] :
|
||||
depth == CV_8S ? ((const schar*)data)[i] :
|
||||
depth == CV_16U ? ((const ushort*)data)[i] :
|
||||
depth == CV_16S ? ((const short*)data)[i] :
|
||||
depth == CV_32S ? ((const int*)data)[i] :
|
||||
depth == CV_32F ? ((const float*)data)[i] :
|
||||
((const double*)data)[i];
|
||||
int ival = cvFloor(val*scale + delta);
|
||||
if( (unsigned)ival < (unsigned)HSZ )
|
||||
{
|
||||
H[ival]++;
|
||||
W[c]++;
|
||||
}
|
||||
else if( dist_type == CV_RAND_UNI )
|
||||
{
|
||||
if( (minVal <= val && val < maxVal) || (depth >= CV_32F && val == maxVal) )
|
||||
{
|
||||
H[ival < 0 ? 0 : HSZ-1]++;
|
||||
W[c]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar('^');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( dist_type == CV_RAND_UNI && W[c] != SZ )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Uniform RNG gave values out of the range [%g,%g) on channel %d/%d\n",
|
||||
A[c], B[c], c, cn);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
if( dist_type == CV_RAND_NORMAL && W[c] < SZ*.90)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Normal RNG gave too many values out of the range (%g+4*%g,%g+4*%g) on channel %d/%d\n",
|
||||
A[c], B[c], A[c], B[c], c, cn);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
double refval = 0, realval = 0;
|
||||
|
||||
if( !check_pdf(hist[c], 1./W[c], dist_type, refval, realval) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "RNG failed Chi-square test "
|
||||
"(got %g vs probable maximum %g) on channel %d/%d\n",
|
||||
realval, refval, c, cn);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Monte-Carlo test. Compute volume of SDIM-dimensional sphere
|
||||
// inscribed in [-1,1]^SDIM cube.
|
||||
if( do_sphere_test )
|
||||
{
|
||||
int SDIM = cvtest::randInt(rng) % (MAX_SDIM-1) + 2;
|
||||
int N0 = (SZ*cn/SDIM), n = 0;
|
||||
double r2 = 0;
|
||||
const uchar* data = arr[0].ptr();
|
||||
double scale[4], delta[4];
|
||||
for( c = 0; c < cn; c++ )
|
||||
{
|
||||
scale[c] = 2./(B[c] - A[c]);
|
||||
delta[c] = -A[c]*scale[c] - 1;
|
||||
}
|
||||
|
||||
for( i = k = c = 0; i <= SZ*cn - SDIM; i++, k++, c++ )
|
||||
{
|
||||
double val = depth == CV_8U ? ((const uchar*)data)[i] :
|
||||
depth == CV_8S ? ((const schar*)data)[i] :
|
||||
depth == CV_16U ? ((const ushort*)data)[i] :
|
||||
depth == CV_16S ? ((const short*)data)[i] :
|
||||
depth == CV_32S ? ((const int*)data)[i] :
|
||||
depth == CV_32F ? ((const float*)data)[i] : ((const double*)data)[i];
|
||||
c &= c < cn ? -1 : 0;
|
||||
val = val*scale[c] + delta[c];
|
||||
r2 += val*val;
|
||||
if( k == SDIM-1 )
|
||||
{
|
||||
n += r2 <= 1;
|
||||
r2 = 0;
|
||||
k = -1;
|
||||
}
|
||||
}
|
||||
|
||||
double V = ((double)n/N0)*(1 << SDIM);
|
||||
|
||||
// the theoretically computed volume
|
||||
int sdim = SDIM % 2;
|
||||
double V0 = sdim + 1;
|
||||
for( sdim += 2; sdim <= SDIM; sdim += 2 )
|
||||
V0 *= 2*CV_PI/sdim;
|
||||
|
||||
if( fabs(V - V0) > 0.3*fabs(V0) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "RNG failed %d-dim sphere volume test (got %g instead of %g)\n",
|
||||
SDIM, V, V0);
|
||||
ts->printf( cvtest::TS::LOG, "depth = %d, N0 = %d\n", depth, N0);
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Core_Rand, quality) { Core_RandTest test; test.safe_run(); }
|
||||
|
||||
|
||||
class Core_RandRangeTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_RandRangeTest() {}
|
||||
~Core_RandRangeTest() {}
|
||||
protected:
|
||||
void run(int)
|
||||
{
|
||||
Mat a(Size(1280, 720), CV_8U, Scalar(20));
|
||||
Mat af(Size(1280, 720), CV_32F, Scalar(20));
|
||||
theRNG().fill(a, RNG::UNIFORM, -DBL_MAX, DBL_MAX);
|
||||
theRNG().fill(af, RNG::UNIFORM, -DBL_MAX, DBL_MAX);
|
||||
int n0 = 0, n255 = 0, nx = 0;
|
||||
int nfmin = 0, nfmax = 0, nfx = 0;
|
||||
|
||||
for( int i = 0; i < a.rows; i++ )
|
||||
for( int j = 0; j < a.cols; j++ )
|
||||
{
|
||||
int v = a.at<uchar>(i,j);
|
||||
double vf = af.at<float>(i,j);
|
||||
if( v == 0 ) n0++;
|
||||
else if( v == 255 ) n255++;
|
||||
else nx++;
|
||||
if( vf < FLT_MAX*-0.999f ) nfmin++;
|
||||
else if( vf > FLT_MAX*0.999f ) nfmax++;
|
||||
else nfx++;
|
||||
}
|
||||
CV_Assert( n0 > nx*2 && n255 > nx*2 );
|
||||
CV_Assert( nfmin > nfx*2 && nfmax > nfx*2 );
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_Rand, range) { Core_RandRangeTest test; test.safe_run(); }
|
||||
|
||||
|
||||
TEST(Core_RNG_MT19937, regression)
|
||||
{
|
||||
cv::RNG_MT19937 rng;
|
||||
int actual[61] = {0, };
|
||||
const size_t length = (sizeof(actual) / sizeof(actual[0]));
|
||||
for (int i = 0; i < 10000; ++i )
|
||||
{
|
||||
actual[(unsigned)(rng.next() ^ i) % length]++;
|
||||
}
|
||||
|
||||
int expected[length] = {
|
||||
177, 158, 180, 177, 160, 179, 143, 162,
|
||||
177, 144, 170, 174, 165, 168, 168, 156,
|
||||
177, 157, 159, 169, 177, 182, 166, 154,
|
||||
144, 180, 168, 152, 170, 187, 160, 145,
|
||||
139, 164, 157, 179, 148, 183, 159, 160,
|
||||
196, 184, 149, 142, 162, 148, 163, 152,
|
||||
168, 173, 160, 181, 172, 181, 155, 153,
|
||||
158, 171, 138, 150, 150 };
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
ASSERT_EQ(expected[i], actual[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(Core_Rand, Regression_Stack_Corruption)
|
||||
{
|
||||
int bufsz = 128; //enough for 14 doubles
|
||||
AutoBuffer<uchar> buffer(bufsz);
|
||||
size_t offset = 0;
|
||||
cv::Mat_<cv::Point2d> x(2, 3, (cv::Point2d*)(buffer.data()+offset));
|
||||
offset += x.total()*x.elemSize();
|
||||
double& param1 = *(double*)(buffer.data()+offset);
|
||||
offset += sizeof(double);
|
||||
double& param2 = *(double*)(buffer.data()+offset);
|
||||
param1 = -9; param2 = 2;
|
||||
|
||||
cv::theRNG().fill(x, cv::RNG::NORMAL, param1, param2);
|
||||
|
||||
ASSERT_EQ(param1, -9);
|
||||
ASSERT_EQ(param2, 2);
|
||||
}
|
||||
|
||||
|
||||
class RandRowFillParallelLoopBody : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
RandRowFillParallelLoopBody(Mat& dst) : dst_(dst) {}
|
||||
~RandRowFillParallelLoopBody() {}
|
||||
void operator()(const cv::Range& r) const
|
||||
{
|
||||
cv::RNG rng = cv::theRNG(); // copy state
|
||||
for (int y = r.start; y < r.end; y++)
|
||||
{
|
||||
cv::theRNG() = cv::RNG(rng.state + y); // seed is based on processed row
|
||||
cv::randu(dst_.row(y), Scalar(-100), Scalar(100));
|
||||
}
|
||||
// theRNG() state is changed here (but state collision has low probability, so we don't check this)
|
||||
}
|
||||
protected:
|
||||
Mat& dst_;
|
||||
};
|
||||
|
||||
TEST(Core_Rand, parallel_for_stable_results)
|
||||
{
|
||||
cv::RNG rng = cv::theRNG(); // save rng state
|
||||
Mat dst1(1000, 100, CV_8SC1);
|
||||
parallel_for_(cv::Range(0, dst1.rows), RandRowFillParallelLoopBody(dst1));
|
||||
|
||||
cv::theRNG() = rng; // restore rng state
|
||||
Mat dst2(1000, 100, CV_8SC1);
|
||||
parallel_for_(cv::Range(0, dst2.rows), RandRowFillParallelLoopBody(dst2));
|
||||
|
||||
ASSERT_EQ(0, countNonZero(dst1 != dst2));
|
||||
}
|
||||
|
||||
}} // namespace
|
108
3rdparty/opencv-4.5.4/modules/core/test/test_rotatedrect.cpp
vendored
Normal file
108
3rdparty/opencv-4.5.4/modules/core/test/test_rotatedrect.cpp
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
class Core_RotatedRectConstructorTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
Core_RotatedRectConstructorTest();
|
||||
protected:
|
||||
int prepare_test_case( int );
|
||||
void run_func();
|
||||
int validate_test_results( int );
|
||||
float MAX_COORD_VAL;
|
||||
Point2f a, b, c;
|
||||
RotatedRect rec;
|
||||
};
|
||||
|
||||
Core_RotatedRectConstructorTest::Core_RotatedRectConstructorTest()
|
||||
{
|
||||
test_case_count = 100;
|
||||
MAX_COORD_VAL = 1000.0f;
|
||||
}
|
||||
|
||||
int Core_RotatedRectConstructorTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
cvtest::BaseTest::prepare_test_case( test_case_idx );
|
||||
RNG& rng = ts->get_rng();
|
||||
a = Point2f( rng.uniform(-MAX_COORD_VAL, MAX_COORD_VAL), rng.uniform(-MAX_COORD_VAL, MAX_COORD_VAL) );
|
||||
do
|
||||
{
|
||||
b = Point2f( rng.uniform(-MAX_COORD_VAL, MAX_COORD_VAL), rng.uniform(-MAX_COORD_VAL, MAX_COORD_VAL) );
|
||||
}
|
||||
while( cv::norm(a - b) <= FLT_EPSILON );
|
||||
Vec2f along(a - b);
|
||||
Vec2f perp = Vec2f(-along[1], along[0]);
|
||||
double d = (double) rng.uniform(1.0f, 5.0f);
|
||||
if( cvtest::randInt(rng) % 2 == 0 ) d = -d;
|
||||
c = Point2f( (float) ((double) b.x + d * perp[0]), (float) ((double) b.y + d * perp[1]) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Core_RotatedRectConstructorTest::run_func()
|
||||
{
|
||||
rec = RotatedRect(a, b, c);
|
||||
}
|
||||
|
||||
int Core_RotatedRectConstructorTest::validate_test_results( int )
|
||||
{
|
||||
Point2f vertices[4];
|
||||
rec.points(vertices);
|
||||
int count_match = 0;
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
if( cv::norm(vertices[i] - a) <= 0.001 ) count_match++;
|
||||
else if( cv::norm(vertices[i] - b) <= 0.001 ) count_match++;
|
||||
else if( cv::norm(vertices[i] - c) <= 0.001 ) count_match++;
|
||||
}
|
||||
if( count_match == 3 )
|
||||
return cvtest::TS::OK;
|
||||
ts->printf( cvtest::TS::LOG, "RotatedRect end points don't match those supplied in constructor");
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
TEST(Core_RotatedRect, three_point_constructor) { Core_RotatedRectConstructorTest test; test.safe_run(); }
|
||||
|
||||
}} // namespace
|
1455
3rdparty/opencv-4.5.4/modules/core/test/test_umat.cpp
vendored
Normal file
1455
3rdparty/opencv-4.5.4/modules/core/test/test_umat.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
505
3rdparty/opencv-4.5.4/modules/core/test/test_utils.cpp
vendored
Normal file
505
3rdparty/opencv-4.5.4/modules/core/test/test_utils.cpp
vendored
Normal file
@ -0,0 +1,505 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/core/utils/logger.defines.hpp"
|
||||
#undef CV_LOG_STRIP_LEVEL
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
#include "opencv2/core/utils/buffer_area.private.hpp"
|
||||
|
||||
#include "opencv2/core/utils/filesystem.private.hpp"
|
||||
|
||||
#ifndef OPENCV_DISABLE_THREAD_SUPPORT
|
||||
#include "test_utils_tls.impl.hpp"
|
||||
#endif
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
static const char * const keys =
|
||||
"{ h help | | print help }"
|
||||
"{ i info | false | print info }"
|
||||
"{ t true | true | true value }"
|
||||
"{ n unused | | dummy }"
|
||||
;
|
||||
|
||||
TEST(CommandLineParser, testFailure)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-q"};
|
||||
const int argc = 2;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_ANY_THROW(parser.has("q"));
|
||||
EXPECT_ANY_THROW(parser.get<bool>("q"));
|
||||
EXPECT_ANY_THROW(parser.get<bool>(0));
|
||||
|
||||
parser.get<bool>("h");
|
||||
EXPECT_FALSE(parser.check());
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testHas_noValues)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h", "--info"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_TRUE(parser.has("help"));
|
||||
EXPECT_TRUE(parser.has("h"));
|
||||
EXPECT_TRUE(parser.get<bool>("help"));
|
||||
EXPECT_TRUE(parser.get<bool>("h"));
|
||||
EXPECT_TRUE(parser.has("info"));
|
||||
EXPECT_TRUE(parser.has("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("info"));
|
||||
EXPECT_TRUE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true"));
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
EXPECT_FALSE(parser.has("n"));
|
||||
EXPECT_FALSE(parser.has("unused"));
|
||||
}
|
||||
TEST(CommandLineParser, testHas_TrueValues)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h=TRUE", "--info=true"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_TRUE(parser.has("help"));
|
||||
EXPECT_TRUE(parser.has("h"));
|
||||
EXPECT_TRUE(parser.get<bool>("help"));
|
||||
EXPECT_TRUE(parser.get<bool>("h"));
|
||||
EXPECT_TRUE(parser.has("info"));
|
||||
EXPECT_TRUE(parser.has("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("info"));
|
||||
EXPECT_TRUE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true"));
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
EXPECT_FALSE(parser.has("n"));
|
||||
EXPECT_FALSE(parser.has("unused"));
|
||||
}
|
||||
TEST(CommandLineParser, testHas_TrueValues1)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h=1", "--info=1"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_TRUE(parser.has("help"));
|
||||
EXPECT_TRUE(parser.has("h"));
|
||||
EXPECT_TRUE(parser.get<bool>("help"));
|
||||
EXPECT_TRUE(parser.get<bool>("h"));
|
||||
EXPECT_TRUE(parser.has("info"));
|
||||
EXPECT_TRUE(parser.has("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("info"));
|
||||
EXPECT_TRUE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true"));
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
EXPECT_FALSE(parser.has("n"));
|
||||
EXPECT_FALSE(parser.has("unused"));
|
||||
}
|
||||
TEST(CommandLineParser, testHas_FalseValues0)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h=0", "--info=0"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_TRUE(parser.has("help"));
|
||||
EXPECT_TRUE(parser.has("h"));
|
||||
EXPECT_FALSE(parser.get<bool>("help"));
|
||||
EXPECT_FALSE(parser.get<bool>("h"));
|
||||
EXPECT_TRUE(parser.has("info"));
|
||||
EXPECT_TRUE(parser.has("i"));
|
||||
EXPECT_FALSE(parser.get<bool>("info"));
|
||||
EXPECT_FALSE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true"));
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
EXPECT_FALSE(parser.has("n"));
|
||||
EXPECT_FALSE(parser.has("unused"));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testBoolOption_noArgs)
|
||||
{
|
||||
const char* argv[] = {"<bin>"};
|
||||
const int argc = 1;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_FALSE(parser.get<bool>("help"));
|
||||
EXPECT_FALSE(parser.get<bool>("h"));
|
||||
EXPECT_FALSE(parser.get<bool>("info"));
|
||||
EXPECT_FALSE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true")); // default is true
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testBoolOption_noValues)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h", "--info"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_TRUE(parser.get<bool>("help"));
|
||||
EXPECT_TRUE(parser.get<bool>("h"));
|
||||
EXPECT_TRUE(parser.get<bool>("info"));
|
||||
EXPECT_TRUE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true"));
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testBoolOption_TrueValues)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h=TrUe", "-t=1", "--info=true", "-n=truE"};
|
||||
const int argc = 5;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_TRUE(parser.get<bool>("help"));
|
||||
EXPECT_TRUE(parser.get<bool>("h"));
|
||||
EXPECT_TRUE(parser.get<bool>("info"));
|
||||
EXPECT_TRUE(parser.get<bool>("i"));
|
||||
EXPECT_TRUE(parser.get<bool>("true"));
|
||||
EXPECT_TRUE(parser.get<bool>("t"));
|
||||
EXPECT_TRUE(parser.get<bool>("unused"));
|
||||
EXPECT_TRUE(parser.get<bool>("n"));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testBoolOption_FalseValues)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "--help=FALSE", "-t=FaLsE", "-i=false", "-n=0"};
|
||||
const int argc = 5;
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
EXPECT_FALSE(parser.get<bool>("help"));
|
||||
EXPECT_FALSE(parser.get<bool>("h"));
|
||||
EXPECT_FALSE(parser.get<bool>("info"));
|
||||
EXPECT_FALSE(parser.get<bool>("i"));
|
||||
EXPECT_FALSE(parser.get<bool>("true"));
|
||||
EXPECT_FALSE(parser.get<bool>("t"));
|
||||
EXPECT_FALSE(parser.get<bool>("unused"));
|
||||
EXPECT_FALSE(parser.get<bool>("n"));
|
||||
}
|
||||
|
||||
|
||||
static const char * const keys2 =
|
||||
"{ h help | | print help }"
|
||||
"{ @arg1 | default1 | param1 }"
|
||||
"{ @arg2 | | param2 }"
|
||||
"{ n unused | | dummy }"
|
||||
;
|
||||
|
||||
TEST(CommandLineParser, testPositional_noArgs)
|
||||
{
|
||||
const char* argv[] = {"<bin>"};
|
||||
const int argc = 1;
|
||||
cv::CommandLineParser parser(argc, argv, keys2);
|
||||
EXPECT_TRUE(parser.has("@arg1"));
|
||||
EXPECT_FALSE(parser.has("@arg2"));
|
||||
EXPECT_EQ("default1", parser.get<String>("@arg1"));
|
||||
EXPECT_EQ("default1", parser.get<String>(0));
|
||||
|
||||
EXPECT_EQ("", parser.get<String>("@arg2"));
|
||||
EXPECT_EQ("", parser.get<String>(1));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testPositional_default)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "test1", "test2"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys2);
|
||||
EXPECT_TRUE(parser.has("@arg1"));
|
||||
EXPECT_TRUE(parser.has("@arg2"));
|
||||
EXPECT_EQ("test1", parser.get<String>("@arg1"));
|
||||
EXPECT_EQ("test2", parser.get<String>("@arg2"));
|
||||
EXPECT_EQ("test1", parser.get<String>(0));
|
||||
EXPECT_EQ("test2", parser.get<String>(1));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testPositional_withFlagsBefore)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "-h", "test1", "test2"};
|
||||
const int argc = 4;
|
||||
cv::CommandLineParser parser(argc, argv, keys2);
|
||||
EXPECT_TRUE(parser.has("@arg1"));
|
||||
EXPECT_TRUE(parser.has("@arg2"));
|
||||
EXPECT_EQ("test1", parser.get<String>("@arg1"));
|
||||
EXPECT_EQ("test2", parser.get<String>("@arg2"));
|
||||
EXPECT_EQ("test1", parser.get<String>(0));
|
||||
EXPECT_EQ("test2", parser.get<String>(1));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testPositional_withFlagsAfter)
|
||||
{
|
||||
const char* argv[] = {"<bin>", "test1", "test2", "-h"};
|
||||
const int argc = 4;
|
||||
cv::CommandLineParser parser(argc, argv, keys2);
|
||||
EXPECT_TRUE(parser.has("@arg1"));
|
||||
EXPECT_TRUE(parser.has("@arg2"));
|
||||
EXPECT_EQ("test1", parser.get<String>("@arg1"));
|
||||
EXPECT_EQ("test2", parser.get<String>("@arg2"));
|
||||
EXPECT_EQ("test1", parser.get<String>(0));
|
||||
EXPECT_EQ("test2", parser.get<String>(1));
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testEmptyStringValue)
|
||||
{
|
||||
static const char * const keys3 =
|
||||
"{ @pos0 | | empty default value }"
|
||||
"{ @pos1 | <none> | forbid empty default value }";
|
||||
|
||||
const char* argv[] = {"<bin>"};
|
||||
const int argc = 1;
|
||||
cv::CommandLineParser parser(argc, argv, keys3);
|
||||
// EXPECT_TRUE(parser.has("@pos0"));
|
||||
EXPECT_EQ("", parser.get<String>("@pos0"));
|
||||
EXPECT_TRUE(parser.check());
|
||||
|
||||
EXPECT_FALSE(parser.has("@pos1"));
|
||||
parser.get<String>(1);
|
||||
EXPECT_FALSE(parser.check());
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, positional_regression_5074_equal_sign)
|
||||
{
|
||||
static const char * const keys3 =
|
||||
"{ @eq0 | | }"
|
||||
"{ eq1 | | }";
|
||||
|
||||
const char* argv[] = {"<bin>", "1=0", "--eq1=1=0"};
|
||||
const int argc = 3;
|
||||
cv::CommandLineParser parser(argc, argv, keys3);
|
||||
EXPECT_EQ("1=0", parser.get<String>("@eq0"));
|
||||
EXPECT_EQ("1=0", parser.get<String>(0));
|
||||
EXPECT_EQ("1=0", parser.get<String>("eq1"));
|
||||
EXPECT_TRUE(parser.check());
|
||||
}
|
||||
|
||||
|
||||
TEST(AutoBuffer, allocate_test)
|
||||
{
|
||||
AutoBuffer<int, 5> abuf(2);
|
||||
EXPECT_EQ(2u, abuf.size());
|
||||
|
||||
abuf.allocate(4);
|
||||
EXPECT_EQ(4u, abuf.size());
|
||||
|
||||
abuf.allocate(6);
|
||||
EXPECT_EQ(6u, abuf.size());
|
||||
}
|
||||
|
||||
TEST(CommandLineParser, testScalar)
|
||||
{
|
||||
static const char * const keys3 =
|
||||
"{ s0 | 3 4 5 | default scalar }"
|
||||
"{ s1 | | single value scalar }"
|
||||
"{ s2 | | two values scalar (default with zeros) }"
|
||||
"{ s3 | | three values scalar }"
|
||||
"{ s4 | | four values scalar }"
|
||||
"{ s5 | | five values scalar }";
|
||||
|
||||
const char* argv[] = {"<bin>", "--s1=1.1", "--s3=1.1 2.2 3",
|
||||
"--s4=-4.2 1 0 3", "--s5=5 -4 3 2 1"};
|
||||
const int argc = 5;
|
||||
CommandLineParser parser(argc, argv, keys3);
|
||||
EXPECT_EQ(parser.get<Scalar>("s0"), Scalar(3, 4, 5));
|
||||
EXPECT_EQ(parser.get<Scalar>("s1"), Scalar(1.1));
|
||||
EXPECT_EQ(parser.get<Scalar>("s2"), Scalar(0));
|
||||
EXPECT_EQ(parser.get<Scalar>("s3"), Scalar(1.1, 2.2, 3));
|
||||
EXPECT_EQ(parser.get<Scalar>("s4"), Scalar(-4.2, 1, 0, 3));
|
||||
EXPECT_EQ(parser.get<Scalar>("s5"), Scalar(5, -4, 3, 2));
|
||||
}
|
||||
|
||||
|
||||
TEST(Logger, DISABLED_message)
|
||||
{
|
||||
int id = 42;
|
||||
CV_LOG_VERBOSE(NULL, 0, "Verbose message: " << id);
|
||||
CV_LOG_VERBOSE(NULL, 1, "Verbose message: " << id);
|
||||
CV_LOG_DEBUG(NULL, "Debug message: " << id);
|
||||
CV_LOG_INFO(NULL, "Info message: " << id);
|
||||
CV_LOG_WARNING(NULL, "Warning message: " << id);
|
||||
CV_LOG_ERROR(NULL, "Error message: " << id);
|
||||
CV_LOG_FATAL(NULL, "Fatal message: " << id);
|
||||
}
|
||||
|
||||
static int testLoggerMessageOnce(int id)
|
||||
{
|
||||
CV_LOG_ONCE_VERBOSE(NULL, 0, "Verbose message: " << id++);
|
||||
CV_LOG_ONCE_VERBOSE(NULL, 1, "Verbose message: " << id++);
|
||||
CV_LOG_ONCE_DEBUG(NULL, "Debug message: " << id++);
|
||||
CV_LOG_ONCE_INFO(NULL, "Info message: " << id++);
|
||||
CV_LOG_ONCE_WARNING(NULL, "Warning message: " << id++);
|
||||
CV_LOG_ONCE_ERROR(NULL, "Error message: " << id++);
|
||||
// doesn't make sense: CV_LOG_ONCE_FATAL
|
||||
return id;
|
||||
}
|
||||
TEST(Logger, DISABLED_message_once)
|
||||
{
|
||||
int check_id_first = testLoggerMessageOnce(42);
|
||||
EXPECT_GT(check_id_first, 42);
|
||||
int check_id_second = testLoggerMessageOnce(0);
|
||||
EXPECT_EQ(0, check_id_second);
|
||||
}
|
||||
|
||||
TEST(Logger, DISABLED_message_if)
|
||||
{
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
CV_LOG_IF_VERBOSE(NULL, 0, i == 0 || i == 42, "Verbose message: " << i);
|
||||
CV_LOG_IF_VERBOSE(NULL, 1, i == 0 || i == 42, "Verbose message: " << i);
|
||||
CV_LOG_IF_DEBUG(NULL, i == 0 || i == 42, "Debug message: " << i);
|
||||
CV_LOG_IF_INFO(NULL, i == 0 || i == 42, "Info message: " << i);
|
||||
CV_LOG_IF_WARNING(NULL, i == 0 || i == 42, "Warning message: " << i);
|
||||
CV_LOG_IF_ERROR(NULL, i == 0 || i == 42, "Error message: " << i);
|
||||
CV_LOG_IF_FATAL(NULL, i == 0 || i == 42, "Fatal message: " << i);
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
TEST(Samples, findFile)
|
||||
{
|
||||
cv::utils::logging::LogLevel prev = cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_VERBOSE);
|
||||
cv::String path;
|
||||
ASSERT_NO_THROW(path = samples::findFile("lena.jpg", false));
|
||||
EXPECT_NE(std::string(), path.c_str());
|
||||
cv::utils::logging::setLogLevel(prev);
|
||||
}
|
||||
|
||||
TEST(Samples, findFile_missing)
|
||||
{
|
||||
cv::utils::logging::LogLevel prev = cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_VERBOSE);
|
||||
cv::String path;
|
||||
ASSERT_ANY_THROW(path = samples::findFile("non-existed.file", true));
|
||||
cv::utils::logging::setLogLevel(prev);
|
||||
}
|
||||
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
|
||||
template <typename T>
|
||||
inline bool buffers_overlap(T * first, size_t first_num, T * second, size_t second_num)
|
||||
{
|
||||
// cerr << "[" << (void*)first << " : " << (void*)(first + first_num) << ")";
|
||||
// cerr << " X ";
|
||||
// cerr << "[" << (void*)second << " : " << (void*)(second + second_num) << ")";
|
||||
// cerr << endl;
|
||||
bool res = false;
|
||||
res |= (second <= first) && (first < second + second_num);
|
||||
res |= (second < first + first_num) && (first + first_num < second + second_num);
|
||||
return res;
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<bool> BufferArea;
|
||||
|
||||
TEST_P(BufferArea, basic)
|
||||
{
|
||||
const bool safe = GetParam();
|
||||
const size_t SZ = 3;
|
||||
int * int_ptr = NULL;
|
||||
uchar * uchar_ptr = NULL;
|
||||
double * dbl_ptr = NULL;
|
||||
{
|
||||
cv::utils::BufferArea area(safe);
|
||||
area.allocate(int_ptr, SZ);
|
||||
area.allocate(uchar_ptr, SZ);
|
||||
area.allocate(dbl_ptr, SZ);
|
||||
area.commit();
|
||||
ASSERT_TRUE(int_ptr != NULL);
|
||||
ASSERT_TRUE(uchar_ptr != NULL);
|
||||
ASSERT_TRUE(dbl_ptr != NULL);
|
||||
EXPECT_EQ((size_t)0, (size_t)int_ptr % sizeof(int));
|
||||
EXPECT_EQ((size_t)0, (size_t)dbl_ptr % sizeof(double));
|
||||
for (size_t i = 0; i < SZ; ++i)
|
||||
{
|
||||
int_ptr[i] = (int)i + 1;
|
||||
uchar_ptr[i] = (uchar)i + 1;
|
||||
dbl_ptr[i] = (double)i + 1;
|
||||
}
|
||||
area.zeroFill(int_ptr);
|
||||
area.zeroFill(uchar_ptr);
|
||||
area.zeroFill(dbl_ptr);
|
||||
for (size_t i = 0; i < SZ; ++i)
|
||||
{
|
||||
EXPECT_EQ((int)0, int_ptr[i]);
|
||||
EXPECT_EQ((uchar)0, uchar_ptr[i]);
|
||||
EXPECT_EQ((double)0, dbl_ptr[i]);
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(int_ptr == NULL);
|
||||
EXPECT_TRUE(uchar_ptr == NULL);
|
||||
EXPECT_TRUE(dbl_ptr == NULL);
|
||||
}
|
||||
|
||||
TEST_P(BufferArea, align)
|
||||
{
|
||||
const bool safe = GetParam();
|
||||
const size_t SZ = 3;
|
||||
const size_t CNT = 5;
|
||||
typedef int T;
|
||||
T * buffers[CNT] = {0};
|
||||
{
|
||||
cv::utils::BufferArea area(safe);
|
||||
// allocate buffers with 3 elements with growing alignment (power of two)
|
||||
for (size_t i = 0; i < CNT; ++i)
|
||||
{
|
||||
const ushort ALIGN = static_cast<ushort>(sizeof(T) << i);
|
||||
EXPECT_TRUE(buffers[i] == NULL);
|
||||
area.allocate(buffers[i], SZ, ALIGN);
|
||||
}
|
||||
area.commit();
|
||||
for (size_t i = 0; i < CNT; ++i)
|
||||
{
|
||||
const ushort ALIGN = static_cast<ushort>(sizeof(T) << i);
|
||||
EXPECT_TRUE(buffers[i] != NULL);
|
||||
EXPECT_EQ((size_t)0, reinterpret_cast<size_t>(buffers[i]) % ALIGN);
|
||||
if (i < CNT - 1)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
EXPECT_FALSE(buffers_overlap(buffers[i], SZ, buffers[i + 1], SZ))
|
||||
<< "Buffers overlap: "
|
||||
<< buffers[i] << " (" << SZ << " elems)"
|
||||
<< " and "
|
||||
<< buffers[i + 1] << " (" << SZ << " elems)"
|
||||
<< " (element size: " << sizeof(T) << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < CNT; ++i)
|
||||
{
|
||||
EXPECT_TRUE(buffers[i] == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(BufferArea, default_align)
|
||||
{
|
||||
const bool safe = GetParam();
|
||||
const size_t CNT = 100;
|
||||
const ushort ALIGN = 64;
|
||||
typedef int T;
|
||||
T * buffers[CNT] = {0};
|
||||
{
|
||||
cv::utils::BufferArea area(safe);
|
||||
// allocate buffers with 1-99 elements with default alignment
|
||||
for (size_t i = 0; i < CNT; ++ i)
|
||||
{
|
||||
EXPECT_TRUE(buffers[i] == NULL);
|
||||
area.allocate(buffers[i], i + 1, ALIGN);
|
||||
}
|
||||
area.commit();
|
||||
for (size_t i = 0; i < CNT; ++i)
|
||||
{
|
||||
EXPECT_TRUE(buffers[i] != NULL);
|
||||
EXPECT_EQ((size_t)0, reinterpret_cast<size_t>(buffers[i]) % ALIGN);
|
||||
if (i < CNT - 1)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
EXPECT_FALSE(buffers_overlap(buffers[i], i + 1, buffers[i + 1], i + 2))
|
||||
<< "Buffers overlap: "
|
||||
<< buffers[i] << " (" << i + 1 << " elems)"
|
||||
<< " and "
|
||||
<< buffers[i + 1] << " (" << i + 2 << " elems)"
|
||||
<< " (element size: " << sizeof(T) << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(BufferArea, bad)
|
||||
{
|
||||
const bool safe = GetParam();
|
||||
int * ptr = 0;
|
||||
cv::utils::BufferArea area(safe);
|
||||
EXPECT_ANY_THROW(area.allocate(ptr, 0)); // bad size
|
||||
EXPECT_ANY_THROW(area.allocate(ptr, 1, 0)); // bad alignment
|
||||
EXPECT_ANY_THROW(area.allocate(ptr, 1, 3)); // bad alignment
|
||||
ptr = (int*)1;
|
||||
EXPECT_ANY_THROW(area.allocate(ptr, 1)); // non-zero pointer
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, BufferArea, testing::Values(true, false));
|
||||
|
||||
|
||||
}} // namespace
|
134
3rdparty/opencv-4.5.4/modules/core/test/test_utils_tls.impl.hpp
vendored
Normal file
134
3rdparty/opencv-4.5.4/modules/core/test/test_utils_tls.impl.hpp
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// This is .hpp file included from test_utils.cpp
|
||||
|
||||
#ifdef CV_CXX11
|
||||
#include <thread> // std::thread
|
||||
#endif
|
||||
|
||||
#include "opencv2/core/utils/tls.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
class TLSReporter
|
||||
{
|
||||
public:
|
||||
static int g_last_id;
|
||||
static int g_allocated;
|
||||
|
||||
int id;
|
||||
|
||||
TLSReporter()
|
||||
{
|
||||
id = CV_XADD(&g_last_id, 1);
|
||||
CV_XADD(&g_allocated, 1);
|
||||
}
|
||||
~TLSReporter()
|
||||
{
|
||||
CV_XADD(&g_allocated, -1);
|
||||
}
|
||||
};
|
||||
|
||||
int TLSReporter::g_last_id = 0;
|
||||
int TLSReporter::g_allocated = 0;
|
||||
|
||||
#ifdef CV_CXX11
|
||||
|
||||
template<typename T>
|
||||
static void callNThreadsWithTLS(int N, TLSData<T>& tls)
|
||||
{
|
||||
std::vector<std::thread> threads(N);
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
threads[i] = std::thread([&]() {
|
||||
TLSReporter* pData = tls.get();
|
||||
(void)pData;
|
||||
});
|
||||
}
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
threads[i].join();
|
||||
}
|
||||
threads.clear();
|
||||
}
|
||||
|
||||
TEST(Core_TLS, HandleThreadTermination)
|
||||
{
|
||||
const int init_id = TLSReporter::g_last_id;
|
||||
const int init_allocated = TLSReporter::g_allocated;
|
||||
|
||||
const int N = 4;
|
||||
TLSData<TLSReporter> tls;
|
||||
|
||||
// use TLS
|
||||
ASSERT_NO_THROW(callNThreadsWithTLS(N, tls));
|
||||
|
||||
EXPECT_EQ(init_id + N, TLSReporter::g_last_id);
|
||||
EXPECT_EQ(init_allocated + 0, TLSReporter::g_allocated);
|
||||
}
|
||||
|
||||
|
||||
static void testTLSAccumulator(bool detachFirst)
|
||||
{
|
||||
const int init_id = TLSReporter::g_last_id;
|
||||
const int init_allocated = TLSReporter::g_allocated;
|
||||
|
||||
const int N = 4;
|
||||
TLSDataAccumulator<TLSReporter> tls;
|
||||
|
||||
{ // empty TLS checks
|
||||
std::vector<TLSReporter*>& data0 = tls.detachData();
|
||||
EXPECT_EQ((size_t)0, data0.size());
|
||||
tls.cleanupDetachedData();
|
||||
}
|
||||
|
||||
// use TLS
|
||||
ASSERT_NO_THROW(callNThreadsWithTLS(N, tls));
|
||||
|
||||
EXPECT_EQ(init_id + N, TLSReporter::g_last_id);
|
||||
EXPECT_EQ(init_allocated + N, TLSReporter::g_allocated);
|
||||
|
||||
if (detachFirst)
|
||||
{
|
||||
std::vector<TLSReporter*>& data1 = tls.detachData();
|
||||
EXPECT_EQ((size_t)N, data1.size());
|
||||
|
||||
// no data through gather after detachData()
|
||||
std::vector<TLSReporter*> data2;
|
||||
tls.gather(data2);
|
||||
EXPECT_EQ((size_t)0, data2.size());
|
||||
|
||||
tls.cleanupDetachedData();
|
||||
|
||||
EXPECT_EQ(init_id + N, TLSReporter::g_last_id);
|
||||
EXPECT_EQ(init_allocated + 0, TLSReporter::g_allocated);
|
||||
EXPECT_EQ((size_t)0, data1.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<TLSReporter*> data2;
|
||||
tls.gather(data2);
|
||||
EXPECT_EQ((size_t)N, data2.size());
|
||||
|
||||
std::vector<TLSReporter*>& data1 = tls.detachData();
|
||||
EXPECT_EQ((size_t)N, data1.size());
|
||||
|
||||
tls.cleanupDetachedData();
|
||||
|
||||
EXPECT_EQ((size_t)0, data1.size());
|
||||
// data2 is not empty, but it has invalid contents
|
||||
EXPECT_EQ((size_t)N, data2.size());
|
||||
}
|
||||
|
||||
EXPECT_EQ(init_id + N, TLSReporter::g_last_id);
|
||||
EXPECT_EQ(init_allocated + 0, TLSReporter::g_allocated);
|
||||
}
|
||||
|
||||
TEST(Core_TLS, AccumulatorHoldData_detachData) { testTLSAccumulator(true); }
|
||||
TEST(Core_TLS, AccumulatorHoldData_gather) { testTLSAccumulator(false); }
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespace
|
Reference in New Issue
Block a user