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

Merge branch 4.x

This commit is contained in:
Alexander Alekhin
2023-01-09 11:08:02 +00:00
880 changed files with 83958 additions and 9368 deletions
+5 -5
View File
@@ -55,17 +55,17 @@ Algorithm::~Algorithm()
CV_TRACE_FUNCTION();
}
void Algorithm::write(const Ptr<FileStorage>& fs, const String& name) const
void Algorithm::write(FileStorage& fs, const String& name) const
{
CV_TRACE_FUNCTION();
if(name.empty())
{
write(*fs);
write(fs);
return;
}
*fs << name << "{";
write(*fs);
*fs << "}";
fs << name << "{";
write(fs);
fs << "}";
}
void Algorithm::save(const String& filename) const
+2 -2
View File
@@ -168,7 +168,7 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst,
if( dims1 <= 2 && dims2 <= 2 && kind1 == kind2 && sz1 == sz2 && type1 == type2 && !haveMask )
{
_dst.create(sz1, type1);
_dst.createSameSize(*psrc1, type1);
CV_OCL_RUN(use_opencl,
ocl_binary_op(*psrc1, *psrc2, _dst, _mask, bitwise, oclop, false))
@@ -1225,7 +1225,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 && src1.size() == src2.size() && src1.type() == src2.type() )
{
int cn = src1.channels();
_dst.create(src1.size(), CV_8UC(cn));
_dst.createSameSize(src1, CV_8UC(cn));
Mat dst = _dst.getMat();
Size sz = getContinuousSize2D(src1, src2, dst, src1.channels());
BinaryFuncC cmpFn = getCmpFunc(depth1);
+20
View File
@@ -97,6 +97,10 @@ void check_failed_MatChannels(const int v1, const int v2, const CheckContext& ct
{
check_failed_auto_<int>(v1, v2, ctx);
}
void check_failed_auto(const bool v1, const bool v2, const CheckContext& ctx)
{
check_failed_auto_<bool>(v1, v2, ctx);
}
void check_failed_auto(const int v1, const int v2, const CheckContext& ctx)
{
check_failed_auto_<int>(v1, v2, ctx);
@@ -151,6 +155,22 @@ void check_failed_MatChannels(const int v, const CheckContext& ctx)
{
check_failed_auto_<int>(v, ctx);
}
void check_failed_true(const bool v, const CheckContext& ctx)
{
CV_UNUSED(v);
std::stringstream ss;
ss << ctx.message << ":" << std::endl
<< " '" << ctx.p1_str << "' must be 'true'";
cv::error(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_false(const bool v, const CheckContext& ctx)
{
CV_UNUSED(v);
std::stringstream ss;
ss << ctx.message << ":" << std::endl
<< " '" << ctx.p1_str << "' must be 'false'";
cv::error(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_auto(const int v, const CheckContext& ctx)
{
check_failed_auto_<int>(v, ctx);
+5 -1
View File
@@ -251,6 +251,11 @@ lapack_SVD(fptype* a, size_t a_step, fptype *w, fptype* u, size_t u_step, fptype
lwork = (int)round(work1); //optimal buffer size
std::vector<fptype> buffer(lwork + 1);
// Make sure MSAN sees the memory as having been written.
// MSAN does not think it has been written because a different language is called.
// Note: we do this here because if dgesdd is C++, MSAN errors can be reported within it.
CV_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, sizeof(fptype) * (lwork + 1));
if(typeid(fptype) == typeid(float))
OCV_LAPACK_FUNC(sgesdd)(mode, &m, &n, (float*)a, &lda, (float*)w, (float*)u, &ldu,
(float*)vt, &ldv, (float*)&buffer[0], &lwork, &iworkBuf[0], info);
@@ -261,7 +266,6 @@ lapack_SVD(fptype* a, size_t a_step, fptype *w, fptype* u, size_t u_step, fptype
// Make sure MSAN sees the memory as having been written.
// MSAN does not think it has been written because a different language was called.
CV_ANNOTATE_MEMORY_IS_INITIALIZED(a, a_step * n);
CV_ANNOTATE_MEMORY_IS_INITIALIZED(buffer, sizeof(fptype) * (lwork + 1));
if (u)
CV_ANNOTATE_MEMORY_IS_INITIALIZED(u, u_step * m);
if (vt)
+25 -7
View File
@@ -233,24 +233,42 @@ void writeLogMessage(LogLevel logLevel, const char* message)
(*out) << std::flush;
}
static const char* stripSourceFilePathPrefix(const char* file)
{
CV_Assert(file);
const char* pos = file;
const char* strip_pos = NULL;
char ch = 0;
while ((ch = pos[0]) != 0)
{
++pos;
if (ch == '/' || ch == '\\')
strip_pos = pos;
}
if (strip_pos == NULL || strip_pos == pos/*eos*/)
return file;
return strip_pos;
}
void writeLogMessageEx(LogLevel logLevel, const char* tag, const char* file, int line, const char* func, const char* message)
{
std::ostringstream strm;
if (tag)
{
strm << tag << " ";
strm << tag << ' ';
}
if (file)
{
strm << file << " ";
}
if (line > 0)
{
strm << "(" << line << ") ";
strm << stripSourceFilePathPrefix(file);
if (line > 0)
{
strm << ':' << line;
}
strm << ' ';
}
if (func)
{
strm << func << " ";
strm << func << ' ';
}
strm << message;
writeLogMessage(logLevel, strm.str().c_str());
+45
View File
@@ -6,6 +6,8 @@
#include "opencl_kernels_core.hpp"
#include "opencv2/core/detail/dispatch_helper.impl.hpp"
#include <algorithm> // std::swap_ranges
namespace cv {
////////////////////////////////////// transpose /////////////////////////////////////////
@@ -812,6 +814,49 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode )
flipHoriz( dst.ptr(), dst.step, dst.ptr(), dst.step, dst.size(), esz );
}
static void
flipNDImpl(uchar* data, const int* shape, const size_t* step, int axis)
{
int total = 1;
for (int i = 0; i < axis; ++i)
total *= shape[i];
int shape_at_axis = shape[axis];
size_t step_at_axis = step[axis];
size_t offset = 0;
size_t offset_increment = axis == 0 ? 0 : step[axis - 1];
for (int i = 0; i < total; ++i, offset += offset_increment)
for (int j = 0, k = shape_at_axis - 1; j < shape_at_axis / 2; ++j, --k)
std::swap_ranges(data + offset + j * step_at_axis,
data + offset + j * step_at_axis + step_at_axis,
data + offset + k * step_at_axis);
}
void flipND(InputArray _src, OutputArray _dst, int _axis)
{
CV_INSTRUMENT_REGION();
Mat src = _src.getMat();
// verify axis
int ndim = src.dims;
CV_CheckLT(_axis, ndim, "flipND: given axis is out of range");
CV_CheckGE(_axis, -ndim, "flipND: given axis is out of range");
int axis = (_axis + ndim) % ndim;
// in-place flip
_src.copyTo(_dst);
// return the src if it has only one element on the flip axis
const auto shape = src.size.p;
if (shape[axis] == 1)
return ;
// call impl
Mat dst = _dst.getMat();
flipNDImpl(dst.ptr(), dst.size.p, dst.step.p, axis);
}
void rotate(InputArray _src, OutputArray _dst, int rotateMode)
{
CV_Assert(_src.dims() <= 2);
+20 -3
View File
@@ -976,6 +976,12 @@ bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* minLoc
return false;
#endif
if (dev.deviceVersionMajor() == 1 && dev.deviceVersionMinor() < 2)
{
// 'static' storage class specifier used by "minmaxloc" is available from OpenCL 1.2+ only
return false;
}
bool doubleSupport = dev.doubleFPConfig() > 0, haveMask = !_mask.empty(),
haveSrc2 = _src2.kind() != _InputArray::NONE;
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type),
@@ -1565,13 +1571,24 @@ void cv::minMaxLoc( InputArray _img, double* minVal, double* maxVal,
{
CV_INSTRUMENT_REGION();
CV_Assert(_img.dims() <= 2);
int dims = _img.dims();
CV_CheckLE(dims, 2, "");
minMaxIdx(_img, minVal, maxVal, (int*)minLoc, (int*)maxLoc, mask);
if( minLoc )
std::swap(minLoc->x, minLoc->y);
{
if (dims == 2)
std::swap(minLoc->x, minLoc->y);
else
minLoc->y = 0;
}
if( maxLoc )
std::swap(maxLoc->x, maxLoc->y);
{
if (dims == 2)
std::swap(maxLoc->x, maxLoc->y);
else
maxLoc->y = 0;
}
}
enum class ReduceMode
+20 -20
View File
@@ -1638,14 +1638,14 @@ Context& initializeContextFromGL()
cl_uint numPlatforms;
cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status));
if (numPlatforms == 0)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
std::vector<cl_platform_id> platforms(numPlatforms);
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status));
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
@@ -1667,7 +1667,7 @@ Context& initializeContextFromGL()
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, extensionSize, (char*)extensionStr.data(), NULL);
}
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platform extension string");
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform extension string: %d", status));
if (!strstr((const char*)extensionStr.data(), "cl_khr_gl_sharing"))
continue;
@@ -1759,31 +1759,31 @@ void convertToGLTexture2D(InputArray src, Texture2D& texture)
cl_int status = 0;
cl_mem clImage = clCreateFromGLTexture(context, CL_MEM_WRITE_ONLY, gl::TEXTURE_2D, 0, texture.texId(), &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromGLTexture failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clCreateFromGLTexture failed: %d", status));
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
status = clEnqueueAcquireGLObjects(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireGLObjects failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueAcquireGLObjects failed: %d", status));
size_t offset = 0; // TODO
size_t dst_origin[3] = {0, 0, 0};
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1};
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueCopyBufferToImage failed: %d", status));
status = clEnqueueReleaseGLObjects(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseGLObjects failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueReleaseGLObjects failed: %d", status));
status = clFinish(q); // TODO Use events
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clFinish failed: %d", status));
status = clReleaseMemObject(clImage); // TODO RAII
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMemObject failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clReleaseMemObject failed: %d", status));
#endif
}
@@ -1821,31 +1821,31 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
cl_int status = 0;
cl_mem clImage = clCreateFromGLTexture(context, CL_MEM_READ_ONLY, gl::TEXTURE_2D, 0, texture.texId(), &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromGLTexture failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clCreateFromGLTexture failed: %d", status));
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
status = clEnqueueAcquireGLObjects(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireGLObjects failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueAcquireGLObjects failed: %d", status));
size_t offset = 0; // TODO
size_t src_origin[3] = {0, 0, 0};
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1};
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueCopyImageToBuffer failed: %d", status));
status = clEnqueueReleaseGLObjects(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseGLObjects failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueReleaseGLObjects failed: %d", status));
status = clFinish(q); // TODO Use events
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clFinish failed: %d", status));
status = clReleaseMemObject(clImage); // TODO RAII
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMemObject failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clReleaseMemObject failed: %d", status));
#endif
}
@@ -1883,13 +1883,13 @@ UMat mapGLBuffer(const Buffer& buffer, AccessFlag accessFlags)
cl_int status = 0;
cl_mem clBuffer = clCreateFromGLBuffer(context, clAccessFlags, buffer.bufId(), &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromGLBuffer failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clCreateFromGLBuffer failed: %d", status));
gl::Finish();
status = clEnqueueAcquireGLObjects(clQueue, 1, &clBuffer, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireGLObjects failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueAcquireGLObjects failed: %d", status));
size_t step = buffer.cols() * buffer.elemSize();
int rows = buffer.rows();
@@ -1921,15 +1921,15 @@ void unmapGLBuffer(UMat& u)
cl_int status = clEnqueueReleaseGLObjects(clQueue, 1, &clBuffer, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseGLObjects failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clEnqueueReleaseGLObjects failed: %d", status));
status = clFinish(clQueue);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clFinish failed: %d", status));
status = clReleaseMemObject(clBuffer);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMemObject failed");
CV_Error_(cv::Error::OpenCLApiCallError, ("OpenCL: clReleaseMemObject failed: %d", status));
#endif
}
@@ -43,7 +43,7 @@ std::vector<ParallelBackendInfo>& getBuiltinParallelBackendsInfo()
#endif
};
return g_backends;
};
}
static
bool sortByPriority(const ParallelBackendInfo &lhs, const ParallelBackendInfo &rhs)
+5 -1
View File
@@ -40,11 +40,13 @@ DECLARE_CV_PAUSE
#endif
#ifndef CV_PAUSE
# if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
# include <x86intrin.h> /* for __rdtsc */
# if !defined(__SSE2__)
static inline void cv_non_sse_mm_pause() { __asm__ __volatile__ ("rep; nop"); }
# define _mm_pause cv_non_sse_mm_pause
# endif
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { _mm_pause(); } } while (0)
// With Skylake CPUs and above, _mm_pause takes 140 cycles so no need for a loop.
# define CV_PAUSE(v) do { (void)v; _mm_pause(); } while (0)
# elif defined __GNUC__ && defined __aarch64__
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("yield" ::: "memory"); } } while (0)
# elif defined __GNUC__ && defined __arm__
@@ -59,6 +61,8 @@ DECLARE_CV_PAUSE
// https://github.com/riscv/riscv-isa-manual/issues/43
// # define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("pause"); } } while (0)
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("nop"); } } while (0)
# elif defined __GNUC__ && defined __loongarch__
# define CV_PAUSE(v) do { for (int __delay = (v); __delay > 0; --__delay) { asm volatile("nop"); } } while (0)
# else
# warning "Can't detect 'pause' (CPU-yield) instruction on the target platform. Specify CV_PAUSE() definition via compiler flags."
# define CV_PAUSE(...) do { /* no-op: works, but not effective */ } while (0)
+6
View File
@@ -434,6 +434,8 @@ struct HWFeatures
g_hwFeatureNames[CPU_AVX512_ICL] = "AVX512-ICL";
g_hwFeatureNames[CPU_RVV] = "RVV";
g_hwFeatureNames[CPU_LASX] = "LASX";
}
void initialize(void)
@@ -689,6 +691,10 @@ struct HWFeatures
have[CV_CPU_RVV] = true;
#endif
#if defined __loongarch_asx
have[CV_CPU_LASX] = true;
#endif
bool skip_baseline_check = false;
#ifndef NO_GETENV
if (getenv("OPENCV_SKIP_CPU_BASELINE_CHECK"))