1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2026-05-25 16:29:45 +03:00
54 changed files with 523 additions and 414 deletions
+1
View File
@@ -278,6 +278,7 @@ endif(PNG_HARDWARE_OPTIMIZATIONS)
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
ocv_warnings_disable(CMAKE_C_FLAGS /wd4146)
endif(MSVC)
add_library(${PNG_LIBRARY} STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL} ${lib_srcs} ${lib_hdrs})
+1 -1
View File
@@ -53,7 +53,7 @@ const char* keys =
"DICT_4X4_50, DICT_4X4_100, DICT_4X4_250, DICT_4X4_1000, DICT_5X5_50, DICT_5X5_100, DICT_5X5_250, "
"DICT_5X5_1000, DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50, DICT_7X7_100, "
"DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL, DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, "
"DICT_APRILTAG_36h10, DICT_APRILTAG_36h11 }"
"DICT_APRILTAG_36h10, DICT_APRILTAG_36h11, DICT_ARUCO_MIP_36h12 }"
"{fad | None | name of file with ArUco dictionary}"
"{of | cameraParameters.xml | Output file name}"
"{ft | true | Auto tuning of calibration flags}"
@@ -175,6 +175,7 @@ bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser)
else if (arucoDictName == "DICT_APRILTAG_25h9") { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_25h9; }
else if (arucoDictName == "DICT_APRILTAG_36h10") { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_36h10; }
else if (arucoDictName == "DICT_APRILTAG_36h11") { mCapParams.charucoDictName = cv::aruco::DICT_APRILTAG_36h11; }
else if (arucoDictName == "DICT_ARUCO_MIP_36h12") { mCapParams.charucoDictName = cv::aruco::DICT_ARUCO_MIP_36h12; }
else {
std::cout << "incorrect name of aruco dictionary \n";
return false;
Binary file not shown.
+3 -3
View File
@@ -489,9 +489,9 @@ class SVG:
f.close()
else:
f = codecs.open(fileName, "w", encoding=encoding)
f.write(self.standalone_xml(encoding=encoding))
f.close()
with open(fileName, "w", encoding=encoding) as f:
f.write(self.standalone_xml(encoding=encoding))
def inkview(self, fileName=None, encoding="utf-8"):
"""View in "inkview", assuming that program is available on your system.
+2 -2
View File
@@ -18,10 +18,10 @@ class aruco_objdetect_test(NewOpenCVTests):
square_size = 100
aruco_type = [cv.aruco.DICT_4X4_1000, cv.aruco.DICT_5X5_1000, cv.aruco.DICT_6X6_1000,
cv.aruco.DICT_7X7_1000, cv.aruco.DICT_ARUCO_ORIGINAL, cv.aruco.DICT_APRILTAG_16h5,
cv.aruco.DICT_APRILTAG_25h9, cv.aruco.DICT_APRILTAG_36h10, cv.aruco.DICT_APRILTAG_36h11]
cv.aruco.DICT_APRILTAG_25h9, cv.aruco.DICT_APRILTAG_36h10, cv.aruco.DICT_APRILTAG_36h11, cv.aruco.DICT_ARUCO_MIP_36h12]
aruco_type_str = ['DICT_4X4_1000','DICT_5X5_1000', 'DICT_6X6_1000',
'DICT_7X7_1000', 'DICT_ARUCO_ORIGINAL', 'DICT_APRILTAG_16h5',
'DICT_APRILTAG_25h9', 'DICT_APRILTAG_36h10', 'DICT_APRILTAG_36h11']
'DICT_APRILTAG_25h9', 'DICT_APRILTAG_36h10', 'DICT_APRILTAG_36h11', 'DICT_ARUCO_MIP_36h12']
marker_size = 0.8*square_size
board_width = cols*square_size
board_height = rows*square_size
@@ -144,7 +144,7 @@ Error correction techniques are employed when necessary.
Consider the following image:
![Image with an assortment of markers](images/singlemarkerssource.jpg)
![Image with an assortment of markers](images/singlemarkerssource.jpg) { width=70% }
And a printout of this image in a photo:
+1 -1
View File
@@ -6,7 +6,7 @@ OpenCV Tutorials {#tutorial_root}
- @subpage tutorial_table_of_content_imgproc - image processing functions
- @subpage tutorial_table_of_content_app - application utils (GUI, image/video input/output)
- @subpage tutorial_table_of_content_calib3d - extract 3D world information from 2D images
- @subpage tutorial_table_of_content_objdetect - INSERT OBJDETECT MODULE INFO
- @subpage tutorial_table_of_content_objdetect - detect ArUco markers and other calibration boards
- @subpage tutorial_table_of_content_features - feature detectors, descriptors and matching framework
- @subpage tutorial_table_of_content_dnn - infer neural networks using built-in _dnn_ module
- @subpage tutorial_table_of_content_other - other modules (stitching, video)
+4
View File
@@ -19,6 +19,8 @@ int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int
//#define cv_hal_warpAffine ipp_hal_warpAffine
#endif
#if IPP_VERSION_X100 >= 202600
int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width,
int dst_height, const double M[9], int interpolation, int borderType, const double borderValue[4]);
@@ -26,6 +28,8 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
//#undef cv_hal_warpPerspective
//#define cv_hal_warpPerspective ipp_hal_warpPerspective
#endif // IPP_VERSION_X100 >= 202600
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
float* mapx, size_t mapx_step, float* mapy, size_t mapy_step,
+180 -304
View File
@@ -8,153 +8,13 @@
#include <opencv2/core.hpp>
#include "precomp_ipp.hpp"
#include <atomic>
// Uncomment to enforce IPP calls for all supported by IPP configurations
// #define IPP_CALLS_ENFORCED
#define CV_IPP_SAFE_CALL(pFunc, pFlag, ...) if (pFunc(__VA_ARGS__) != ippStsNoErr) {*pFlag = false; return;}
#define CV_TYPE(src_type) (src_type & (CV_DEPTH_MAX - 1))
#ifdef HAVE_IPP_IW
// Warp affine section
#include "iw++/iw.hpp"
class ipp_warpAffineParallel: public cv::ParallelLoopBody
{
public:
ipp_warpAffineParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, IppiInterpolationType _inter, double (&_coeffs)[2][3], ::ipp::IwiBorderType _borderType, IwTransDirection _iwTransDirection, bool *_ok):m_src(src), m_dst(dst)
{
ok = _ok;
inter = _inter;
borderType = _borderType;
iwTransDirection = _iwTransDirection;
for( int i = 0; i < 2; i++ )
for( int j = 0; j < 3; j++ )
coeffs[i][j] = _coeffs[i][j];
*ok = true;
}
~ipp_warpAffineParallel() {}
virtual void operator() (const cv::Range& range) const CV_OVERRIDE
{
//CV_INSTRUMENT_REGION_IPP();
if(*ok == false)
return;
try
{
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, m_dst.m_size.width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, m_src, m_dst, coeffs, iwTransDirection, inter, ::ipp::IwiWarpAffineParams(), borderType, tile);
}
catch(const ::ipp::IwException &)
{
*ok = false;
return;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
}
private:
::ipp::IwiImage &m_src;
::ipp::IwiImage &m_dst;
IppiInterpolationType inter;
double coeffs[2][3];
::ipp::IwiBorderType borderType;
IwTransDirection iwTransDirection;
bool *ok;
const ipp_warpAffineParallel& operator= (const ipp_warpAffineParallel&);
};
int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width,
int dst_height, const double M[6], int interpolation, int borderType, const double borderValue[4])
{
CV_HAL_CHECK_USE_IPP();
//CV_INSTRUMENT_REGION_IPP();
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
if((int)ippInter < 0 || interpolation > 2)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
#if defined(IPP_CALLS_ENFORCED)
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16U
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32F
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}}; //64F
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}}, //16U
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}, //16S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}}; //64F
#endif
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// Acquire data and begin processing
try
{
::ipp::IwiImage iwSrc;
iwSrc.Init({src_width, src_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), NULL, src_data, IwSize(src_step));
::ipp::IwiImage iwDst({dst_width, dst_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), NULL, dst_data, dst_step);
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), {borderValue[0], borderValue[1], borderValue[2], borderValue[3]});
IwTransDirection iwTransDirection = iwTransInverse;
if((int)ippBorder == -1)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
double coeffs[2][3];
for( int i = 0; i < 2; i++ )
for( int j = 0; j < 3; j++ )
coeffs[i][j] = M[i*3 + j];
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
const int threads = ippiSuggestRowThreadsNum(iwDst, min_payload);
if (threads > 1)
{
bool ok = true;
cv::Range range(0, (int)iwDst.m_size.height);
ipp_warpAffineParallel invoker(iwSrc, iwDst, ippInter, coeffs, ippBorder, iwTransDirection, &ok);
if(!ok)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
parallel_for_(range, invoker, threads);
if(!ok)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
else
{
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder);
}
}
catch (const ::ipp::IwException &)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_OK;
}
#endif // HAVE_IPP_IW
// End of Warp affine section
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
template <int channels, typename Type>
@@ -214,168 +74,143 @@ static bool IPPSet(const double value[4], void *dataPointer, int step, IppiSize
return false;
}
// Warp perspective section
#ifdef HAVE_IPP_IW
typedef IppStatus (CV_STDCALL* ippiWarpPerspectiveFunc)(const Ipp8u*, int, Ipp8u*, int,IppiPoint, IppiSize, const IppiWarpSpec*,Ipp8u*);
typedef IppStatus (CV_STDCALL* ippiWarpPerspectiveInitFunc)(IppiSize, IppiRect, IppiSize, IppDataType,const double [3][3], IppiWarpDirection, int, IppiBorderType, const Ipp64f *, int, IppiWarpSpec*);
#include "iw++/iw.hpp"
class IPPWarpPerspectiveInvoker :
public cv::ParallelLoopBody
int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step,
int dst_width, int dst_height, const double M[6], int interpolation, int borderType, const double borderValue[4])
{
// Mem object ot simplify IPP memory lifetime control
struct IPPWarpPerspectiveMem
//CV_INSTRUMENT_REGION_IPP();
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
if((int)ippInter < 0 || interpolation > 2)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
#if defined(IPP_CALLS_ENFORCED)
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16U
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32F
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}}; //64F
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}}, //16U
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}, //16S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}}; //64F
#endif
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
{
IppiWarpSpec* pSpec = nullptr;
Ipp8u* pBuffer = nullptr;
IPPWarpPerspectiveMem() = default;
IPPWarpPerspectiveMem (const IPPWarpPerspectiveMem&) = delete;
IPPWarpPerspectiveMem& operator= (const IPPWarpPerspectiveMem&) = delete;
void AllocateSpec(int size)
{
pSpec = (IppiWarpSpec*)ippMalloc_L(size);
}
void AllocateBuffer(int size)
{
pBuffer = (Ipp8u*)ippMalloc_L(size);
}
~IPPWarpPerspectiveMem()
{
if (nullptr != pSpec) ippFree(pSpec);
if (nullptr != pBuffer) ippFree(pBuffer);
}
};
public:
IPPWarpPerspectiveInvoker(int _src_type, cv::Mat &_src, size_t _src_step, cv::Mat &_dst, size_t _dst_step, IppiInterpolationType _interpolation,
double (&_coeffs)[3][3], int &_borderType, const double _borderValue[4], ippiWarpPerspectiveFunc _func, ippiWarpPerspectiveInitFunc _initFunc,
bool *_ok) :
ParallelLoopBody(), src_type(_src_type), src(_src), src_step(_src_step), dst(_dst), dst_step(_dst_step), inter(_interpolation), coeffs(_coeffs),
borderType(_borderType), func(_func), initFunc(_initFunc), ok(_ok)
{
memcpy(this->borderValue, _borderValue, sizeof(this->borderValue));
*ok = true;
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
virtual void operator() (const cv::Range& range) const CV_OVERRIDE
// Acquire data and begin processing
double coeffs[2][3];
for( int i = 0; i < 2; i++ )
for( int j = 0; j < 3; j++ )
coeffs[i][j] = M[i*3 + j];
try
{
//CV_INSTRUMENT_REGION_IPP();
if (*ok == false)
return;
std::atomic_bool ok{true};
cv::Range cv_range(0, dst_height);
::ipp::IwiImage iwSrc;
iwSrc.Init(IwiSize{src_width, src_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), src_data, IwSize(src_step));
::ipp::IwiImage iwDst(IwiSize{dst_width, dst_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), dst_data, IwSize(dst_step));
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), {borderValue, 4});
// OpenCV inverts the affine matrix before calling the HAL (lines 2401-2411 of imgwarp.cpp), so the HAL receives the inverse transform.
IwTransDirection iwTransDirection = iwTransInverse;
IPPWarpPerspectiveMem mem;
int specSize = 0, initSize = 0, bufSize = 0;
IppiWarpDirection direction = ippWarpBackward; //fixed for IPP
const Ipp32u numChannels = CV_MAT_CN(src_type);
IppiSize srcsize = {src.cols, src.rows};
IppiSize dstsize = {dst.cols, dst.rows};
IppiRect srcroi = {0, 0, src.cols, src.rows};
/* Spec and init buffer sizes */
CV_IPP_SAFE_CALL(ippiWarpPerspectiveGetSize, ok, srcsize, srcroi, dstsize, ippiGetDataType(src_type), coeffs, inter, ippWarpBackward, ippiGetBorderType(borderType), &specSize, &initSize);
mem.AllocateSpec(specSize);
CV_IPP_SAFE_CALL(initFunc, ok, srcsize, srcroi, dstsize, ippiGetDataType(src_type), coeffs, direction, numChannels, ippiGetBorderType(borderType),
borderValue, 0, mem.pSpec);
CV_IPP_SAFE_CALL(ippiWarpGetBufferSize, ok, mem.pSpec, dstsize, &bufSize);
mem.AllocateBuffer(bufSize);
IppiPoint dstRoiOffset = {0, range.start};
IppiSize dstRoiSize = {dst.cols, range.size()};
auto* pDst = dst.ptr(range.start);
if (borderType == cv::BorderTypes::BORDER_CONSTANT &&
!IPPSet(borderValue, pDst, (int)dst_step, dstRoiSize, src.channels(), src.depth()))
if ((int)ippBorder == -1)
{
*ok = false;
return;
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// The lambda function is used to invoke IPP warping function in parallel for different image stripes.
// The function is exception safe and sets the 'ok' flag to false if any exception occurs during processing.
// The 'ok' flag is checked before and after parallel processing to determine if the operation was successful or
// if it should fall back to a non-IPP implementation.
auto IPPWarpAffineInvokerLambda = [&iwSrc, &iwDst, dst_width, ippInter, &coeffs, ippBorder, iwTransDirection, &ok](const cv::Range& range)
{
//CV_INSTRUMENT_REGION_IPP();
if (!ok.load(std::memory_order_relaxed))
{
return;
}
try
{
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst_width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder, tile);
}
catch (const ::ipp::IwException &)
{
ok.store(false, std::memory_order_relaxed);
return;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
};
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
const int num_threads = ippiSuggestRowThreadsNum(iwDst, min_payload);
if (num_threads > 1)
{
parallel_for_(cv_range, IPPWarpAffineInvokerLambda, num_threads);
}
else
{
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder);
}
if (ippStsNoErr != CV_INSTRUMENT_FUN_IPP(func, src.ptr(), (int)src_step, pDst, (int)dst_step, dstRoiOffset, dstRoiSize, mem.pSpec, mem.pBuffer))
if (!ok)
{
*ok = false;
return;
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
}
private:
int src_type;
cv::Mat &src;
size_t src_step;
cv::Mat &dst;
size_t dst_step;
IppiInterpolationType inter;
double (&coeffs)[3][3];
int borderType;
double borderValue[4];
ippiWarpPerspectiveFunc func;
ippiWarpPerspectiveInitFunc initFunc;
bool *ok;
const IPPWarpPerspectiveInvoker& operator= (const IPPWarpPerspectiveInvoker&);
};
catch (const ::ipp::IwException &)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_OK;
}
#if IPP_VERSION_X100 >= 202600
int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar * dst_data, size_t dst_step,
int dst_width, int dst_height, const double M[9], int interpolation, int borderType, const double borderValue[4])
{
CV_HAL_CHECK_USE_IPP();
//CV_INSTRUMENT_REGION_IPP();
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
if (src_height <= 1 || src_width <= 1)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
ippiWarpPerspectiveFunc ippFunc = nullptr;
ippiWarpPerspectiveInitFunc ippInitFunc = nullptr;
int mode =
interpolation == cv::InterpolationFlags::INTER_NEAREST ? IPPI_INTER_NN :
interpolation == cv::InterpolationFlags::INTER_LINEAR ? IPPI_INTER_LINEAR : 0;
if (interpolation == cv::InterpolationFlags::INTER_NEAREST)
{
ippInitFunc = ippiWarpPerspectiveNearestInit;
ippFunc =
src_type == CV_8UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_8u_C1R :
src_type == CV_8UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_8u_C3R :
src_type == CV_8UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_8u_C4R :
src_type == CV_16UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16u_C1R :
src_type == CV_16UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16u_C3R :
src_type == CV_16UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16u_C4R :
src_type == CV_16SC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16s_C1R :
src_type == CV_16SC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16s_C3R :
src_type == CV_16SC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_16s_C4R :
src_type == CV_32FC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_32f_C1R :
src_type == CV_32FC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_32f_C3R :
src_type == CV_32FC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveNearest_32f_C4R : nullptr;
}
else if (interpolation == cv::InterpolationFlags::INTER_LINEAR)
{
ippInitFunc = ippiWarpPerspectiveLinearInit;
ippFunc =
src_type == CV_8UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_8u_C1R :
src_type == CV_8UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_8u_C3R :
src_type == CV_8UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_8u_C4R :
src_type == CV_16UC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16u_C1R :
src_type == CV_16UC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16u_C3R :
src_type == CV_16UC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16u_C4R :
src_type == CV_16SC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16s_C1R :
src_type == CV_16SC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16s_C3R :
src_type == CV_16SC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_16s_C4R :
src_type == CV_32FC1 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_32f_C1R :
src_type == CV_32FC3 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_32f_C3R :
src_type == CV_32FC4 ? (ippiWarpPerspectiveFunc)ippiWarpPerspectiveLinear_32f_C4R : nullptr;
}
else
if (mode == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
if (ippFunc == nullptr)
// Unsupported source type
if (src_type != CV_8UC1 && src_type != CV_8UC3 && src_type != CV_8UC4 &&
src_type != CV_16UC1 && src_type != CV_16UC3 && src_type != CV_16UC4 &&
src_type != CV_16SC1 && src_type != CV_16SC3 && src_type != CV_16SC4 &&
src_type != CV_32FC1 && src_type != CV_32FC3 && src_type != CV_32FC4)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
@@ -396,46 +231,90 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
{{0, 0}, {0, 0}, {0, 1}, {0, 1}}, //16U
{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //16S
{{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //32S
{{0, 0}, {0, 0}, {0, 0}, {1, 0}}, //32F
{{1, 0}, {0, 0}, {0, 0}, {1, 0}}, //32F
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; //64F
#endif
const char type_size[CV_DEPTH_MAX] = {1,1,2,2,4,4,8};
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
if (impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// Acquire data and begin processing
double coeffs[3][3];
for( int i = 0; i < 3; i++ )
for( int j = 0; j < 3; j++ )
coeffs[i][j] = M[i*3 + j];
bool ok = true;
cv::Range range(0, dst_height);
cv::Mat src(cv::Size(src_width, src_height), src_type, const_cast<uchar*>(src_data), src_step);
cv::Mat dst(cv::Size(dst_width, dst_height), src_type, dst_data, dst_step);
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
int num_threads = ippiSuggestRowThreadsNum(dst_width, dst_height, type_size[CV_TYPE(src_type)]*CV_MAT_CN(src_type), min_payload);
IPPWarpPerspectiveInvoker invoker(src_type, src, src_step, dst, dst_step, ippInter, coeffs, borderType, borderValue, ippFunc, ippInitFunc, &ok);
(num_threads > 1) ? parallel_for_(range, invoker, num_threads) : invoker(range);
if (ok)
try
{
CV_IMPL_ADD(CV_IMPL_IPP | CV_IMPL_MT);
return CV_HAL_ERROR_OK;
std::atomic_bool ok{true};
cv::Range cv_range(0, dst_height);
::ipp::IwiImage iwSrc; // src_data is const pointer. So, we need to call an init function
iwSrc.Init(IwiSize{src_width, src_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), src_data, IwSize(src_step));
::ipp::IwiImage iwDst(IwiSize{dst_width, dst_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), dst_data, IwSize(dst_step));
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), {borderValue, 4});
IwTransDirection iwTransDirection = iwTransInverse; //fixed for IPP
if ((int)ippBorder == -1)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// The lambda function is used to invoke IPP warping function in parallel for different image stripes.
// The function is exception safe and sets the 'ok' flag to false if any exception occurs during processing.
// The 'ok' flag is checked before and after parallel processing to determine
// if the operation was successful or if it should fall back to a non-IPP implementation.
auto IPPWarpPerspectiveInvokerLambda = [&iwSrc, &iwDst, dst_width, ippInter, &coeffs, ippBorder, iwTransDirection, &ok](const cv::Range& range)
{
//CV_INSTRUMENT_REGION_IPP();
if (!ok.load(std::memory_order_relaxed))
{
return;
}
try
{
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst_width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpPerspective, iwSrc, iwDst, ippRectInfinite, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpPerspectiveParams(), ippBorder, tile);
}
catch (const ::ipp::IwException &)
{
ok.store(false, std::memory_order_relaxed);
return;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
};
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
const char type_size[CV_DEPTH_MAX] = {1,1,2,2,4,4,8};
const int num_threads = ippiSuggestRowThreadsNum(dst_width, dst_height, type_size[CV_TYPE(src_type)]*CV_MAT_CN(src_type), min_payload);
if (num_threads > 1)
{
parallel_for_(cv_range, IPPWarpPerspectiveInvokerLambda, num_threads);
}
else
{
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpPerspective, iwSrc, iwDst, ippRectInfinite, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpPerspectiveParams(), ippBorder);
}
if (!ok)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}
catch (const ::ipp::IwException &)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
return CV_HAL_ERROR_OK;
}
#endif // IPP_VERSION_X100 >= 202600
// End of Warp perspective section
#endif // HAVE_IPP_IW
// Remap section
typedef IppStatus(CV_STDCALL *ippiRemap)(const void *pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
const Ipp32f *pxMap, int xMapStep, const Ipp32f *pyMap, int yMapStep,
void *pDst, int dstStep, IppiSize dstRoiSize, int interpolation);
@@ -445,20 +324,18 @@ class IPPRemapInvoker : public cv::ParallelLoopBody
public:
IPPRemapInvoker(int _src_type, const uchar *_src_data, size_t _src_step, int _src_width, int _src_height,
uchar *_dst_data, size_t _dst_step, int _dst_width, float *_mapx, size_t _mapx_step, float *_mapy,
size_t _mapy_step, ippiRemap _ippFunc, int _ippInterpolation, int _borderType, const double _borderValue[4], bool *_ok) :
ParallelLoopBody(),
size_t _mapy_step, ippiRemap _ippFunc, int _ippInterpolation, int _borderType, const double _borderValue[4], std::atomic_bool *_ok) :
src_type(_src_type), src(_src_data), src_step(_src_step), src_width(_src_width), src_height(_src_height),
dst(_dst_data), dst_step(_dst_step), dst_width(_dst_width), mapx(_mapx), mapx_step(_mapx_step), mapy(_mapy),
mapy_step(_mapy_step), ippFunc(_ippFunc), ippInterpolation(_ippInterpolation), borderType(_borderType), ok(_ok)
{
memcpy(this->borderValue, _borderValue, sizeof(this->borderValue));
*ok = true;
}
virtual void operator()(const cv::Range &range) const
{
//CV_INSTRUMENT_REGION_IPP();
if (*ok == false)
if(!ok->load(std::memory_order_relaxed))
return;
IppiRect srcRoiRect = {0, 0, src_width, src_height};
@@ -469,7 +346,7 @@ public:
if (borderType == cv::BORDER_CONSTANT &&
!IPPSet(borderValue, dst_roi_data, (int)dst_step, dstRoiSize, cn, depth))
{
*ok = false;
ok->store(false, std::memory_order_relaxed);
return;
}
@@ -477,7 +354,7 @@ public:
mapx, (int)mapx_step, mapy, (int)mapy_step,
dst_roi_data, (int)dst_step, dstRoiSize, ippInterpolation))
{
*ok = false;
ok->store(false, std::memory_order_relaxed);
return;
}
@@ -499,7 +376,7 @@ private:
ippiRemap ippFunc;
int ippInterpolation, borderType;
double borderValue[4];
bool *ok;
std::atomic_bool *ok;
};
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
@@ -507,7 +384,6 @@ int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int s
float *mapx, size_t mapx_step, float *mapy, size_t mapy_step,
int interpolation, int border_type, const double border_value[4])
{
CV_HAL_CHECK_USE_IPP();
if (!((interpolation == cv::INTER_LINEAR || interpolation == cv::INTER_CUBIC || interpolation == cv::INTER_NEAREST) &&
(border_type == cv::BORDER_CONSTANT || border_type == cv::BORDER_TRANSPARENT)))
{
@@ -555,7 +431,7 @@ int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int s
if (ippFunc)
{
bool ok = true;
std::atomic_bool ok{true};
IPPRemapInvoker invoker(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width,
mapx, mapx_step, mapy, mapy_step, ippFunc, ippInterpolation, border_type, border_value, &ok);
+2 -2
View File
@@ -1,8 +1,8 @@
function(download_kleidicv root_var)
set(${root_var} "" PARENT_SCOPE)
ocv_update(KLEIDICV_SRC_COMMIT "0.7.0")
ocv_update(KLEIDICV_SRC_HASH "e8f94e427bd78a745afa5c8cd073b416")
ocv_update(KLEIDICV_SRC_COMMIT "26.03")
ocv_update(KLEIDICV_SRC_HASH "b85a745bfe0e87e67e30be9533eb6b24")
set(THE_ROOT "${OpenCV_BINARY_DIR}/3rdparty/kleidicv")
ocv_download(FILENAME "kleidicv-${KLEIDICV_SRC_COMMIT}.tar.gz"
+9 -3
View File
@@ -708,9 +708,15 @@ __CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType)
#endif
#if defined(__clang__) || defined(__GNUC__)
#define CV_DISABLE_UBSAN __attribute__((no_sanitize("undefined")))
#else
#define CV_DISABLE_UBSAN
# if defined(__has_attribute)
# if __has_attribute(no_sanitize)
# define CV_DISABLE_UBSAN __attribute__((no_sanitize("undefined")))
# endif
# endif
#endif
#ifndef CV_DISABLE_UBSAN
# define CV_DISABLE_UBSAN
#endif
/****************************************************************************************\
@@ -2620,23 +2620,25 @@ inline v_float32 v_matmul(const v_float32& v, const v_float32& mat0,
const v_float32& mat1, const v_float32& mat2,
const v_float32& mat3)
{
vfloat32m2_t res;
res = __riscv_vfmul_vf_f32m2(mat0, v_extract_n(v, 0), VTraits<v_float32>::vlanes());
res = __riscv_vfmacc_vf_f32m2(res, v_extract_n(v, 1), mat1, VTraits<v_float32>::vlanes());
res = __riscv_vfmacc_vf_f32m2(res, v_extract_n(v, 2), mat2, VTraits<v_float32>::vlanes());
res = __riscv_vfmacc_vf_f32m2(res, v_extract_n(v, 3), mat3, VTraits<v_float32>::vlanes());
return res;
const int vl = VTraits<v_float32>::vlanes();
vuint32m2_t idx = __riscv_vand(__riscv_vid_v_u32m2(vl), 0xfffffffc, vl);
v_float32 v0 = __riscv_vrgather(v, idx, vl);
v_float32 v1 = __riscv_vrgather(v, __riscv_vadd(idx, 1, vl), vl);
v_float32 v2 = __riscv_vrgather(v, __riscv_vadd(idx, 2, vl), vl);
v_float32 v3 = __riscv_vrgather(v, __riscv_vadd(idx, 3, vl), vl);
return v_fma(v0, mat0, v_fma(v1, mat1, v_fma(v2, mat2, v_mul(v3, mat3))));
}
// TODO: only 128 bit now.
inline v_float32 v_matmuladd(const v_float32& v, const v_float32& mat0,
const v_float32& mat1, const v_float32& mat2,
const v_float32& a)
{
vfloat32m2_t res = __riscv_vfmul_vf_f32m2(mat0, v_extract_n(v,0), VTraits<v_float32>::vlanes());
res = __riscv_vfmacc_vf_f32m2(res, v_extract_n(v,1), mat1, VTraits<v_float32>::vlanes());
res = __riscv_vfmacc_vf_f32m2(res, v_extract_n(v,2), mat2, VTraits<v_float32>::vlanes());
return __riscv_vfadd(res, a, VTraits<v_float32>::vlanes());
const int vl = VTraits<v_float32>::vlanes();
vuint32m2_t idx = __riscv_vand(__riscv_vid_v_u32m2(vl), 0xfffffffc, vl);
v_float32 v0 = __riscv_vrgather(v, idx, vl);
v_float32 v1 = __riscv_vrgather(v, __riscv_vadd(idx, 1, vl), vl);
v_float32 v2 = __riscv_vrgather(v, __riscv_vadd(idx, 2, vl), vl);
return v_fma(v0, mat0, v_fma(v1, mat1, v_fma(v2, mat2, a)));
}
inline void v_cleanup() {}
+19 -7
View File
@@ -1820,12 +1820,18 @@ public class CoreTest extends OpenCVTestCase {
assertGE(1e-6, Math.abs(Core.solvePoly(coeffs, roots)));
truth = new Mat(3, 1, CvType.CV_32FC2) {
List<Mat> rootsReIm = new ArrayList<Mat>();
Core.split(roots, rootsReIm);
Core.sort(rootsReIm.get(0), dst, Core.SORT_EVERY_COLUMN);
Mat truthRe = new Mat(3, 1, CvType.CV_32F) {
{
put(0, 0, 1, 0, 2, 0, 3, 0);
put(0, 0, 1, 2, 3);
}
};
assertMatEqual(truth, roots, EPS);
Mat truthIm = Mat.zeros(3, 1, CvType.CV_32F);
assertMatEqual(truthRe, dst, EPS);
assertMatEqual(truthIm, rootsReIm.get(1), EPS);
}
public void testSolvePolyMatMatInt() {
@@ -1836,14 +1842,20 @@ public class CoreTest extends OpenCVTestCase {
};
Mat roots = new Mat();
assertEquals(10.198039027185569, Core.solvePoly(coeffs, roots, 1));
assertGE(1e-6, Core.solvePoly(coeffs, roots, 10));
truth = new Mat(3, 1, CvType.CV_32FC2) {
List<Mat> rootsReIm = new ArrayList<Mat>();
Core.split(roots, rootsReIm);
Core.sort(rootsReIm.get(0), dst, Core.SORT_EVERY_COLUMN);
Mat truthRe = new Mat(3, 1, CvType.CV_32F) {
{
put(0, 0, 1, 0, -1, 2, -2, 12);
put(0, 0, 1, 2, 3);
}
};
assertMatEqual(truth, roots, EPS);
Mat truthIm = Mat.zeros(3, 1, CvType.CV_32F);
assertMatEqual(truthRe, dst, EPS);
assertMatEqual(truthIm, rootsReIm.get(1), EPS);
}
public void testSort() {
+34 -1
View File
@@ -1585,7 +1585,40 @@ double cv::solvePoly( InputArray _coeffs0, OutputArray _roots0, int maxIters )
break;
}
C p(1, 0), r(1, 1);
// Related issue: https://github.com/opencv/opencv/issues/23644,
// This the initialization scheme of "Initial approximations in Durand-Kerner's root finding method" by Guggenheimer.
// https://link.springer.com/article/10.1007/BF01935059
// We put the initial points equidistantly on a circle on the complex plane. This code computes the circle radius as in the paper.
Mat absCoeffs(n + 1, 1, CV_64F);
for( i = 0; i <= n; i++ )
absCoeffs.at<double>(i) = abs(coeffs[i]);
int nonZeroCoeffs = 0;
Mat u(n, 1, CV_64F, Scalar(0)), v(n, 1, CV_64F, Scalar(0));
for( i = 0; i <= n; i++ )
{
double coeff = absCoeffs.at<double>(i);
if( coeff > DBL_EPSILON )
{
if( i != n )
u.at<double>(i) = 2.0 * pow(coeff / absCoeffs.at<double>(n), 1.0 / (n - i));
if( i != 0 )
v.at<double>(i - 1) = 0.5 * pow(absCoeffs.at<double>(0) / coeff, 1.0 / i);
nonZeroCoeffs++;
}
}
double scale = 1;
if( nonZeroCoeffs > 2 )
{
Point maxU, minV;
minMaxLoc(u, nullptr, nullptr, nullptr, &maxU);
minMaxLoc(v, nullptr, nullptr, &minV);
u.at<double>(maxU) = 0;
v.at<double>(minV) = 0;
scale = (sum(u).val[0] + sum(v).val[0]) / (2 * nonZeroCoeffs - 2);
}
C p(scale, 0), r(cos(CV_2PI / n), sin(CV_2PI / n));
for( i = 0; i < n; i++ )
{
+1 -2
View File
@@ -1596,8 +1596,7 @@ static void
transform_32f( const float* src, float* dst, const float* m, int len, int scn, int dcn )
{
// Disabled for RISC-V Vector (scalable), because of:
// 1. v_matmuladd for RVV is 128-bit only but not scalable, this will fail the test `Core_Transform.accuracy`.
// 2. Both gcc and clang can autovectorize this, with better performance than using Universal intrinsic.
// 1. Both gcc and clang can autovectorize this, with better performance than using Universal intrinsic.
#if (CV_SIMD || CV_SIMD_SCALABLE) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) && !(CV_TRY_RVV && CV_RVV)
int x = 0;
if( scn == 3 && dcn == 3 )
+1 -1
View File
@@ -1283,7 +1283,7 @@ struct MaskedNormInf_SIMD<float, float> {
v_float32 acc = vx_setzero_f32();
for (; i <= len - vstep; i += vstep) {
v_uint32 m = v_reinterpret_as_u32(vx_load_expand(mask + i));
v_uint32 m = vx_load_expand_q(mask + i);
v_uint32 cmp = v_gt(m, vx_setzero_u32());
v_float32 s = vx_load(src + i);
s = v_abs(s);
+6 -8
View File
@@ -1570,9 +1570,8 @@ template<typename R> struct TheTest
R v = dataV, a = dataA, b = dataB, c = dataC, d = dataD;
Data<R> res = v_matmul(v, a, b, c, d);
// for (int i = 0; i < VTraits<R>::vlanes(); i += 4)
// {
int i = 0;
for (int i = 0; i < VTraits<R>::vlanes(); i += 4)
{
for (int j = i; j < i + 4; ++j)
{
SCOPED_TRACE(cv::format("i=%d j=%d", i, j));
@@ -1582,12 +1581,11 @@ template<typename R> struct TheTest
+ dataV[i + 3] * dataD[j];
EXPECT_COMPARE_EQ(val, res[j]);
}
// }
}
Data<R> resAdd = v_matmuladd(v, a, b, c, d);
// for (int i = 0; i < VTraits<R>::vlanes(); i += 4)
// {
i = 0;
for (int i = 0; i < VTraits<R>::vlanes(); i += 4)
{
for (int j = i; j < i + 4; ++j)
{
SCOPED_TRACE(cv::format("i=%d j=%d", i, j));
@@ -1597,7 +1595,7 @@ template<typename R> struct TheTest
+ dataD[j];
EXPECT_COMPARE_EQ(val, resAdd[j]);
}
// }
}
return *this;
}
+87
View File
@@ -1978,6 +1978,93 @@ TEST(Core_SolvePoly, regression_5599)
}
}
TEST(Core_SolvePoly, regression_23644)
{
// x^2 - 2x - 3 = 0, roots: 3, -1
cv::Mat coefs = (cv::Mat_<float>(1,3) << -3, -2, 1 );
cv::Mat r;
double prec;
prec = cv::solvePoly(coefs, r);
EXPECT_LE(prec, 1e-6);
EXPECT_EQ(2u, r.total());
ASSERT_EQ(CV_32FC2, r.type());
checkRoot<float>(r, 3, 0);
checkRoot<float>(r, -1, 0);
}
TEST(Core_SolvePoly, degree_2_polynomials)
{
cv::Mat_<float> coefs(1,3);
cv::Mat r;
double prec;
for (float c0 = -20; c0 <= 20; c0++)
{
coefs.at<float>(0) = c0;
for (float c1 = -20; c1 <= 20; c1++)
{
coefs.at<float>(1) = c1;
for (float c2 = -20; c2 <= 20; c2++)
{
coefs.at<float>(2) = c2;
prec = cv::solvePoly(coefs, r);
EXPECT_LE(prec, 1e-6);
}
}
}
}
TEST(Core_SolvePoly, degree_4_polynomials)
{
applyTestTag(CV_TEST_TAG_VERYLONG);
cv::Mat_<float> coefs(1,5);
cv::Mat r;
double prec;
for (float c0 = -10; c0 <= 10; c0++)
{
coefs.at<float>(0) = c0;
for (float c1 = -10; c1 <= 10; c1++)
{
coefs.at<float>(1) = c1;
for (float c2 = -10; c2 <= 10; c2++)
{
coefs.at<float>(2) = c2;
for (float c3 = -10; c3 <= 10; c3++)
{
coefs.at<float>(3) = c3;
for (float c4 = -10; c4 <= 10; c4++)
{
coefs.at<float>(4) = c4;
prec = cv::solvePoly(coefs, r);
EXPECT_LE(prec, 1e-3);
}
}
}
}
}
}
TEST(Core_SolvePoly, different_magnitudes_polynomials)
{
cv::Mat_<float> coefs(1,3);
cv::Mat r;
double prec;
for (float i = -10; i < 10; i++)
{
coefs.at<float>(0) = pow(2.f, i);
for (float j = -10; j < 10; j++)
{
coefs.at<float>(1) = pow(2.f, j);
for (float k = -10; k < 10; k++)
{
coefs.at<float>(2) = pow(2.f, k);
prec = cv::solvePoly(coefs, r);
EXPECT_LE(prec, 1e-6);
}
}
}
}
class Core_PhaseTest : public cvtest::BaseTest
{
int t;
+1 -1
View File
@@ -231,7 +231,7 @@ class dnn_test(NewOpenCVTests):
iouDiff = 0.05
confThreshold = 0.0001
nmsThreshold = 0
scoreDiff = 1e-3
scoreDiff = 1.1e-3
classIds, confidences, boxes = model.detect(frame, confThreshold, nmsThreshold)
+1 -1
View File
@@ -278,7 +278,7 @@ TEST(Reproducibility_FCN, Accuracy)
int shape[] = {1, 21, 500, 500};
Mat ref(4, shape, CV_32FC1, refData.data);
normAssert(ref, out);
normAssert(ref, out, "", 0.013, 0.17);
}
TEST(Reproducibility_SSD, Accuracy)
+2
View File
@@ -138,6 +138,8 @@ void normAssertDetections(
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
{
scores_diff = std::max(0.022, scores_diff);
boxes_iou_diff = std::max(0.019, boxes_iou_diff);
ASSERT_FALSE(testClassIds.empty()) << "No detections";
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
std::vector<double> refBoxesIoUDiff(refBoxes.size(), 1.0);
+6 -8
View File
@@ -979,7 +979,7 @@ TEST_P(Test_Int8_nets, MobileNet_v1_SSD)
Mat blob = blobFromImage(inp, 1.0, Size(300, 300), Scalar(), true, false);
Mat ref = blobFromNPY(_tf("tensorflow/ssd_mobilenet_v1_coco_2017_11_17.detection_out.npy"));
float confThreshold = 0.5, scoreDiff = 0.034, iouDiff = 0.13;
float confThreshold = 0.5, scoreDiff = 0.034, iouDiff = 0.14;
testDetectionNet(net, blob, ref, confThreshold, scoreDiff, iouDiff);
}
@@ -997,7 +997,7 @@ TEST_P(Test_Int8_nets, MobileNet_v1_SSD_PPN)
Mat blob = blobFromImage(inp, 1.0, Size(300, 300), Scalar(), true, false);
Mat ref = blobFromNPY(_tf("tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy"));
float confThreshold = 0.51, scoreDiff = 0.05, iouDiff = 0.06;
float confThreshold = 0.51, scoreDiff = 0.05, iouDiff = 0.07;
testDetectionNet(net, blob, ref, confThreshold, scoreDiff, iouDiff);
}
@@ -1259,7 +1259,7 @@ TEST_P(Test_Int8_nets, YOLOv3)
std::string model_file = "yolov3.onnx";
double scoreDiff = 0.08, iouDiff = 0.21, confThreshold = 0.25;
double scoreDiff = 0.08, iouDiff = 0.21, confThreshold = 0.28;
{
SCOPED_TRACE("batch size 1");
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
@@ -1285,7 +1285,7 @@ TEST_P(Test_Int8_nets, YOLOv4)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL);
const int N0 = 3;
const int N1 = 7;
const int N1 = 5;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 16, 0.992194f, 0.172375f, 0.402458f, 0.403918f, 0.932801f,
0, 1, 0.988326f, 0.166708f, 0.228236f, 0.737208f, 0.735803f,
@@ -1296,8 +1296,6 @@ TEST_P(Test_Int8_nets, YOLOv4)
1, 2, 0.98233f, 0.452007f, 0.462217f, 0.495612f, 0.521687f,
1, 9, 0.919195f, 0.374642f, 0.316524f, 0.398126f, 0.393714f,
1, 9, 0.856303f, 0.666842f, 0.372215f, 0.685539f, 0.44141f,
1, 9, 0.313516f, 0.656791f, 0.374734f, 0.671959f, 0.438371f,
1, 9, 0.256625f, 0.940232f, 0.326931f, 0.967586f, 0.374002f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
@@ -1305,13 +1303,13 @@ TEST_P(Test_Int8_nets, YOLOv4)
double scoreDiff = 0.15, iouDiff = 0.2;
{
SCOPED_TRACE("batch size 1");
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.5);
}
{
SCOPED_TRACE("batch size 2");
testYOLOModel(model_file, ref, scoreDiff, iouDiff);
testYOLOModel(model_file, ref, scoreDiff, iouDiff, 0.5);
}
}
+1 -1
View File
@@ -460,7 +460,7 @@ TEST_P(Test_Model, Keypoints_face)
bool swapRB = false;
// Ref. Range: [-1.1784188, 1.7758257]
float norm = 1e-4;
float norm = 2e-3;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CPU_FP16)
norm = 5e-3;
if (target == DNN_TARGET_MYRIAD)
+4 -4
View File
@@ -2432,7 +2432,7 @@ TEST_P(Test_ONNX_nets, RAFT)
// and output 12006 is calculated from 12007 so checking 12007 is sufficient.
std::string ref_12700_path = _tf("data/output_optical_flow_estimation_raft_2023aug.npy");
auto ref0 = blobFromNPY(ref_12700_path);
normAssert(ref0, outs[0], "", 1e-5, 1.8e-4);
normAssert(ref0, outs[0], "", 1.5e-3, 3.2e-2);
}
TEST_P(Test_ONNX_nets, Squeezenet)
@@ -3503,9 +3503,9 @@ TEST_P(Test_ONNX_nets, VitTrack) {
auto ref_output2 = blobFromNPY(_tf("data/output_object_tracking_vittrack_2023sep_1.npy"));
auto ref_output3 = blobFromNPY(_tf("data/output_object_tracking_vittrack_2023sep_2.npy"));
normAssert(ref_output1, outputs[0], "VitTrack output1");
normAssert(ref_output2, outputs[1], "VitTrack output2");
normAssert(ref_output3, outputs[2], "VitTrack output3");
normAssert(ref_output1, outputs[0], "VitTrack output1", 3e-5, 3e-4);
normAssert(ref_output2, outputs[1], "VitTrack output2", 3e-5, 2e-4);
normAssert(ref_output3, outputs[2], "VitTrack output3", 3e-4, 9e-4);
}
TEST_P(Test_ONNX_layers, LayerNormNoFusion) {
+2 -6
View File
@@ -70,7 +70,7 @@ TEST(Test_TensorFlow, inception_accuracy)
Mat ref = blobFromNPY(_tf("tf_inception_prob.npy"));
normAssert(ref, out);
normAssert(ref, out, "", 5e-5, 0.02);
}
static std::string path(const std::string& file)
@@ -937,16 +937,12 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
net.setInput(inp);
Mat out = net.forward();
double scoreDiff = default_l1, iouDiff = default_lInf;
double scoreDiff = default_l1, iouDiff = 0.04;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
{
scoreDiff = 0.01;
iouDiff = 0.1;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
iouDiff = 0.04;
}
normAssertDetections(ref, out, "", 0.2, scoreDiff, iouDiff);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2019010000
+2 -2
View File
@@ -94,7 +94,7 @@ TEST_P(Test_TFLite, face_landmark)
{
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
double l1 = 2.2e-5, lInf = 2e-4;
double l1 = 0.066, lInf = 0.21;
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD ||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL))
{
@@ -120,7 +120,7 @@ TEST_P(Test_TFLite, face_detection_short_range)
// https://google.github.io/mediapipe/solutions/selfie_segmentation
TEST_P(Test_TFLite, selfie_segmentation)
{
double l1 = 0, lInf = 0;
double l1 = 0.002, lInf = 0.24;
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD ||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL))
{
+7 -3
View File
@@ -825,10 +825,12 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
if( (channels > 1) && ( sampling_factor != 0 ) )
{
cinfo.comp_info[0].v_samp_factor = (sampling_factor >> 16 ) & 0xF;
cinfo.comp_info[0].h_samp_factor = (sampling_factor >> 20 ) & 0xF;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[0].v_samp_factor = (sampling_factor >> 16 ) & 0xF;
cinfo.comp_info[1].h_samp_factor = (sampling_factor >> 12 ) & 0xF;
cinfo.comp_info[1].v_samp_factor = (sampling_factor >> 8 ) & 0xF;
cinfo.comp_info[2].h_samp_factor = (sampling_factor >> 4 ) & 0xF;
cinfo.comp_info[2].v_samp_factor = (sampling_factor >> 0 ) & 0xF;
}
if (luma_quality >= 0 && chroma_quality >= 0)
@@ -843,6 +845,8 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
cinfo.comp_info[0].h_samp_factor = 1;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[2].v_samp_factor = 1;
cinfo.comp_info[2].h_samp_factor = 1;
}
jpeg_default_qtables( &cinfo, TRUE );
#else
@@ -240,7 +240,7 @@ TEST(Imgproc_ConnectedComponents, missing_background_pixels)
TEST(Imgproc_ConnectedComponents, spaghetti_bbdt_sauf_stats)
{
cv::Mat1b img({16, 16}, {
cv::Mat1b img({16, 16}, { (unsigned char)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
@@ -361,8 +361,8 @@ TEST(Imgproc_ConnectedComponents, spaghetti_bbdt_sauf_stats)
TEST(Imgproc_ConnectedComponents, chessboard_even)
{
const auto size = {16, 16};
cv::Mat1b input(size, {
auto size = {16, 16};
cv::Mat1b input(size, { (unsigned char)
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
@@ -445,8 +445,8 @@ TEST(Imgproc_ConnectedComponents, chessboard_even)
TEST(Imgproc_ConnectedComponents, chessboard_odd)
{
const auto size = {15, 15};
cv::Mat1b input(size, {
auto size = {15, 15};
cv::Mat1b input(size, { (unsigned char)
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
@@ -526,8 +526,8 @@ TEST(Imgproc_ConnectedComponents, chessboard_odd)
TEST(Imgproc_ConnectedComponents, maxlabels_8conn_even)
{
const auto size = {16, 16};
cv::Mat1b input(size, {
auto size = {16, 16};
cv::Mat1b input(size, { (unsigned char)
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
@@ -607,8 +607,8 @@ TEST(Imgproc_ConnectedComponents, maxlabels_8conn_even)
TEST(Imgproc_ConnectedComponents, maxlabels_8conn_odd)
{
const auto size = {15, 15};
cv::Mat1b input(size, {
auto size = {15, 15};
cv::Mat1b input(size, { (unsigned char)
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
@@ -685,7 +685,7 @@ TEST(Imgproc_ConnectedComponents, maxlabels_8conn_odd)
TEST(Imgproc_ConnectedComponents, single_row)
{
const auto size = {1, 15};
auto size = {1, 15};
cv::Mat1b input(size, {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1});
cv::Mat1i output_8c(size, {1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8});
cv::Mat1i output_4c(size, {1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8});
@@ -715,8 +715,8 @@ TEST(Imgproc_ConnectedComponents, single_row)
TEST(Imgproc_ConnectedComponents, single_column)
{
const auto size = {15, 1};
cv::Mat1b input(size, {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1});
auto size = {15, 1};
cv::Mat1b input(size, {(unsigned char)1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1});
cv::Mat1i output_8c(size, {1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8});
cv::Mat1i output_4c(size, {1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8});
+1 -2
View File
@@ -3,7 +3,6 @@
import sys, re, os.path, errno, fnmatch
import json
import logging
import codecs
from shutil import copyfile
from pprint import pformat
from string import Template
@@ -601,7 +600,7 @@ class JavaWrapperGenerator(object):
content = f.read()
if content == buf:
return
with codecs.open(path, "w", "utf-8") as f:
with open(path, "w", encoding="utf-8") as f:
f.write(buf)
updated_files += 1
+2 -3
View File
@@ -4,7 +4,6 @@ from __future__ import print_function, unicode_literals
import sys, re, os.path, errno, fnmatch
import json
import logging
import codecs
import io
from shutil import copyfile
from pprint import pformat
@@ -903,7 +902,7 @@ class ObjectiveCWrapperGenerator(object):
content = f.read()
if content == buf:
return
with codecs.open(path, "w", "utf-8") as f:
with open(path, "w", encoding="utf-8") as f:
f.write(buf)
updated_files += 1
@@ -1531,7 +1530,7 @@ typedef NS_ENUM(int, {1}) {{
body = file.read()
body = body.replace("import OpenCV", "import " + framework_name)
body = body.replace("#import <OpenCV/OpenCV.h>", "#import <" + framework_name + "/" + framework_name + ".h>")
with codecs.open(filepath, "w", "utf-8") as file:
with open(filepath, "w", encoding="utf-8") as file:
file.write(body)
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

@@ -78,6 +78,65 @@
@sa @cite Aruco2014
This code has been originally developed by Sergio Garrido-Jurado as a project
for Google Summer of Code 2015 (GSoC 15).
<br>
@warning In OpenCV, the order of the returned corners locations for the AprilTag family is not aligned with the ArUco one.\n
Note that this order is also different from the convention adopted by the official [AprilTag library](https://github.com/AprilRobotics/apriltag/).
![](pics/AprilTag_corners_comparison_opencv_april.png) { width=80% }
<br>
An overview of the supported ArUco markers family is visible in the following image:
![](pics/ArUco_family.png) { width=80% }
<br>
An overview of the supported AprilTag markers family is visible in the following image:
![](pics/AprilTag_family.png) { width=80% }
@note The generated images (in the above picture) using @ref aruco::generateImageMarker for the AprilTag markers have been
rotated by 180 degree in order to match the official AprilTag images.
When using the @ref aruco::generateImageMarker function, it will output by default a different image from the official AprilTag convention,
see the [AprilRobotics/apriltag-imgs](https://github.com/AprilRobotics/apriltag-imgs) repository.
This is the reason why you see a different corners order between ArUco and AprilTag in the above image.
<br>
For the ArUco marker family, the recommended family is the DICT_ARUCO_MIP_36h12 one, [see](https://stackoverflow.com/a/51511558).
In general, a smaller marker family (e.g. `4x4` vs `6x6`) should give you a better detection rate with respect to the camera distance,
at the expense of having more probability to have issues with false detection or marker id decoding error.
The number of marker ids in a family is also something to take into account with respect to the application use case and the ability
to correct wrong bits during the marker id decoding process.
You can download some pregenerated MIP_36h12 ArUco marker images from:
- https://sourceforge.net/projects/aruco/files/
- or use the `samples/cpp/tutorial_code/objectDetection/create_marker.cpp` sample to generate the marker image for your
desired marker family (which uses the @ref aruco::generateImageMarker function)
For the AprilTag family, you can find some pregenerated marker images in the
[AprilRobotics/apriltag-imgs](https://github.com/AprilRobotics/apriltag-imgs) repository.
@note For accurate corners location extraction, a white border (to have a strong gradient between white and black transition) around the marker is important.
This is necessary to precisely extract the marker contour in difficult conditions such as bad illumination, confusing color background, etc.
<br>
There are multiple parameters which can be tweaked to improve the marker detection rate or to be adapted to your use case (e.g. image resolution).
Please refer to the:
- @ref aruco::DetectorParameters
- "Detector Parameters" section in the @ref tutorial_aruco_detection tutorial or in the @ref tutorial_aruco_faq page
- [ArUco Library Documentation](https://drive.google.com/file/d/1OiavRVYVJ-WH88sQg1LUsh8CuJZUQyrX) for additional information from the ArUco library
The corner refinement method can be changed according to the @ref aruco::CornerRefineMethod to improve the corners location accuracy
at the expense of more computation time.
<br>
To estimate the marker pose with respect to the camera frame, we recommend you to look at the following sources of information:
- @ref tutorial_aruco_detection for a tutorial about ArUco markers detection
- @ref calib for some theoretical background about the pinhole camera model and the @ref calib3d_solvePnP page
- @ref solvePnP, @ref solvePnPGeneric, @ref solveP3P for the relevant pose estimation methods
@}
@}
+1 -1
View File
@@ -161,7 +161,7 @@ public:
inline void put_bits(unsigned bits, int len)
{
CV_Assert(len >=0 && len < 32);
if((m_pos == (data.size() - 1) && len > bits_free) || m_pos == data.size())
if((m_pos == (data.size() - 1) && len >= bits_free) || m_pos == data.size())
{
resize(int(2*data.size()));
}
+17
View File
@@ -1278,4 +1278,21 @@ VideoCaptureAPIs seekable_backeinds[] = {CAP_FFMPEG, CAP_MSMF, CAP_AVFOUNDATION}
INSTANTIATE_TEST_CASE_P(videoio, PreciseSeekingTest, testing::ValuesIn(seekable_backeinds), safe_capture_name_printer);
// Regression test for heap-buffer-overflow in mjpeg_buffer::put_bits (GitHub issue #29112).
// When len == bits_free the old guard used strict '>' and skipped the resize, causing
// an out-of-bounds write after '++m_pos' advanced past data.size().
TEST(Videoio_MJPEG, put_bits_no_heap_overflow)
{
const std::string filename = cv::tempfile(".avi");
cv::Mat frame(1, 1, CV_8UC1, cv::Scalar::all(255));
int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
{
cv::VideoWriter writer;
ASSERT_NO_THROW(writer.open(filename, CAP_OPENCV_MJPEG, fourcc, 25.0, cv::Size(1, 1), false));
ASSERT_TRUE(writer.isOpened());
EXPECT_NO_THROW(writer.write(frame));
}
remove(filename.c_str());
}
} // namespace
+5 -5
View File
@@ -32,7 +32,7 @@ Adding --dynamic parameter will build {framework_name}.framework as App Store dy
"""
from __future__ import print_function, unicode_literals
import glob, os, os.path, shutil, string, sys, argparse, traceback, multiprocessing, codecs, io
import glob, os, os.path, shutil, string, sys, argparse, traceback, multiprocessing, io
from subprocess import check_call, check_output, CalledProcessError
if sys.version_info >= (3, 8): # Python 3.8+
@@ -190,7 +190,7 @@ class Builder:
body = body[:insert_pos] + "import " + self.framework_name + "\n" + body[insert_pos:]
else:
body = "import " + self.framework_name + "\n\n" + body
with codecs.open(os.path.join(swift_sources_dir, file), "w", "utf-8") as file_out:
with open(os.path.join(swift_sources_dir, file), "w", encoding="utf-8") as file_out:
file_out.write(body)
def build(self, outdir):
@@ -380,7 +380,7 @@ class Builder:
framework = self.framework_name,
hosting_base_path = self.hosting_base_path
)
with codecs.open(os.path.join(docs_dir, "HOWTO.md"), "w", "utf-8") as file:
with open(os.path.join(docs_dir, "HOWTO.md"), "w", encoding="utf-8") as file:
file.write(howto)
self.docs_built = True
execute(["cmake", "-DBUILD_TYPE=%s" % self.getConfiguration(), "-DCMAKE_INSTALL_PREFIX=%s" % (builddir + "/install"), "-P", "cmake_install.cmake"], cwd = framework_build_dir)
@@ -473,11 +473,11 @@ class Builder:
for dirname, dirs, files in os.walk(os.path.join(dstdir, "Headers")):
for filename in files:
filepath = os.path.join(dirname, filename)
with codecs.open(filepath, "r", "utf-8") as file:
with open(filepath, "r", encoding="utf-8") as file:
body = file.read()
body = body.replace("include \"opencv2/", "include \"" + name + "/")
body = body.replace("include <opencv2/", "include <" + name + "/")
with codecs.open(filepath, "w", "utf-8") as file:
with open(filepath, "w", encoding="utf-8") as file:
file.write(body)
if self.build_objc_wrapper:
copy_tree(os.path.join(builddirs[0], "install", "lib", name + ".framework", "Headers"), os.path.join(dstdir, "Headers"))
+5 -3
View File
@@ -260,7 +260,7 @@ const char* keys =
"DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50,"
"DICT_7X7_100, DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL,"
"DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10,"
"DICT_APRILTAG_36h11}"
"DICT_APRILTAG_36h11, DICT_ARUCO_MIP_36h12}"
"{nMarkers | | Number of markers in the dictionary }"
"{markerSize | | Marker size }"
"{cd | | Input file with custom dictionary }";
@@ -309,6 +309,7 @@ int main(int argc, char *argv[])
else if (arucoDictName == "DICT_APRILTAG_25h9") { arucoDict = cv::aruco::DICT_APRILTAG_25h9; }
else if (arucoDictName == "DICT_APRILTAG_36h10") { arucoDict = cv::aruco::DICT_APRILTAG_36h10; }
else if (arucoDictName == "DICT_APRILTAG_36h11") { arucoDict = cv::aruco::DICT_APRILTAG_36h11; }
else if (arucoDictName == "DICT_ARUCO_MIP_36h12") { arucoDict = cv::aruco::DICT_ARUCO_MIP_36h12; }
else {
cout << "incorrect name of aruco dictionary \n";
return 1;
@@ -328,13 +329,14 @@ int main(int argc, char *argv[])
cerr << "Dictionary not specified" << endl;
return 0;
}
if (!outputFile.empty() && nMarkers > 0 && markerSize > 0)
{
FileStorage fs(outputFile, FileStorage::WRITE);
if (checkFlippedMarkers)
dictionary = generateCustomAsymmetricDictionary(nMarkers, markerSize, aruco::Dictionary(), 0);
dictionary = generateCustomAsymmetricDictionary(nMarkers, markerSize, dictionary, 0);
else
dictionary = aruco::extendDictionary(nMarkers, markerSize, aruco::Dictionary(), 0);
dictionary = aruco::extendDictionary(nMarkers, markerSize, dictionary, 0);
dictionary.writeDictionary(fs);
}
+2 -1
View File
@@ -67,7 +67,7 @@ static void help(char** argv)
"DICT_4X4_1000, DICT_5X5_50, DICT_5X5_100, DICT_5X5_250, DICT_5X5_1000, "
"DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50, "
"DICT_7X7_100, DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL, "
"DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11\n"
"DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11, DICT_ARUCO_MIP_36h12\n"
" [-adf=<dictFilename>] # Custom aruco dictionary file for ChArUco board\n"
" [-o=<out_camera_params>] # the output filename for intrinsic [and extrinsic] parameters\n"
" [-op] # write detected feature points\n"
@@ -459,6 +459,7 @@ int main( int argc, char** argv )
else if (arucoDictName == "DICT_APRILTAG_25h9") { arucoDict = cv::aruco::DICT_APRILTAG_25h9; }
else if (arucoDictName == "DICT_APRILTAG_36h10") { arucoDict = cv::aruco::DICT_APRILTAG_36h10; }
else if (arucoDictName == "DICT_APRILTAG_36h11") { arucoDict = cv::aruco::DICT_APRILTAG_36h11; }
else if (arucoDictName == "DICT_ARUCO_MIP_36h12") { arucoDict = cv::aruco::DICT_ARUCO_MIP_36h12; }
else {
cout << "Incorrect Aruco dictionary name " << arucoDictName << std::endl;
return 1;
+2 -1
View File
@@ -60,7 +60,7 @@ static int print_help(char** argv)
<< "DICT_4X4_1000, DICT_5X5_50, DICT_5X5_100, DICT_5X5_250, DICT_5X5_1000, "
<< "DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50, "
<< "DICT_7X7_100, DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL, "
<< "DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11\n";
<< "DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11, DICT_ARUCO_MIP_36h12\n";
return 0;
}
@@ -437,6 +437,7 @@ int main(int argc, char** argv)
else if (arucoDictName == "DICT_APRILTAG_25h9") { arucoDict = cv::aruco::DICT_APRILTAG_25h9; }
else if (arucoDictName == "DICT_APRILTAG_36h10") { arucoDict = cv::aruco::DICT_APRILTAG_36h10; }
else if (arucoDictName == "DICT_APRILTAG_36h11") { arucoDict = cv::aruco::DICT_APRILTAG_36h11; }
else if (arucoDictName == "DICT_ARUCO_MIP_36h12") { arucoDict = cv::aruco::DICT_ARUCO_MIP_36h12; }
else {
cout << "incorrect name of aruco dictionary \n";
return 1;
@@ -340,6 +340,7 @@ int main(int argc, char* argv[])
else if (s.arucoDictName == "DICT_APRILTAG_25h9") { arucoDict = cv::aruco::DICT_APRILTAG_25h9; }
else if (s.arucoDictName == "DICT_APRILTAG_36h10") { arucoDict = cv::aruco::DICT_APRILTAG_36h10; }
else if (s.arucoDictName == "DICT_APRILTAG_36h11") { arucoDict = cv::aruco::DICT_APRILTAG_36h11; }
else if (s.arucoDictName == "DICT_ARUCO_MIP_36h12") { arucoDict = cv::aruco::DICT_ARUCO_MIP_36h12; }
else {
cout << "incorrect name of aruco dictionary \n";
return 1;
@@ -25,7 +25,8 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{@outfile |cam.yml| Output file with calibrated camera parameters }"
"{v | | Input from video file, if ommited, input comes from camera }"
@@ -23,7 +23,8 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{@outfile |cam.yml| Output file with calibrated camera parameters }"
"{v | | Input from video file, if ommited, input comes from camera }"
@@ -16,7 +16,8 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{m | | Margins size (in pixels). Default is marker separation (-s) }"
"{bb | 1 | Number of bits in marker borders }"
@@ -17,7 +17,8 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{m | | Margins size (in pixels). Default is (squareLength-markerLength) }"
"{bb | 1 | Number of bits in marker borders }"
@@ -17,7 +17,8 @@ const char* keys =
"{d | 10 | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{ids |0, 1, 2, 3 | Four ids for the ChArUco marker: id1,id2,id3,id4 }"
"{m | 0 | Margins size (in pixels) }"
"{bb | 1 | Number of bits in marker borders }"
@@ -6,7 +6,7 @@
using namespace cv;
namespace {
const char* about = "Create an ArUco marker image";
const char* about = "Create an ArUco/AprilTag marker image";
//! [aruco_create_markers_keys]
const char* keys =
@@ -14,7 +14,8 @@ const char* keys =
"{d | 0 | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{id | 0 | Marker id in the dictionary }"
"{ms | 200 | Marker size in pixels }"
@@ -19,7 +19,8 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{c | | Output file with calibrated camera parameters }"
"{v | | Input from video or image file, if omitted, input comes from camera }"
@@ -19,7 +19,8 @@ const char* keys =
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{c | | Output file with calibrated camera parameters }"
"{v | | Input from video or image file, if ommited, input comes from camera }"
@@ -16,7 +16,8 @@ const char* keys =
"{d | 10 | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{c | | Output file with calibrated camera parameters }"
"{as | | Automatic scale. The provided number is multiplied by the last"
@@ -15,7 +15,7 @@ const char* keys =
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20}"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}"
"{cd | | Input file with custom dictionary }"
"{v | | Input from video or image file, if ommited, input comes from camera }"
"{ci | 0 | Camera id if input doesnt come from video (-v) }"
+2 -1
View File
@@ -36,7 +36,8 @@ def main():
parser.add_argument("-d", help="dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2, DICT_4X4_1000=3,"
"DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, DICT_6X6_50=8,"
"DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12, DICT_7X7_100=13,"
"DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}",
"DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL=16,"
"DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36h12=21}",
default="0", action="store", dest="d", type=int)
parser.add_argument("-ci", help="Camera id if input doesnt come from video (-v)", default="0", action="store",
dest="ci", type=int)
+2 -1
View File
@@ -100,7 +100,8 @@ def main():
'DICT_APRILTAG_16h5': cv.aruco.DICT_APRILTAG_16h5,
'DICT_APRILTAG_25h9': cv.aruco.DICT_APRILTAG_25h9,
'DICT_APRILTAG_36h10': cv.aruco.DICT_APRILTAG_36h10,
'DICT_APRILTAG_36h11': cv.aruco.DICT_APRILTAG_36h11
'DICT_APRILTAG_36h11': cv.aruco.DICT_APRILTAG_36h11,
'DICT_ARUCO_MIP_36h12': cv.aruco.DICT_ARUCO_MIP_36h12
}
if (aruco_dict_name not in set(aruco_dicts.keys())):