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 Smorkalov
2026-05-19 16:23:55 +03:00
160 changed files with 9385 additions and 2093 deletions
+7 -1
View File
@@ -697,7 +697,7 @@ __CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType)
#endif
/****************************************************************************************\
* Thread sanitizer *
* Sanitizers *
\****************************************************************************************/
#ifndef CV_THREAD_SANITIZER
# if defined(__has_feature)
@@ -707,6 +707,12 @@ __CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType)
# endif
#endif
#if defined(__clang__) || defined(__GNUC__)
#define CV_DISABLE_UBSAN __attribute__((no_sanitize("undefined")))
#else
#define CV_DISABLE_UBSAN
#endif
/****************************************************************************************\
* exchange-add operation for atomic operations on reference counters *
\****************************************************************************************/
@@ -361,6 +361,7 @@ CV_INLINE int cvRound( int value )
}
/** @overload */
CV_DISABLE_UBSAN
CV_INLINE int cvFloor( float value )
{
#if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
+9 -2
View File
@@ -680,6 +680,13 @@ public:
double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
Mat R = (Mat_<double>(2,2) << a, -b, b, a);
\endcode
\deprecated Use constructors with std::initializer_list instead:
\code
Mat_<int> m1({1, 2, 3, 4}); // 4x1 Mat
Mat_<uchar> m2({2, 3}, {1, 2, 3, 4, 5, 6}); // 2x3 Mat
Mat_<double> R({2, 2}, {a, -b, b, a}); // from example
*/
template<typename _Tp> class MatCommaInitializer_
{
@@ -1261,7 +1268,7 @@ public:
/** @overload
*/
template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
template<typename _Tp> CV_DEPRECATED_EXTERNAL explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
//! download data from GpuMat
explicit Mat(const cuda::GpuMat& m);
@@ -2618,7 +2625,7 @@ public:
template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
CV_DEPRECATED_EXTERNAL explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
Mat_(std::initializer_list<_Tp> values);
explicit Mat_(const std::initializer_list<int> sizes, const std::initializer_list<_Tp> values);
@@ -3207,7 +3207,7 @@ MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
}
template<typename _Tp, typename T2> static inline
template<typename _Tp, typename T2> CV_DEPRECATED_EXTERNAL static inline
MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
{
MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
@@ -115,7 +115,7 @@ public:
int idx;
};
template<typename _Tp, typename _T2, int m, int n> static inline
template<typename _Tp, typename _T2, int m, int n> CV_DEPRECATED_EXTERNAL static inline
MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
{
MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
@@ -738,7 +738,7 @@ public:
Vec<_Tp, m> operator *() const;
};
template<typename _Tp, typename _T2, int cn> static inline
template<typename _Tp, typename _T2, int cn> CV_DEPRECATED_EXTERNAL static inline
VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
{
VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
@@ -307,8 +307,12 @@ public:
before opening the file.
@param filename Name of the file to open or the text string to read the data from.
Extension of the file (.xml, .yml/.yaml or .json) determines its format (XML, YAML or JSON
respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz.
You can also specify a compression level from 0 to 9 by appending it to the extension
(e.g. ".gz0" for no compression, ".gz9" for high compression).
The last digit will be truncated internally to write/read.
(e.g. If "a.xml.gz9" is specified, "a.xml.gz" is used for the actual file name.)
If both FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters.
You can use this format, "*?base64" (e.g. "file.json?base64" (case sensitive)), as an alternative to
FileStorage::BASE64 flag.
@@ -1245,6 +1245,26 @@ _Tp Point_<_Tp>::dot(const Point_& pt) const
return saturate_cast<_Tp>(x*pt.x + y*pt.y);
}
template<> inline
int Point_<int>::dot(const Point_<int>& pt) const
{
const int64_t xx = (int64_t)x * pt.x;
const int64_t yy = (int64_t)y * pt.y;
// detect int64 overflow before adding
if (yy > 0 && xx > INT64_MAX - yy)
{
return INT32_MAX;
}
if (yy < 0 && xx < INT64_MIN - yy)
{
return INT32_MIN;
}
const int64_t v = xx + yy;
return cv::saturate_cast<int>(v);
}
template<typename _Tp> inline
double Point_<_Tp>::ddot(const Point_& pt) const
{
@@ -1490,6 +1510,50 @@ _Tp Point3_<_Tp>::dot(const Point3_& pt) const
return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z);
}
template<> inline
int Point3_<int>::dot(const Point3_<int>& pt) const
{
const int64_t xx = (int64_t)x * pt.x;
const int64_t yy = (int64_t)y * pt.y;
const int64_t zz = (int64_t)z * pt.z;
// Sort the three products so that lo <= mid <= hi.
// We add in the order (lo + hi) first, then add mid.
// This minimizes the absolute value of the intermediate sum,
// reducing the chance of int64 overflow during addition.
int64_t lo = xx, mid = yy, hi = zz;
if (lo > mid) std::swap(lo, mid);
if (mid > hi) std::swap(mid, hi);
if (lo > mid) std::swap(lo, mid);
// Step 1: lo + hi
// If lo + hi overflows int64, the final result must saturate to INT32_MAX/INT32_MIN.
// The middle value (mid) cannot bring the result back into the int32 range,
// so we can return immediately without considering mid.
if (hi > 0 && lo > INT64_MAX - hi)
{
return INT32_MAX;
}
if (hi < 0 && lo < INT64_MIN - hi)
{
return INT32_MIN;
}
int64_t sum = lo + hi;
// Step 2: sum + mid
if (mid > 0 && sum > INT64_MAX - mid)
{
return INT32_MAX;
}
if (mid < 0 && sum < INT64_MIN - mid)
{
return INT32_MIN;
}
sum += mid;
return cv::saturate_cast<int>(sum);
}
template<typename _Tp> inline
double Point3_<_Tp>::ddot(const Point3_& pt) const
{
+33 -1
View File
@@ -102,11 +102,18 @@ template<typename _Tp, size_t fixed_size = 1024/sizeof(_Tp)+8> class AutoBuffer
{
public:
typedef _Tp value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef const _Tp* const_iterator;
typedef _Tp* iterator;
typedef const _Tp& const_reference;
typedef _Tp& reference;
//! the default constructor
AutoBuffer();
//! constructor taking the real buffer size
explicit AutoBuffer(size_t _size);
AutoBuffer(size_t _size, const _Tp& value);
//! the copy constructor
AutoBuffer(const AutoBuffer<_Tp, fixed_size>& buf);
@@ -140,7 +147,25 @@ public:
//! returns a reference to the element at specified location. No bounds checking is performed in Release builds.
inline const _Tp& operator[] (size_t i) const { CV_DbgCheckLT(i, sz, "out of range"); return ptr[i]; }
#endif
public:
inline iterator begin() { return data(); }
inline const_iterator begin() const { return data(); }
inline const_iterator cbegin() const { return begin(); }
inline iterator end() { return data()+size(); }
inline const_iterator end() const { return data()+size(); }
inline const_iterator cend() const { return end(); }
public:
inline bool empty() const { return !size(); }
inline void clear() {resize(0);}
inline const_reference front() const { return (*this)[0] ;}
inline reference front() { return (*this)[0] ;}
inline const_reference back() const { CV_DbgCheckGT(sz, (size_t)0, "out of range"); return (*this)[size()-1] ;}
inline reference back() { CV_DbgCheckGT(sz, (size_t)0, "out of range"); return (*this)[size()-1] ;}
public:
inline void push_back( const _Tp& value ) {resize(size()+1); back() = value;}
inline void push_back( _Tp&& value ) {resize(size()+1); back() = std::move(value);}
inline void emplace_back( _Tp&& value ) {push_back(value);}
inline void pop_back() {CV_DbgCheckGT(sz, (size_t)0, "out of range"); resize(size()-1);}
protected:
//! pointer to the real buffer, can point to buf if the buffer is small enough
_Tp* ptr;
@@ -1054,6 +1079,13 @@ AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
allocate(_size);
}
template<typename _Tp, size_t fixed_size> inline
AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size, const _Tp& value)
:AutoBuffer<_Tp, fixed_size>(_size)
{
std::fill(begin(), end(), value);
}
template<typename _Tp, size_t fixed_size> inline
AutoBuffer<_Tp, fixed_size>::AutoBuffer(const AutoBuffer<_Tp, fixed_size>& abuf )
{