Merge branch 4.x

This commit is contained in:
Alexander Smorkalov 2024-10-23 10:03:04 +03:00
commit 8e55659afe
66 changed files with 2346 additions and 937 deletions

View File

@ -1962,4 +1962,20 @@ inline int TEGRA_LKOpticalFlowLevel(const uchar *prev_data, size_t prev_data_ste
#define cv_hal_LKOpticalFlowLevel TEGRA_LKOpticalFlowLevel
#endif // __ARM_ARCH=7
#if 0 // OpenCV provides fater parallel implementation
inline int TEGRA_ScharrDeriv(const uchar* src_data, size_t src_step,
short* dst_data, size_t dst_step,
int width, int height, int cn)
{
if (!CAROTENE_NS::isSupportedConfiguration())
return CV_HAL_ERROR_NOT_IMPLEMENTED;
CAROTENE_NS::ScharrDeriv(CAROTENE_NS::Size2D(width, height), cn, src_data, src_step, dst_data, dst_step);
return CV_HAL_ERROR_OK;
}
#undef cv_hal_ScharrDeriv
#define cv_hal_ScharrDeriv TEGRA_ScharrDeriv
#endif
#endif

View File

@ -19,4 +19,8 @@
#include "version/hal_rvv_071.hpp"
#endif
#endif
#if defined(__riscv_v) && __riscv_v == 1000000
#include "hal_rvv_1p0/merge.hpp" // core
#endif
#endif

363
3rdparty/hal_rvv/hal_rvv_1p0/merge.hpp vendored Normal file
View File

@ -0,0 +1,363 @@
#ifndef OPENCV_HAL_RVV_MERGE_HPP_INCLUDED
#define OPENCV_HAL_RVV_MERGE_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_merge8u
#define cv_hal_merge8u cv::cv_hal_rvv::merge8u
#undef cv_hal_merge16u
#define cv_hal_merge16u cv::cv_hal_rvv::merge16u
#undef cv_hal_merge32s
#define cv_hal_merge32s cv::cv_hal_rvv::merge32s
#undef cv_hal_merge64s
#define cv_hal_merge64s cv::cv_hal_rvv::merge64s
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i = 0, j;
int vl = __riscv_vsetvlmax_e8m1();
if( k == 1 )
{
const uchar* src0 = src[0];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*2, a, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++)
dst[i*cn] = src0[i];
}
else if( k == 2 )
{
const uchar *src0 = src[0], *src1 = src[1];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*2, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*2, b, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[i*cn] = src0[i];
dst[i*cn+1] = src1[i];
}
}
else if( k == 3 )
{
const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
auto c = __riscv_vle8_v_u8m1(src2 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*3, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*3, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*3, c, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[i*cn] = src0[i];
dst[i*cn+1] = src1[i];
dst[i*cn+2] = src2[i];
}
}
else
{
const uchar *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
auto c = __riscv_vle8_v_u8m1(src2 + i, vl);
auto d = __riscv_vle8_v_u8m1(src3 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*4, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*4, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*4, c, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 3, sizeof(uchar)*4, d, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[i*cn] = src0[i];
dst[i*cn+1] = src1[i];
dst[i*cn+2] = src2[i];
dst[i*cn+3] = src3[i];
}
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; k < cn; k += 4 )
{
const uchar *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
}
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i = 0, j;
int vl = __riscv_vsetvlmax_e16m1();
if( k == 1 )
{
const ushort* src0 = src[0];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*2, a, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++)
dst[i*cn] = src0[i];
}
else if( k == 2 )
{
const ushort *src0 = src[0], *src1 = src[1];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*2, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*2, b, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[i*cn] = src0[i];
dst[i*cn+1] = src1[i];
}
}
else if( k == 3 )
{
const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
auto c = __riscv_vle16_v_u16m1(src2 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*3, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*3, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*3, c, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[i*cn] = src0[i];
dst[i*cn+1] = src1[i];
dst[i*cn+2] = src2[i];
}
}
else
{
const ushort *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
auto c = __riscv_vle16_v_u16m1(src2 + i, vl);
auto d = __riscv_vle16_v_u16m1(src3 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*4, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*4, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*4, c, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 3, sizeof(ushort)*4, d, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[i*cn] = src0[i];
dst[i*cn+1] = src1[i];
dst[i*cn+2] = src2[i];
dst[i*cn+3] = src3[i];
}
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; k < cn; k += 4 )
{
const uint16_t *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
}
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge32s(const int** src, int* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i, j;
if( k == 1 )
{
const int* src0 = src[0];
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( i = j = 0; i < len; i++, j += cn )
dst[j] = src0[i];
}
else if( k == 2 )
{
const int *src0 = src[0], *src1 = src[1];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
}
}
else if( k == 3 )
{
const int *src0 = src[0], *src1 = src[1], *src2 = src[2];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
dst[j+2] = src2[i];
}
}
else
{
const int *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; k < cn; k += 4 )
{
const int *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
}
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge64s(const int64** src, int64* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i, j;
if( k == 1 )
{
const int64* src0 = src[0];
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( i = j = 0; i < len; i++, j += cn )
dst[j] = src0[i];
}
else if( k == 2 )
{
const int64 *src0 = src[0], *src1 = src[1];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
}
}
else if( k == 3 )
{
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i];
dst[j+1] = src1[i];
dst[j+2] = src2[i];
}
}
else
{
const int64 *src0 = src[0], *src1 = src[1], *src2 = src[2], *src3 = src[3];
i = j = 0;
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; k < cn; k += 4 )
{
const int64 *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
}
}}
#endif

View File

@ -1,8 +1,8 @@
project(kleidicv_hal)
set(KLEIDICV_SOURCE_PATH "" CACHE PATH "Directory containing KleidiCV sources")
ocv_update(KLEIDICV_SRC_COMMIT "0.1.0")
ocv_update(KLEIDICV_SRC_HASH "9388f28cf2fbe3338197b2b57d491468")
ocv_update(KLEIDICV_SRC_COMMIT "0.2.0")
ocv_update(KLEIDICV_SRC_HASH "dabe522e8f55ac342d07a787391dab80")
if(KLEIDICV_SOURCE_PATH)
set(THE_ROOT "${KLEIDICV_SOURCE_PATH}")

View File

@ -52,6 +52,10 @@ if(POLICY CMP0056)
cmake_policy(SET CMP0056 NEW) # try_compile(): link flags
endif()
if(POLICY CMP0057)
cmake_policy(SET CMP0057 NEW) # CMake 3.3: if(IN_LIST) support
endif()
if(POLICY CMP0066)
cmake_policy(SET CMP0066 NEW) # CMake 3.7: try_compile(): use per-config flags, like CMAKE_CXX_FLAGS_RELEASE
endif()
@ -217,7 +221,7 @@ OCV_OPTION(WITH_1394 "Include IEEE1394 support" OFF
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O (iOS/visionOS/Mac)" ON
VISIBLE_IF APPLE
VERIFY HAVE_AVFOUNDATION)
OCV_OPTION(WITH_AVIF "Enable AVIF support" OFF
OCV_OPTION(WITH_AVIF "Enable AVIF support" ON
VERIFY HAVE_AVIF)
OCV_OPTION(WITH_CAP_IOS "Enable iOS video capture" ON
VISIBLE_IF IOS

View File

@ -353,23 +353,23 @@ function(ocv_target_include_directories target)
#ocv_debug_message("ocv_target_include_directories(${target} ${ARGN})")
_ocv_fix_target(target)
set(__params "")
if(CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND
";${ARGN};" MATCHES "/usr/include;")
return() # workaround for GCC 6.x bug
endif()
set(__params "")
set(__system_params "")
set(__var_name __params)
foreach(dir ${ARGN})
if("${dir}" STREQUAL "SYSTEM")
set(__var_name __system_params)
else()
get_filename_component(__abs_dir "${dir}" ABSOLUTE)
ocv_is_opencv_directory(__is_opencv_dir "${dir}")
if(__is_opencv_dir)
list(APPEND ${__var_name} "${__abs_dir}")
if(CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0" AND
dir MATCHES "/usr/include$")
# workaround for GCC 6.x bug
else()
list(APPEND ${__var_name} "${dir}")
get_filename_component(__abs_dir "${dir}" ABSOLUTE)
ocv_is_opencv_directory(__is_opencv_dir "${dir}")
if(__is_opencv_dir)
list(APPEND ${__var_name} "${__abs_dir}")
else()
list(APPEND ${__var_name} "${dir}")
endif()
endif()
endif()
endforeach()

View File

@ -4,9 +4,9 @@ Arithmetic Operations on Images {#tutorial_js_image_arithmetics}
Goal
----
- Learn several arithmetic operations on images like addition, subtraction, bitwise operations
- Learn several arithmetic operations on images like addition, subtraction, bitwise operations,
etc.
- You will learn these functions : **cv.add()**, **cv.subtract()** etc.
- You will learn these functions : **cv.add()**, **cv.subtract()**, etc.
Image Addition
--------------

View File

@ -72,12 +72,23 @@ function buttonsToAdd($elements, $heading, $type) {
}
function addTutorialsButtons() {
$("h1").each(function() {
var $elements = $(this).nextUntil("h1")
// See https://github.com/opencv/opencv/issues/26339
$lastHeader = undefined
$("h1,h2,h3,div.newInnerHTML").each(function() {
if( this.tagName.startsWith("H") ) {
$lastHeader = $(this)
return true // loop-continue
}
if( $lastHeader === undefined ) {
return true // loop-continue
}
var $toggleHeader = $lastHeader.tagName
var $elements = $lastHeader.nextUntil($toggleHeader)
var $lower = $elements.find("div.newInnerHTML")
$elements = $elements.add($lower)
$elements = $elements.filter("div.newInnerHTML")
buttonsToAdd($elements, $(this), "h1")
buttonsToAdd($elements, $lastHeader, $toggleHeader)
$lastHeader = undefined
});
$(".toggleable_button").first().click();
var $clickDefault = $('.toggleable_button.label_python').first();

View File

@ -1,4 +1,4 @@
File Input and Output using XML and YAML files {#tutorial_file_input_output_with_xml_yml}
File Input and Output using XML / YAML / JSON files {#tutorial_file_input_output_with_xml_yml}
==============================================
@tableofcontents
@ -14,12 +14,12 @@ File Input and Output using XML and YAML files {#tutorial_file_input_output_with
Goal
----
You'll find answers for the following questions:
You'll find answers to the following questions:
- How to print and read text entries to a file and OpenCV using YAML or XML files?
- How to do the same for OpenCV data structures?
- How to do this for your data structures?
- Usage of OpenCV data structures such as @ref cv::FileStorage , @ref cv::FileNode or @ref
- How do you print and read text entries to a file in OpenCV using YAML, XML, or JSON files?
- How can you perform the same operations for OpenCV data structures?
- How can this be done for your custom data structures?
- How do you use OpenCV data structures, such as @ref cv::FileStorage , @ref cv::FileNode or @ref
cv::FileNodeIterator .
Source code
@ -49,14 +49,14 @@ Here's a sample code of how to achieve all the stuff enumerated at the goal list
Explanation
-----------
Here we talk only about XML and YAML file inputs. Your output (and its respective input) file may
Here we talk only about XML, YAML and JSON file inputs. Your output (and its respective input) file may
have only one of these extensions and the structure coming from this. They are two kinds of data
structures you may serialize: *mappings* (like the STL map and the Python dictionary) and *element sequence* (like the STL
vector). The difference between these is that in a map every element has a unique name through what
you may access it. For sequences you need to go through them to query a specific item.
-# **XML/YAML File Open and Close.** Before you write any content to such file you need to open it
and at the end to close it. The XML/YAML data structure in OpenCV is @ref cv::FileStorage . To
-# **XML/YAML/JSON File Open and Close.** Before you write any content to such file you need to open it
and at the end to close it. The XML/YAML/JSON data structure in OpenCV is @ref cv::FileStorage . To
specify that this structure to which file binds on your hard drive you can use either its
constructor or the *open()* function of this:
@add_toggle_cpp

View File

@ -1,3 +1,10 @@
// Implementation of SQPnP as described in the paper:
//
// "A Consistently Fast and Globally Optimal Solution to the Perspective-n-Point Problem" by G. Terzakis and M. Lourakis
// a) Paper: https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123460460.pdf
// b) Supplementary: https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123460460-supp.pdf
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
@ -39,6 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "precomp.hpp"
#include "sqpnp.hpp"
#ifdef HAVE_EIGEN
#include <Eigen/Dense>
#endif
namespace cv {
namespace sqpnp {
@ -52,8 +63,8 @@ const double PoseSolver::POINT_VARIANCE_THRESHOLD = 1e-5;
const double PoseSolver::SQRT3 = std::sqrt(3);
const int PoseSolver::SQP_MAX_ITERATION = 15;
//No checking done here for overflow, since this is not public all call instances
//are assumed to be valid
// No checking done here for overflow, since this is not public all call instances
// are assumed to be valid
template <typename tp, int snrows, int sncols,
int dnrows, int dncols>
void set(int row, int col, cv::Matx<tp, dnrows, dncols>& dest,
@ -78,7 +89,7 @@ PoseSolver::PoseSolver()
void PoseSolver::solve(InputArray objectPoints, InputArray imagePoints, OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs)
{
//Input checking
// Input checking
int objType = objectPoints.getMat().type();
CV_CheckType(objType, objType == CV_32FC3 || objType == CV_64FC3,
"Type of objectPoints must be CV_32FC3 or CV_64FC3");
@ -158,12 +169,12 @@ void PoseSolver::computeOmega(InputArray objectPoints, InputArray imagePoints)
sum_img += img_pt;
sum_obj += obj_pt;
const double& x = img_pt.x, & y = img_pt.y;
const double& X = obj_pt.x, & Y = obj_pt.y, & Z = obj_pt.z;
const double x = img_pt.x, y = img_pt.y;
const double X = obj_pt.x, Y = obj_pt.y, Z = obj_pt.z;
double sq_norm = x * x + y * y;
sq_norm_sum += sq_norm;
double X2 = X * X,
const double X2 = X * X,
XY = X * Y,
XZ = X * Z,
Y2 = Y * Y,
@ -178,47 +189,47 @@ void PoseSolver::computeOmega(InputArray objectPoints, InputArray imagePoints)
omega_(2, 2) += Z2;
//Populating this manually saves operations by only calculating upper triangle
omega_(0, 6) += -x * X2; omega_(0, 7) += -x * XY; omega_(0, 8) += -x * XZ;
omega_(1, 7) += -x * Y2; omega_(1, 8) += -x * YZ;
omega_(2, 8) += -x * Z2;
// Populating this manually saves operations by only calculating upper triangle
omega_(0, 6) -= x * X2; omega_(0, 7) -= x * XY; omega_(0, 8) -= x * XZ;
omega_(1, 7) -= x * Y2; omega_(1, 8) -= x * YZ;
omega_(2, 8) -= x * Z2;
omega_(3, 6) += -y * X2; omega_(3, 7) += -y * XY; omega_(3, 8) += -y * XZ;
omega_(4, 7) += -y * Y2; omega_(4, 8) += -y * YZ;
omega_(5, 8) += -y * Z2;
omega_(3, 6) -= y * X2; omega_(3, 7) -= y * XY; omega_(3, 8) -= y * XZ;
omega_(4, 7) -= y * Y2; omega_(4, 8) -= y * YZ;
omega_(5, 8) -= y * Z2;
omega_(6, 6) += sq_norm * X2; omega_(6, 7) += sq_norm * XY; omega_(6, 8) += sq_norm * XZ;
omega_(7, 7) += sq_norm * Y2; omega_(7, 8) += sq_norm * YZ;
omega_(8, 8) += sq_norm * Z2;
//Compute qa_sum. Certain pairs of elements are equal, so filling them outside the loop saves some operations
// Compute qa_sum. Certain pairs of elements are equal, so filling them outside the loop saves some operations
qa_sum(0, 0) += X; qa_sum(0, 1) += Y; qa_sum(0, 2) += Z;
qa_sum(0, 6) += -x * X; qa_sum(0, 7) += -x * Y; qa_sum(0, 8) += -x * Z;
qa_sum(1, 6) += -y * X; qa_sum(1, 7) += -y * Y; qa_sum(1, 8) += -y * Z;
qa_sum(0, 6) -= x * X; qa_sum(0, 7) -= x * Y; qa_sum(0, 8) -= x * Z;
qa_sum(1, 6) -= y * X; qa_sum(1, 7) -= y * Y; qa_sum(1, 8) -= y * Z;
qa_sum(2, 6) += sq_norm * X; qa_sum(2, 7) += sq_norm * Y; qa_sum(2, 8) += sq_norm * Z;
}
//Complete qa_sum
// Complete qa_sum
qa_sum(1, 3) = qa_sum(0, 0); qa_sum(1, 4) = qa_sum(0, 1); qa_sum(1, 5) = qa_sum(0, 2);
qa_sum(2, 0) = qa_sum(0, 6); qa_sum(2, 1) = qa_sum(0, 7); qa_sum(2, 2) = qa_sum(0, 8);
qa_sum(2, 3) = qa_sum(1, 6); qa_sum(2, 4) = qa_sum(1, 7); qa_sum(2, 5) = qa_sum(1, 8);
//lower triangles of omega_'s off-diagonal blocks (0:2, 6:8), (3:5, 6:8) and (6:8, 6:8)
// lower triangles of omega_'s off-diagonal blocks (0:2, 6:8), (3:5, 6:8) and (6:8, 6:8)
omega_(1, 6) = omega_(0, 7); omega_(2, 6) = omega_(0, 8); omega_(2, 7) = omega_(1, 8);
omega_(4, 6) = omega_(3, 7); omega_(5, 6) = omega_(3, 8); omega_(5, 7) = omega_(4, 8);
omega_(7, 6) = omega_(6, 7); omega_(8, 6) = omega_(6, 8); omega_(8, 7) = omega_(7, 8);
//upper triangle of omega_'s block (3:5, 3:5)
// upper triangle of omega_'s block (3:5, 3:5)
omega_(3, 3) = omega_(0, 0); omega_(3, 4) = omega_(0, 1); omega_(3, 5) = omega_(0, 2);
omega_(4, 4) = omega_(1, 1); omega_(4, 5) = omega_(1, 2);
omega_(5, 5) = omega_(2, 2);
//Mirror omega_'s upper triangle to lower triangle
//Note that elements (7, 6), (8, 6) & (8, 7) have already been assigned above
// Mirror omega_'s upper triangle to lower triangle
// Note that elements (7, 6), (8, 6) & (8, 7) have already been assigned above
omega_(1, 0) = omega_(0, 1);
omega_(2, 0) = omega_(0, 2); omega_(2, 1) = omega_(1, 2);
omega_(3, 0) = omega_(0, 3); omega_(3, 1) = omega_(1, 3); omega_(3, 2) = omega_(2, 3);
@ -240,12 +251,26 @@ void PoseSolver::computeOmega(InputArray objectPoints, InputArray imagePoints)
CV_Assert(point_coordinate_variance >= POINT_VARIANCE_THRESHOLD);
Matx<double, 3, 3> q_inv;
analyticalInverse3x3Symm(q, q_inv);
if (!invertSPD3x3(q, q_inv)) analyticalInverse3x3Symm(q, q_inv);
p_ = -q_inv * qa_sum;
omega_ += qa_sum.t() * p_;
#ifdef HAVE_EIGEN
// Rank revealing QR nullspace computation with full pivoting.
// This is slightly less accurate compared to SVD but x2-x3 faster
Eigen::Matrix<double, 9, 9> omega_eig, tmp_eig;
cv::cv2eigen(omega_, omega_eig);
Eigen::FullPivHouseholderQR<Eigen::Matrix<double, 9, 9> > rrqr(omega_eig);
tmp_eig = rrqr.matrixQ();
cv::eigen2cv(tmp_eig, u_);
tmp_eig = rrqr.matrixQR().template triangularView<Eigen::Upper>(); // R
Eigen::Matrix<double, 9, 1> S_eig = tmp_eig.diagonal().array().abs();
cv::eigen2cv(S_eig, s_);
#else
// Use OpenCV's SVD
cv::SVD omega_svd(omega_, cv::SVD::FULL_UV);
s_ = omega_svd.w;
u_ = cv::Mat(omega_svd.vt.t());
@ -255,6 +280,8 @@ void PoseSolver::computeOmega(InputArray objectPoints, InputArray imagePoints)
u_ = u_.t(); // eigenvectors were returned as rows
#endif
#endif // HAVE_EIGEN
CV_Assert(s_(0) >= 1e-7);
while (s_(7 - num_null_vectors_) < RANK_TOLERANCE) num_null_vectors_++;
@ -276,7 +303,7 @@ void PoseSolver::solveInternal(InputArray objectPoints)
SQPSolution solutions[2];
//If e is orthogonal, we can skip SQP
// If e is orthogonal, we can skip SQP
if (orthogonality_sq_err < ORTHOGONALITY_SQUARED_ERROR_THRESHOLD)
{
solutions[0].r_hat = det3x3(e) * e;
@ -393,6 +420,77 @@ void PoseSolver::solveSQPSystem(const cv::Matx<double, 9, 1>& r, cv::Matx<double
delta += N * y;
}
// Inverse of SPD 3x3 A via a lower triangular sqrt-free Cholesky
// factorization A=L*D*L' (L has ones on its diagonal, D is diagonal).
//
// Only the lower triangular part of A is accessed.
//
// The function returns true if successful
//
// see http://euler.nmt.edu/~brian/ldlt.html
//
bool PoseSolver::invertSPD3x3(const cv::Matx<double, 3, 3>& A, cv::Matx<double, 3, 3>& A1)
{
double L[3*3], D[3], v[2], x[3];
v[0]=D[0]=A(0, 0);
if(v[0]<=1E-10) return false;
v[1]=1.0/v[0];
L[3]=A(1, 0)*v[1];
L[6]=A(2, 0)*v[1];
//L[0]=1.0;
//L[1]=L[2]=0.0;
v[0]=L[3]*D[0];
v[1]=D[1]=A(1, 1)-L[3]*v[0];
if(v[1]<=1E-10) return false;
L[7]=(A(2, 1)-L[6]*v[0])/v[1];
//L[4]=1.0;
//L[5]=0.0;
v[0]=L[6]*D[0];
v[1]=L[7]*D[1];
D[2]=A(2, 2)-L[6]*v[0]-L[7]*v[1];
if(D[2]<=1E-10) return false;
//L[8]=1.0;
D[0]=1.0/D[0];
D[1]=1.0/D[1];
D[2]=1.0/D[2];
/* Forward solve Lx = e0 */
//x[0]=1.0;
x[1]=-L[3];
x[2]=-L[6]+L[7]*L[3];
/* Backward solve D*L'x = y */
A1(0, 2)=x[2]=x[2]*D[2];
A1(0, 1)=x[1]=x[1]*D[1]-L[7]*x[2];
A1(0, 0) = D[0]-L[3]*x[1]-L[6]*x[2];
/* Forward solve Lx = e1 */
//x[0]=0.0;
//x[1]=1.0;
x[2]=-L[7];
/* Backward solve D*L'x = y */
A1(1, 2)=x[2]=x[2]*D[2];
A1(1, 1)=x[1]= D[1]-L[7]*x[2];
A1(1, 0) = -L[3]*x[1]-L[6]*x[2];
/* Forward solve Lx = e2 */
//x[0]=0.0;
//x[1]=0.0;
//x[2]=1.0;
/* Backward solve D*L'x = y */
A1(2, 2)=x[2]=D[2];
A1(2, 1)=x[1]= -L[7]*x[2];
A1(2, 0) = -L[3]*x[1]-L[6]*x[2];
return true;
}
bool PoseSolver::analyticalInverse3x3Symm(const cv::Matx<double, 3, 3>& Q,
cv::Matx<double, 3, 3>& Qinv,
const double& threshold)
@ -411,7 +509,7 @@ bool PoseSolver::analyticalInverse3x3Symm(const cv::Matx<double, 3, 3>& Q,
t12 = c * c;
double det = -t4 * f + a * t2 + t7 * f - 2.0 * t9 * e + t12 * d;
if (fabs(det) < threshold) return false;
if (fabs(det) < threshold) { cv::invert(Q, Qinv, cv::DECOMP_SVD); return false; } // fall back to pseudoinverse
// 3. Inverse
double t15, t20, t24, t30;
@ -502,7 +600,7 @@ void PoseSolver::computeRowAndNullspace(const cv::Matx<double, 9, 1>& r,
H(6, 4) = r(3) - dot_j5q3 * H(6, 2); H(7, 4) = r(4) - dot_j5q3 * H(7, 2); H(8, 4) = r(5) - dot_j5q3 * H(8, 2);
Matx<double, 9, 1> q4 = H.col(4);
q4 /= cv::norm(q4);
q4 *= (1.0 / cv::norm(q4));
set<double, 9, 1, 9, 6>(0, 4, H, q4);
K(4, 0) = 0;
@ -531,7 +629,7 @@ void PoseSolver::computeRowAndNullspace(const cv::Matx<double, 9, 1>& r,
H(8, 5) = r(2) - dot_j6q3 * H(8, 2) - dot_j6q5 * H(8, 4);
Matx<double, 9, 1> q5 = H.col(5);
q5 /= cv::norm(q5);
q5 *= (1.0 / cv::norm(q5));
set<double, 9, 1, 9, 6>(0, 5, H, q5);
K(5, 0) = r(6) * H(0, 0) + r(7) * H(1, 0) + r(8) * H(2, 0);
@ -573,10 +671,11 @@ void PoseSolver::computeRowAndNullspace(const cv::Matx<double, 9, 1>& r,
Matx<double, 9, 1> v1 = Pn.col(index1);
v1 /= max_norm1;
set<double, 9, 1, 9, 3>(0, 0, N, v1);
col_norms[index1] = -1.0; // mark to avoid use in subsequent loops
for (int i = 0; i < 9; i++)
{
if (i == index1) continue;
//if (i == index1) continue;
if (col_norms[i] >= norm_threshold)
{
double cos_v1_x_col = fabs(Pn.col(i).dot(v1) / col_norms[i]);
@ -592,16 +691,18 @@ void PoseSolver::computeRowAndNullspace(const cv::Matx<double, 9, 1>& r,
Matx<double, 9, 1> v2 = Pn.col(index2);
Matx<double, 9, 1> n0 = N.col(0);
v2 -= v2.dot(n0) * n0;
v2 /= cv::norm(v2);
v2 *= (1.0 / cv::norm(v2));
set<double, 9, 1, 9, 3>(0, 1, N, v2);
col_norms[index2] = -1.0; // mark to avoid use in subsequent loops
for (int i = 0; i < 9; i++)
{
if (i == index2 || i == index1) continue;
//if (i == index2 || i == index1) continue;
if (col_norms[i] >= norm_threshold)
{
double cos_v1_x_col = fabs(Pn.col(i).dot(v1) / col_norms[i]);
double cos_v2_x_col = fabs(Pn.col(i).dot(v2) / col_norms[i]);
double inv_norm = 1.0 / col_norms[i];
double cos_v1_x_col = fabs(Pn.col(i).dot(v1) * inv_norm);
double cos_v2_x_col = fabs(Pn.col(i).dot(v2) * inv_norm);
if (cos_v1_x_col + cos_v2_x_col <= min_dot1323)
{
@ -614,7 +715,7 @@ void PoseSolver::computeRowAndNullspace(const cv::Matx<double, 9, 1>& r,
Matx<double, 9, 1> v3 = Pn.col(index3);
Matx<double, 9, 1> n1 = N.col(1);
v3 -= (v3.dot(n1)) * n1 - (v3.dot(n0)) * n0;
v3 /= cv::norm(v3);
v3 *= (1.0 / cv::norm(v3));
set<double, 9, 1, 9, 3>(0, 2, N, v3);
}
@ -635,17 +736,17 @@ void PoseSolver::nearestRotationMatrixSVD(const cv::Matx<double, 9, 1>& e,
// Faster nearest rotation computation based on FOAM. See M. Lourakis: "An Efficient Solution to Absolute Orientation", ICPR 2016
// and M. Lourakis, G. Terzakis: "Efficient Absolute Orientation Revisited", IROS 2018.
/* Solve the nearest orthogonal approximation problem
* i.e., given e, find R minimizing ||R-e||_F
*
* The computation borrows from Markley's FOAM algorithm
* "Attitude Determination Using Vector Observations: A Fast Optimal Matrix Algorithm", J. Astronaut. Sci. 1993.
*
* See also M. Lourakis: "An Efficient Solution to Absolute Orientation", ICPR 2016
*
* Copyright (C) 2019 Manolis Lourakis (lourakis **at** ics forth gr)
* Institute of Computer Science, Foundation for Research & Technology - Hellas
* Heraklion, Crete, Greece.
*/
* i.e., given e, find R minimizing ||R-e||_F
*
* The computation borrows from Markley's FOAM algorithm
* "Attitude Determination Using Vector Observations: A Fast Optimal Matrix Algorithm", J. Astronaut. Sci. 1993.
*
* See also M. Lourakis: "An Efficient Solution to Absolute Orientation", ICPR 2016
*
* Copyright (C) 2019 Manolis Lourakis (lourakis **at** ics forth gr)
* Institute of Computer Science, Foundation for Research & Technology - Hellas
* Heraklion, Crete, Greece.
*/
void PoseSolver::nearestRotationMatrixFOAM(const cv::Matx<double, 9, 1>& e,
cv::Matx<double, 9, 1>& r)
{
@ -653,7 +754,7 @@ void PoseSolver::nearestRotationMatrixFOAM(const cv::Matx<double, 9, 1>& e,
double l, lprev, det_e, e_sq, adj_e_sq, adj_e[9];
// det(e)
det_e = e(0) * e(4) * e(8) - e(0) * e(5) * e(7) - e(1) * e(3) * e(8) + e(2) * e(3) * e(7) + e(1) * e(6) * e(5) - e(2) * e(6) * e(4);
det_e = ( e(0) * e(4) * e(8) - e(0) * e(5) * e(7) - e(1) * e(3) * e(8) ) + ( e(2) * e(3) * e(7) + e(1) * e(6) * e(5) - e(2) * e(6) * e(4) );
if (fabs(det_e) < 1E-04) { // singular, handle it with SVD
PoseSolver::nearestRotationMatrixSVD(e, r);
return;
@ -665,8 +766,8 @@ void PoseSolver::nearestRotationMatrixFOAM(const cv::Matx<double, 9, 1>& e,
adj_e[6] = e(3) * e(7) - e(4) * e(6); adj_e[7] = e(1) * e(6) - e(0) * e(7); adj_e[8] = e(0) * e(4) - e(1) * e(3);
// ||e||^2, ||adj(e)||^2
e_sq = e(0) * e(0) + e(1) * e(1) + e(2) * e(2) + e(3) * e(3) + e(4) * e(4) + e(5) * e(5) + e(6) * e(6) + e(7) * e(7) + e(8) * e(8);
adj_e_sq = adj_e[0] * adj_e[0] + adj_e[1] * adj_e[1] + adj_e[2] * adj_e[2] + adj_e[3] * adj_e[3] + adj_e[4] * adj_e[4] + adj_e[5] * adj_e[5] + adj_e[6] * adj_e[6] + adj_e[7] * adj_e[7] + adj_e[8] * adj_e[8];
e_sq = ( e(0) * e(0) + e(1) * e(1) + e(2) * e(2) ) + ( e(3) * e(3) + e(4) * e(4) + e(5) * e(5) ) + ( e(6) * e(6) + e(7) * e(7) + e(8) * e(8) );
adj_e_sq = ( adj_e[0] * adj_e[0] + adj_e[1] * adj_e[1] + adj_e[2] * adj_e[2] ) + ( adj_e[3] * adj_e[3] + adj_e[4] * adj_e[4] + adj_e[5] * adj_e[5] ) + ( adj_e[6] * adj_e[6] + adj_e[7] * adj_e[7] + adj_e[8] * adj_e[8] );
// compute l_max with Newton-Raphson from FOAM's characteristic polynomial, i.e. eq.(23) - (26)
l = 0.5*(e_sq + 3.0); // 1/2*(trace(mat(e)*mat(e)') + trace(eye(3)))
@ -733,8 +834,8 @@ void PoseSolver::nearestRotationMatrixFOAM(const cv::Matx<double, 9, 1>& e,
double PoseSolver::det3x3(const cv::Matx<double, 9, 1>& e)
{
return e(0) * e(4) * e(8) + e(1) * e(5) * e(6) + e(2) * e(3) * e(7)
- e(6) * e(4) * e(2) - e(7) * e(5) * e(0) - e(8) * e(3) * e(1);
return ( e(0) * e(4) * e(8) + e(1) * e(5) * e(6) + e(2) * e(3) * e(7) )
- ( e(6) * e(4) * e(2) + e(7) * e(5) * e(0) + e(8) * e(3) * e(1) );
}
inline bool PoseSolver::positiveDepth(const SQPSolution& solution) const
@ -815,8 +916,8 @@ double PoseSolver::orthogonalityError(const cv::Matx<double, 9, 1>& e)
double dot_e1e3 = e(0) * e(6) + e(1) * e(7) + e(2) * e(8);
double dot_e2e3 = e(3) * e(6) + e(4) * e(7) + e(5) * e(8);
return (sq_norm_e1 - 1) * (sq_norm_e1 - 1) + (sq_norm_e2 - 1) * (sq_norm_e2 - 1) + (sq_norm_e3 - 1) * (sq_norm_e3 - 1) +
2 * (dot_e1e2 * dot_e1e2 + dot_e1e3 * dot_e1e3 + dot_e2e3 * dot_e2e3);
return ( (sq_norm_e1 - 1) * (sq_norm_e1 - 1) + (sq_norm_e2 - 1) * (sq_norm_e2 - 1) ) + ( (sq_norm_e3 - 1) * (sq_norm_e3 - 1) +
2 * (dot_e1e2 * dot_e1e2 + dot_e1e3 * dot_e1e3 + dot_e2e3 * dot_e2e3) );
}
}

View File

@ -1,3 +1,10 @@
// Implementation of SQPnP as described in the paper:
//
// "A Consistently Fast and Globally Optimal Solution to the Perspective-n-Point Problem" by G. Terzakis and M. Lourakis
// a) Paper: https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123460460.pdf
// b) Supplementary: https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123460460-supp.pdf
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
@ -158,6 +165,13 @@ private:
*/
void solveSQPSystem(const cv::Matx<double, 9, 1>& r, cv::Matx<double, 9, 1>& delta);
/*
* @brief Inverse of SPD 3x3 A via lower triangular sqrt-free Cholesky: A = L*D*L'
* @param A The input matrix
* @param A1 The inverse
*/
static bool invertSPD3x3(const cv::Matx<double, 3, 3>& A, cv::Matx<double, 3, 3>& A1);
/*
* @brief Analytically computes the inverse of a symmetric 3x3 matrix using the
* lower triangle.

View File

@ -14,6 +14,9 @@ libraries. The following modules are available:
- @ref imgproc (**imgproc**) - an image processing module that includes linear and non-linear image filtering,
geometrical image transformations (resize, affine and perspective warping, generic table-based
remapping), color space conversion, histograms, and so on.
- @ref imgcodecs (**imgcodecs**) - includes functions for reading and writing image files in various formats.
- @ref videoio (**videoio**) - an easy-to-use interface to video capturing and video codecs.
- @ref highgui (**highgui**) - an easy-to-use interface to simple UI capabilities.
- @ref video (**video**) - a video analysis module that includes motion estimation, background subtraction,
and object tracking algorithms.
- @ref _3d "3d" (**3d**) - basic multiple-view geometry algorithms, object pose estimation and elements of 3D reconstruction.
@ -24,6 +27,9 @@ libraries. The following modules are available:
- @ref stereo (**stereo**) - stereo correspondence algorithms
- @ref highgui (**highgui**) - an easy-to-use interface to simple UI capabilities.
- @ref videoio (**videoio**) - an easy-to-use interface to video capturing and video codecs.
- @ref dnn (**dnn**) - Deep Neural Network module.
- @ref photo (**photo**) - advanced photo processing techniques like denoising, inpainting.
- @ref stitching (**stitching**) - functions for image stitching and panorama creation.
- ... some other helper modules, such as FLANN and Google test wrappers, Python bindings, and
others.

View File

@ -60,11 +60,16 @@
/**
@defgroup core Core functionality
The Core module is the backbone of OpenCV, offering fundamental data structures, matrix operations,
and utility functions that other modules depend on. Its essential for handling image data,
performing mathematical computations, and managing memory efficiently within the OpenCV ecosystem.
@{
@defgroup core_basic Basic structures
@defgroup core_array Operations on arrays
@defgroup core_async Asynchronous API
@defgroup core_xml XML/YAML Persistence
@defgroup core_xml XML/YAML/JSON Persistence
@defgroup core_cluster Clustering
@defgroup core_utils Utility and system functions and macros
@{
@ -76,7 +81,6 @@
@defgroup core_utils_samples Utility functions for OpenCV samples
@}
@defgroup core_opengl OpenGL interoperability
@defgroup core_ipp Intel IPP Asynchronous C/C++ Converters
@defgroup core_optim Optimization Algorithms
@defgroup core_directx DirectX interoperability
@defgroup core_eigen Eigen support
@ -96,12 +100,13 @@
@{
@defgroup core_parallel_backend Parallel backends API
@}
@defgroup core_quaternion Quaternion
@}
*/
namespace cv {
//! @addtogroup core
//! @addtogroup core_utils
//! @{
enum SortFlags { SORT_EVERY_ROW = 0, //!< each matrix row is sorted independently
@ -115,6 +120,11 @@ enum SortFlags { SORT_EVERY_ROW = 0, //!< each matrix row is sorted independe
//!< mutually exclusive.
};
//! @} core_utils
//! @addtogroup core_array
//! @{
//! Covariation flags
enum CovarFlags {
/** The output covariance matrix is calculated as:
@ -151,27 +161,6 @@ enum CovarFlags {
COVAR_COLS = 16
};
//! @addtogroup core_cluster
//! @{
//! k-Means flags
enum KmeansFlags {
/** Select random initial centers in each attempt.*/
KMEANS_RANDOM_CENTERS = 0,
/** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/
KMEANS_PP_CENTERS = 2,
/** During the first (and possibly the only) attempt, use the
user-supplied labels instead of computing them from the initial centers. For the second and
further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag
to specify the exact method.*/
KMEANS_USE_INITIAL_LABELS = 1
};
//! @} core_cluster
//! @addtogroup core_array
//! @{
enum ReduceTypes { REDUCE_SUM = 0, //!< the output is the sum of all rows/columns of the matrix.
REDUCE_AVG = 1, //!< the output is the mean vector of all rows/columns of the matrix.
REDUCE_MAX = 2, //!< the output is the maximum (column/row-wise) of all rows/columns of the matrix.
@ -179,19 +168,12 @@ enum ReduceTypes { REDUCE_SUM = 0, //!< the output is the sum of all rows/column
REDUCE_SUM2 = 4 //!< the output is the sum of all squared rows/columns of the matrix.
};
//! @} core_array
/** @brief Swaps two matrices
*/
CV_EXPORTS void swap(Mat& a, Mat& b);
/** @overload */
CV_EXPORTS void swap( UMat& a, UMat& b );
//! @} core
//! @addtogroup core_array
//! @{
/** @brief Computes the source location of an extrapolated pixel.
The function computes and returns the coordinate of a donor pixel corresponding to the specified
@ -492,6 +474,10 @@ For example:
CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst,
double alpha = 1, double beta = 0);
/** @example samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp
Check @ref tutorial_how_to_scan_images "the corresponding tutorial" for more details
*/
/** @brief Performs a look-up table transform of an array.
The function LUT fills the output array with values from the look-up table. Indices of the entries
@ -3007,6 +2993,19 @@ private:
//! @addtogroup core_cluster
//! @{
//! k-means flags
enum KmeansFlags {
/** Select random initial centers in each attempt.*/
KMEANS_RANDOM_CENTERS = 0,
/** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/
KMEANS_PP_CENTERS = 2,
/** During the first (and possibly the only) attempt, use the
user-supplied labels instead of computing them from the initial centers. For the second and
further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag
to specify the exact method.*/
KMEANS_USE_INITIAL_LABELS = 1
};
/** @example samples/cpp/snippets/kmeans.cpp
An example on k-means clustering
*/
@ -3021,7 +3020,7 @@ and groups the input samples around the clusters. As an output, \f$\texttt{bestL
0-based cluster index for the sample stored in the \f$i^{th}\f$ row of the samples matrix.
@note
- (Python) An example on K-means clustering can be found at
- (Python) An example on k-means clustering can be found at
opencv_source_code/samples/python/kmeans.py
@param data Data for clustering. An array of N-Dimensional points with float coordinates is needed.
Examples of this array can be:

View File

@ -51,7 +51,7 @@
namespace cv
{
//! @addtogroup core
//! @addtogroup core_eigen
//! @{
/** @brief Affine transform

View File

@ -15,7 +15,7 @@
namespace cv
{
//! @addtogroup core
//! @addtogroup core_opencl
//! @{
class BufferPoolController

View File

@ -30,7 +30,7 @@
#include <opencv2/core/affine.hpp>
namespace cv{
//! @addtogroup core
//! @addtogroup core_quaternion
//! @{
template <typename _Tp> class DualQuat;

View File

@ -127,28 +127,28 @@ CV_EXPORTS CV_NORETURN void error(const Exception& exc);
By default the function prints information about the error to stderr,
then it either stops if setBreakOnError() had been called before or raises the exception.
It is possible to alternate error processing by using redirectError().
@param _code - error code (Error::Code)
@param _err - error description
@param _func - function name. Available only when the compiler supports getting it
@param _file - source file name where the error has occurred
@param _line - line number in the source file where the error has occurred
@param code - error code (Error::Code)
@param err - error description
@param func - function name. Available only when the compiler supports getting it
@param file - source file name where the error has occurred
@param line - line number in the source file where the error has occurred
@see CV_Error, CV_Error_, CV_Assert, CV_DbgAssert
*/
CV_EXPORTS CV_NORETURN void error(Error::Code _code, const String& _err, const char* _func, const char* _file, int _line);
CV_EXPORTS CV_NORETURN void error(Error::Code code, const String& err, const char* func, const char* file, int line);
/*! @brief Signals an error and terminate application.
By default the function prints information about the error to stderr, then it terminates application
with std::terminate. The function is designed for invariants check in functions and methods with
noexcept attribute.
@param _code - error code (Error::Code)
@param _err - error description
@param _func - function name. Available only when the compiler supports getting it
@param _file - source file name where the error has occurred
@param _line - line number in the source file where the error has occurred
@param code - error code (Error::Code)
@param err - error description
@param func - function name. Available only when the compiler supports getting it
@param file - source file name where the error has occurred
@param line - line number in the source file where the error has occurred
@see CV_AssertTerminate
*/
CV_EXPORTS CV_NORETURN void terminate(Error::Code _code, const String& _err, const char* _func, const char* _file, int _line) CV_NOEXCEPT;
CV_EXPORTS CV_NORETURN void terminate(Error::Code code, const String& err, const char* func, const char* file, int line) CV_NOEXCEPT;
#ifdef CV_STATIC_ANALYSIS

View File

@ -194,6 +194,20 @@ CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(double, int64, uint64, double, void, double)
#endif // CV_CPU_OPTIMIZATION_HAL_NAMESPACE
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
template <typename _VecTp> inline _VecTp v_setzero_();
template <typename _VecTp> inline _VecTp v_setall_(uchar);
template <typename _VecTp> inline _VecTp v_setall_(schar);
template <typename _VecTp> inline _VecTp v_setall_(ushort);
template <typename _VecTp> inline _VecTp v_setall_(short);
template <typename _VecTp> inline _VecTp v_setall_(unsigned);
template <typename _VecTp> inline _VecTp v_setall_(int);
template <typename _VecTp> inline _VecTp v_setall_(uint64);
template <typename _VecTp> inline _VecTp v_setall_(int64);
template <typename _VecTp> inline _VecTp v_setall_(float);
template <typename _VecTp> inline _VecTp v_setall_(double);
template <typename _VecTp> inline _VecTp v_setall_(hfloat);
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
#endif

View File

@ -447,6 +447,10 @@ OPENCV_HAL_IMPL_AVX_LOADSTORE_FLT(v_float64x4, double, pd, __m128d)
{ return _Tpvec(_mm256_setzero_si256()); } \
inline _Tpvec v256_setall_##suffix(_Tp v) \
{ return _Tpvec(_mm256_set1_##ssuffix((ctype_s)v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v256_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v256_setall_##suffix(v); } \
OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint8x32, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int8x32, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint16x16, suffix, OPENCV_HAL_NOP) \
@ -472,6 +476,10 @@ OPENCV_HAL_IMPL_AVX_INIT(v_int64x4, int64, s64, epi64x, int64)
{ return _Tpvec(_mm256_setzero_##zsuffix()); } \
inline _Tpvec v256_setall_##suffix(_Tp v) \
{ return _Tpvec(_mm256_set1_##zsuffix(v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v256_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v256_setall_##suffix(v); } \
OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint8x32, suffix, cast) \
OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int8x32, suffix, cast) \
OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint16x16, suffix, cast) \
@ -3179,6 +3187,20 @@ inline void v_pack_store(bfloat* ptr, const v_float32x8& a)
inline void v256_cleanup() { _mm256_zeroall(); }
#include "intrin_math.hpp"
inline v_float32x8 v_exp(const v_float32x8& x) { return v_exp_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float32x8 v_log(const v_float32x8& x) { return v_log_default_32f<v_float32x8, v_int32x8>(x); }
inline void v_sincos(const v_float32x8& x, v_float32x8& s, v_float32x8& c) { v_sincos_default_32f<v_float32x8, v_int32x8>(x, s, c); }
inline v_float32x8 v_sin(const v_float32x8& x) { return v_sin_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float32x8 v_cos(const v_float32x8& x) { return v_cos_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float32x8 v_erf(const v_float32x8& x) { return v_erf_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float64x4 v_exp(const v_float64x4& x) { return v_exp_default_64f<v_float64x4, v_int64x4>(x); }
inline v_float64x4 v_log(const v_float64x4& x) { return v_log_default_64f<v_float64x4, v_int64x4>(x); }
inline void v_sincos(const v_float64x4& x, v_float64x4& s, v_float64x4& c) { v_sincos_default_64f<v_float64x4, v_int64x4>(x, s, c); }
inline v_float64x4 v_sin(const v_float64x4& x) { return v_sin_default_64f<v_float64x4, v_int64x4>(x); }
inline v_float64x4 v_cos(const v_float64x4& x) { return v_cos_default_64f<v_float64x4, v_int64x4>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -458,6 +458,10 @@ OPENCV_HAL_IMPL_AVX512_LOADSTORE_FLT(v_float64x8, double, pd, __m256d)
{ return _Tpvec(_mm512_setzero_si512()); } \
inline _Tpvec v512_setall_##suffix(_Tp v) \
{ return _Tpvec(_mm512_set1_##ssuffix((ctype_s)v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v512_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v512_setall_##suffix(v); } \
OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint8x64, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int8x64, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint16x32, suffix, OPENCV_HAL_NOP) \
@ -483,6 +487,10 @@ OPENCV_HAL_IMPL_AVX512_INIT(v_int64x8, int64, s64, epi64, int64)
{ return _Tpvec(_mm512_setzero_##zsuffix()); } \
inline _Tpvec v512_setall_##suffix(_Tp v) \
{ return _Tpvec(_mm512_set1_##zsuffix(v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v512_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v512_setall_##suffix(v); } \
OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint8x64, suffix, cast) \
OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int8x64, suffix, cast) \
OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint16x32, suffix, cast) \
@ -3070,6 +3078,20 @@ inline int v_scan_forward(const v_float64x8& a) { return trailingZeros32(v_signm
inline void v512_cleanup() { _mm256_zeroall(); }
#include "intrin_math.hpp"
inline v_float32x16 v_exp(const v_float32x16& x) { return v_exp_default_32f<v_float32x16, v_int32x16>(x); }
inline v_float32x16 v_log(const v_float32x16& x) { return v_log_default_32f<v_float32x16, v_int32x16>(x); }
inline void v_sincos(const v_float32x16& x, v_float32x16& s, v_float32x16& c) { v_sincos_default_32f<v_float32x16, v_int32x16>(x, s, c); }
inline v_float32x16 v_sin(const v_float32x16& x) { return v_sin_default_32f<v_float32x16, v_int32x16>(x); }
inline v_float32x16 v_cos(const v_float32x16& x) { return v_cos_default_32f<v_float32x16, v_int32x16>(x); }
inline v_float32x16 v_erf(const v_float32x16& x) { return v_erf_default_32f<v_float32x16, v_int32x16>(x); }
inline v_float64x8 v_exp(const v_float64x8& x) { return v_exp_default_64f<v_float64x8, v_int64x8>(x); }
inline v_float64x8 v_log(const v_float64x8& x) { return v_log_default_64f<v_float64x8, v_int64x8>(x); }
inline void v_sincos(const v_float64x8& x, v_float64x8& s, v_float64x8& c) { v_sincos_default_64f<v_float64x8, v_int64x8>(x, s, c); }
inline v_float64x8 v_sin(const v_float64x8& x) { return v_sin_default_64f<v_float64x8, v_int64x8>(x); }
inline v_float64x8 v_cos(const v_float64x8& x) { return v_cos_default_64f<v_float64x8, v_int64x8>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -263,8 +263,8 @@ Most of these operations return only one value.
### Other math
- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude, @ref v_exp,
@ref v_erf
- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude, @ref v_exp, @ref v_log,
@ref v_erf, @ref v_sin, @ref v_cos
- Absolute values: @ref v_abs, @ref v_absdiff, @ref v_absdiffs
### Conversions
@ -366,6 +366,7 @@ Floating point:
|broadcast_element | x | |
|exp | x | x |
|log | x | x |
|sin, cos | x | x |
@{ */
@ -745,10 +746,41 @@ OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp)
*/
OPENCV_HAL_IMPL_MATH_FUNC(v_erf, std::erf, _Tp)
//! @cond IGNORED
/**
* @brief Compute sine \f$ sin(x) \f$ and cosine \f$ cos(x) \f$ of elements at the same time
*
* Only for floating point types. Core implementation steps:
* 1. Input Normalization: Scale the periodicity from 2π to 4 and reduce the angle to the range \f$ [0, \frac{\pi}{4}] \f$ using periodicity and trigonometric identities.
* 2. Polynomial Approximation for \f$ sin(x) \f$ and \f$ cos(x) \f$:
* - For float16 and float32, use a Taylor series with 4 terms for sine and 5 terms for cosine.
* - For float64, use a Taylor series with 7 terms for sine and 8 terms for cosine.
* 3. Select Results: select and convert the final sine and cosine values for the original input angle.
*
* @note The precision of the calculation depends on the implementation and the data type of the input vector.
*/
template<typename _Tp, int n>
inline void v_sincos(const v_reg<_Tp, n>& x, v_reg<_Tp, n>& s, v_reg<_Tp, n>& c)
{
for( int i = 0; i < n; i++ )
{
s.s[i] = std::sin(x.s[i]);
c.s[i] = std::cos(x.s[i]);
}
}
/**
* @brief Sine \f$ sin(x) \f$ of elements
*
* Only for floating point types. Core implementation the same as @ref v_sincos.
*/
OPENCV_HAL_IMPL_MATH_FUNC(v_sin, std::sin, _Tp)
/**
* @brief Cosine \f$ cos(x) \f$ of elements
*
* Only for floating point types. Core implementation the same as @ref v_sincos.
*/
OPENCV_HAL_IMPL_MATH_FUNC(v_cos, std::cos, _Tp)
//! @endcond
/** @brief Absolute value of elements
@ -2801,7 +2833,8 @@ inline void v_transpose4x4( v_reg<_Tp, n>& a0, const v_reg<_Tp, n>& a1,
//! @brief Helper macro
//! @ingroup core_hal_intrin_impl
#define OPENCV_HAL_IMPL_C_INIT_ZERO(_Tpvec, prefix, suffix) \
inline _Tpvec prefix##_setzero_##suffix() { return _Tpvec::zero(); }
inline _Tpvec prefix##_setzero_##suffix() { return _Tpvec::zero(); } \
template <> inline _Tpvec v_setzero_() { return _Tpvec::zero(); }
//! @name Init with zero
//! @{
@ -2847,7 +2880,8 @@ OPENCV_HAL_IMPL_C_INIT_ZERO(v_int64x8, v512, s64)
//! @brief Helper macro
//! @ingroup core_hal_intrin_impl
#define OPENCV_HAL_IMPL_C_INIT_VAL(_Tpvec, _Tp, prefix, suffix) \
inline _Tpvec prefix##_setall_##suffix(_Tp val) { return _Tpvec::all(val); }
inline _Tpvec prefix##_setall_##suffix(_Tp val) { return _Tpvec::all(val); } \
template <> inline _Tpvec v_setall_(_Tp val) { return _Tpvec::all(val); }
//! @name Init with value
//! @{

View File

@ -557,6 +557,10 @@ inline __m256i _lasx_256_castpd_si256(const __m256d& v)
{ return _Tpvec(__lasx_xvreplgr2vr_d(0)); } \
inline _Tpvec v256_setall_##suffix(_Tp v) \
{ return _Tpvec(__lasx_xvreplgr2vr_##ssuffix((ctype_s)v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v256_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v256_setall_##suffix(v); } \
OPENCV_HAL_IMPL_LASX_CAST(_Tpvec, v_uint8x32, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_LASX_CAST(_Tpvec, v_int8x32, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_LASX_CAST(_Tpvec, v_uint16x16, suffix, OPENCV_HAL_NOP) \
@ -588,7 +592,11 @@ inline __m256d _lasx_256_castsi256_pd(const __m256i &v)
inline _Tpvec v256_setzero_##suffix() \
{ return _Tpvec(__lasx_xvreplgr2vr_d(0)); } \
inline _Tpvec v256_setall_##suffix(_Tp v) \
{ return _Tpvec(_v256_setall_##zsuffix(v)); } \
{ return _Tpvec(_v256_setall_##zsuffix(v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v256_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v256_setall_##suffix(v); } \
OPENCV_HAL_IMPL_LASX_CAST(_Tpvec, v_uint8x32, suffix, cast) \
OPENCV_HAL_IMPL_LASX_CAST(_Tpvec, v_int8x32, suffix, cast) \
OPENCV_HAL_IMPL_LASX_CAST(_Tpvec, v_uint16x16, suffix, cast) \
@ -3005,6 +3013,20 @@ inline void v_pack_store(hfloat* ptr, const v_float32x8& a)
inline void v256_cleanup() {}
#include "intrin_math.hpp"
inline v_float32x8 v_exp(const v_float32x8& x) { return v_exp_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float32x8 v_log(const v_float32x8& x) { return v_log_default_32f<v_float32x8, v_int32x8>(x); }
inline void v_sincos(const v_float32x8& x, v_float32x8& s, v_float32x8& c) { v_sincos_default_32f<v_float32x8, v_int32x8>(x, s, c); }
inline v_float32x8 v_sin(const v_float32x8& x) { return v_sin_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float32x8 v_cos(const v_float32x8& x) { return v_cos_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float32x8 v_erf(const v_float32x8& x) { return v_erf_default_32f<v_float32x8, v_int32x8>(x); }
inline v_float64x4 v_exp(const v_float64x4& x) { return v_exp_default_64f<v_float64x4, v_int64x4>(x); }
inline v_float64x4 v_log(const v_float64x4& x) { return v_log_default_64f<v_float64x4, v_int64x4>(x); }
inline void v_sincos(const v_float64x4& x, v_float64x4& s, v_float64x4& c) { v_sincos_default_64f<v_float64x4, v_int64x4>(x, s, c); }
inline v_float64x4 v_sin(const v_float64x4& x) { return v_sin_default_64f<v_float64x4, v_int64x4>(x); }
inline v_float64x4 v_cos(const v_float64x4& x) { return v_cos_default_64f<v_float64x4, v_int64x4>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -417,6 +417,10 @@ inline __m128i _lsx_128_castpd_si128(const __m128d& v)
{ return _Tpvec(__lsx_vldi(0)); } \
inline _Tpvec v_setall_##suffix(_Tp v) \
{ return _Tpvec(__lsx_vreplgr2vr_##ssuffix((ctype_s)v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v_setall_##suffix(v); } \
OPENCV_HAL_IMPL_LSX_CAST(_Tpvec, v_uint8x16, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_LSX_CAST(_Tpvec, v_int8x16, suffix, OPENCV_HAL_NOP) \
OPENCV_HAL_IMPL_LSX_CAST(_Tpvec, v_uint16x8, suffix, OPENCV_HAL_NOP) \
@ -448,6 +452,10 @@ inline __m128d _lsx_128_castsi128_pd(const __m128i &v)
{ return _Tpvec(__lsx_vldi(0)); } \
inline _Tpvec v_setall_##suffix(_Tp v) \
{ return _Tpvec(_v128_setall_##zsuffix(v)); } \
template <> inline _Tpvec v_setzero_() \
{ return v_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) \
{ return v_setall_##suffix(v); } \
OPENCV_HAL_IMPL_LSX_CAST(_Tpvec, v_uint8x16, suffix, cast) \
OPENCV_HAL_IMPL_LSX_CAST(_Tpvec, v_int8x16, suffix, cast) \
OPENCV_HAL_IMPL_LSX_CAST(_Tpvec, v_uint16x8, suffix, cast) \
@ -2515,6 +2523,20 @@ inline void v_pack_store(hfloat* ptr, const v_float32x4& a)
inline void v_cleanup() {}
#include "intrin_math.hpp"
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

File diff suppressed because it is too large Load Diff

View File

@ -235,6 +235,8 @@ struct v_float64x2
#define OPENCV_HAL_IMPL_MSA_INIT(_Tpv, _Tp, suffix) \
inline v_##_Tpv v_setzero_##suffix() { return v_##_Tpv(msa_dupq_n_##suffix((_Tp)0)); } \
inline v_##_Tpv v_setall_##suffix(_Tp v) { return v_##_Tpv(msa_dupq_n_##suffix(v)); } \
template <> inline v_##_Tpv v_setzero_() { return v_setzero_##suffix(); } \
template <> inline v_##_Tpv v_setall_(_Tp v) { return v_setall_##suffix(v); } \
inline v_uint8x16 v_reinterpret_as_u8(const v_##_Tpv& v) { return v_uint8x16(MSA_TPV_REINTERPRET(v16u8, v.val)); } \
inline v_int8x16 v_reinterpret_as_s8(const v_##_Tpv& v) { return v_int8x16(MSA_TPV_REINTERPRET(v16i8, v.val)); } \
inline v_uint16x8 v_reinterpret_as_u16(const v_##_Tpv& v) { return v_uint16x8(MSA_TPV_REINTERPRET(v8u16, v.val)); } \
@ -1861,6 +1863,20 @@ inline void v_pack_store(hfloat* ptr, const v_float32x4& v)
inline void v_cleanup() {}
#include "intrin_math.hpp"
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -414,6 +414,8 @@ private:
#define OPENCV_HAL_IMPL_NEON_INIT(_Tpv, _Tp, _TpCast, suffix) \
inline v_##_Tpv v_setzero_##suffix() { return v_##_Tpv(vdupq_n_##suffix((_TpCast)0)); } \
inline v_##_Tpv v_setall_##suffix(_Tp v) { return v_##_Tpv(vdupq_n_##suffix((_TpCast)v)); } \
template <> inline v_##_Tpv v_setzero_() { return v_setzero_##suffix(); } \
template <> inline v_##_Tpv v_setall_(_Tp v) { return v_setall_##suffix(v); } \
inline _Tpv##_t vreinterpretq_##suffix##_##suffix(_Tpv##_t v) { return v; } \
inline v_uint8x16 v_reinterpret_as_u8(const v_##_Tpv& v) { return v_uint8x16(vreinterpretq_u8_##suffix(v.val)); } \
inline v_int8x16 v_reinterpret_as_s8(const v_##_Tpv& v) { return v_int8x16(vreinterpretq_s8_##suffix(v.val)); } \
@ -435,6 +437,7 @@ OPENCV_HAL_IMPL_NEON_INIT(uint64x2, uint64, uint64, u64)
OPENCV_HAL_IMPL_NEON_INIT(int64x2, int64, int64, s64)
#if CV_SIMD128_FP16
OPENCV_HAL_IMPL_NEON_INIT(float16x8, hfloat, __fp16, f16);
template <> inline v_float16x8 v_setall_(float v) { return v_setall_f16((hfloat)v); }
#define OPENCV_HAL_IMPL_NEON_INIT_FP16(_Tpv, suffix) \
inline v_float16x8 v_reinterpret_as_f16(const v_##_Tpv& v) { return v_float16x8(vreinterpretq_f16_##suffix(v.val)); }
OPENCV_HAL_IMPL_NEON_INIT_FP16(uint8x16, u8)
@ -3030,6 +3033,28 @@ inline void v_pack_store(hfloat* ptr, const v_float32x4& v)
inline void v_cleanup() {}
#include "intrin_math.hpp"
#if CV_SIMD128_FP16
inline v_float16x8 v_exp(const v_float16x8& x) { return v_exp_default_16f<v_float16x8, v_int16x8>(x); }
inline v_float16x8 v_log(const v_float16x8& x) { return v_log_default_16f<v_float16x8, v_int16x8>(x); }
inline void v_sincos(const v_float16x8& x, v_float16x8& s, v_float16x8& c) { v_sincos_default_16f<v_float16x8, v_int16x8>(x, s, c); }
inline v_float16x8 v_sin(const v_float16x8& x) { return v_sin_default_16f<v_float16x8, v_int16x8>(x); }
inline v_float16x8 v_cos(const v_float16x8& x) { return v_cos_default_16f<v_float16x8, v_int16x8>(x); }
#endif
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
#if CV_SIMD128_64F
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
#endif
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -355,10 +355,12 @@ inline v_float64x2 v_reinterpret_as_f64(const v_float64x2& v) { return v_float64
#define OPENCV_HAL_IMPL_RISCVV_INIT_SET(__Tp, _Tp, suffix, len, num) \
inline v_##_Tp##x##num v_setzero_##suffix() { return v_##_Tp##x##num(vmv_v_x_##len##m1(0, num)); } \
inline v_##_Tp##x##num v_setall_##suffix(__Tp v) { return v_##_Tp##x##num(vmv_v_x_##len##m1(v, num)); }
inline v_##_Tp##x##num v_setall_##suffix(__Tp v) { return v_##_Tp##x##num(vmv_v_x_##len##m1(v, num)); } \
template <> inline v_##_Tp##x##num v_setzero_() { return v_setzero_##suffix(); } \
template <> inline v_##_Tp##x##num v_setall_(__Tp v) { return v_setall_##suffix(v); }
OPENCV_HAL_IMPL_RISCVV_INIT_SET(uchar, uint8, u8, u8, 16)
OPENCV_HAL_IMPL_RISCVV_INIT_SET(char, int8, s8, i8, 16)
OPENCV_HAL_IMPL_RISCVV_INIT_SET(schar, int8, s8, i8, 16)
OPENCV_HAL_IMPL_RISCVV_INIT_SET(ushort, uint16, u16, u16, 8)
OPENCV_HAL_IMPL_RISCVV_INIT_SET(short, int16, s16, i16, 8)
OPENCV_HAL_IMPL_RISCVV_INIT_SET(unsigned int, uint32, u32, u32, 4)
@ -371,6 +373,11 @@ inline v_float32x4 v_setall_f32(float v) { return v_float32x4(vfmv_v_f_f32m1(v,
inline v_float64x2 v_setzero_f64() { return v_float64x2(vfmv_v_f_f64m1(0, 2)); }
inline v_float64x2 v_setall_f64(double v) { return v_float64x2(vfmv_v_f_f64m1(v, 2)); }
template <> inline v_float32x4 v_setzero_() { return v_setzero_f32(); }
template <> inline v_float32x4 v_setall_(float v) { return v_setall_f32(v); }
template <> inline v_float64x2 v_setzero_() { return v_setzero_f64(); }
template <> inline v_float64x2 v_setall_(double v) { return v_setall_f64(v); }
#define OPENCV_HAL_IMPL_RISCVV_BIN_OP(bin_op, _Tpvec, intrin) \
inline _Tpvec bin_op(const _Tpvec& a, const _Tpvec& b) \
@ -2859,6 +2866,20 @@ inline void v_pack_store(hfloat* ptr, const v_float32x4& v)
inline void v_cleanup() {}
#include "intrin_math.hpp"
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -182,6 +182,14 @@ inline v_##_Tpvec v_setzero_##suffix1() \
inline v_##_Tpvec v_setall_##suffix1(_Tp v) \
{ \
return __riscv_vmv_v_x_##suffix2##m1(v, vl); \
} \
template <> inline v_##_Tpvec v_setzero_() \
{ \
return v_setzero_##suffix1(); \
} \
template <> inline v_##_Tpvec v_setall_(_Tp v) \
{ \
return v_setall_##suffix1(v); \
}
OPENCV_HAL_IMPL_RVV_INIT_INTEGER(uint8, uchar, u8, u8, VTraits<v_int8>::vlanes())
@ -201,6 +209,14 @@ inline v_##_Tpv v_setzero_##suffix() \
inline v_##_Tpv v_setall_##suffix(_Tp v) \
{ \
return __riscv_vfmv_v_f_##suffix##m1(v, vl); \
} \
template <> inline v_##_Tpv v_setzero_() \
{ \
return v_setzero_##suffix(); \
} \
template <> inline v_##_Tpv v_setall_(_Tp v) \
{ \
return v_setall_##suffix(v); \
}
#if CV_SIMD_SCALABLE_FP16
@ -2471,6 +2487,20 @@ inline v_float32 v_matmuladd(const v_float32& v, const v_float32& m0,
inline void v_cleanup() {}
#include "intrin_math.hpp"
inline v_float32 v_exp(const v_float32& x) { return v_exp_default_32f<v_float32, v_int32>(x); }
inline v_float32 v_log(const v_float32& x) { return v_log_default_32f<v_float32, v_int32>(x); }
inline void v_sincos(const v_float32& x, v_float32& s, v_float32& c) { v_sincos_default_32f<v_float32, v_int32>(x, s, c); }
inline v_float32 v_sin(const v_float32& x) { return v_sin_default_32f<v_float32, v_int32>(x); }
inline v_float32 v_cos(const v_float32& x) { return v_cos_default_32f<v_float32, v_int32>(x); }
inline v_float32 v_erf(const v_float32& x) { return v_erf_default_32f<v_float32, v_int32>(x); }
inline v_float64 v_exp(const v_float64& x) { return v_exp_default_64f<v_float64, v_int64>(x); }
inline v_float64 v_log(const v_float64& x) { return v_log_default_64f<v_float64, v_int64>(x); }
inline void v_sincos(const v_float64& x, v_float64& s, v_float64& c) { v_sincos_default_64f<v_float64, v_int64>(x, s, c); }
inline v_float64 v_sin(const v_float64& x) { return v_sin_default_64f<v_float64, v_int64>(x); }
inline v_float64 v_cos(const v_float64& x) { return v_cos_default_64f<v_float64, v_int64>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -347,6 +347,8 @@ namespace hal_sse_internal
#define OPENCV_HAL_IMPL_SSE_INITVEC(_Tpvec, _Tp, suffix, zsuffix, ssuffix, _Tps, cast) \
inline _Tpvec v_setzero_##suffix() { return _Tpvec(_mm_setzero_##zsuffix()); } \
inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(_mm_set1_##ssuffix((_Tps)v)); } \
template <> inline _Tpvec v_setzero_() { return v_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) { return v_setall_##suffix(v); } \
template<typename _Tpvec0> inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0& a) \
{ return _Tpvec(cast(a.val)); }
@ -364,6 +366,11 @@ inline v_int64x2 v_setzero_s64() { return v_int64x2(_mm_setzero_si128()); }
inline v_uint64x2 v_setall_u64(uint64 val) { return v_uint64x2(val, val); }
inline v_int64x2 v_setall_s64(int64 val) { return v_int64x2(val, val); }
template <> inline v_uint64x2 v_setzero_() { return v_setzero_u64(); }
template <> inline v_int64x2 v_setzero_() { return v_setzero_s64(); }
template <> inline v_uint64x2 v_setall_(uint64 val) { return v_setall_u64(val); }
template <> inline v_int64x2 v_setall_(int64 val) { return v_setall_s64(val); }
template<typename _Tpvec> inline
v_uint64x2 v_reinterpret_as_u64(const _Tpvec& a) { return v_uint64x2(a.val); }
template<typename _Tpvec> inline
@ -3462,6 +3469,21 @@ inline void v_pack_store(hfloat* ptr, const v_float32x4& v)
inline void v_cleanup() {}
#include "intrin_math.hpp"
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -261,6 +261,8 @@ OPENCV_HAL_IMPL_VSX_EXTRACT_N(v_float64x2, double)
#define OPENCV_HAL_IMPL_VSX_INITVEC(_Tpvec, _Tp, suffix, cast) \
inline _Tpvec v_setzero_##suffix() { return _Tpvec(vec_splats((_Tp)0)); } \
inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(vec_splats((_Tp)v));} \
template <> inline _Tpvec v_setzero_() { return v_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) { return v_setall_##suffix(_Tp v); } \
template<typename _Tpvec0> inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0 &a) \
{ return _Tpvec((cast)a.val); }
@ -1594,6 +1596,19 @@ template<int i, typename Tvec>
inline Tvec v_broadcast_element(const Tvec& v)
{ return Tvec(vec_splat(v.val, i)); }
#include "intrin_math.hpp"
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END

View File

@ -8,9 +8,18 @@
#include <limits>
#include <cstring>
#include <algorithm>
#include <emscripten/version.h>
#include "opencv2/core/saturate.hpp"
// Emscripten v2.0.13 (latest officially supported, as of 07/30/2024):
// __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__ and __EMSCRIPTEN_tiny__ are defined via commandline in
// https://github.com/emscripten-core/emscripten/blob/1690a5802cd1241adc9714fb7fa2f633d38860dc/tools/shared.py#L506-L515
//
// See https://github.com/opencv/opencv/pull/25909
#ifndef __EMSCRIPTEN_major__
#include <emscripten/version.h>
#endif
#define CV_SIMD128 1
#define CV_SIMD128_64F 0 // Now all implementation of f64 use fallback, so disable it.
#define CV_SIMD128_FP16 0
@ -392,6 +401,8 @@ inline v128_t v128_cvti32x4_i64x2_high(const v128_t& a)
#define OPENCV_HAL_IMPL_WASM_INITVEC(_Tpvec, _Tp, suffix, zsuffix, _Tps) \
inline _Tpvec v_setzero_##suffix() { return _Tpvec(wasm_##zsuffix##_splat((_Tps)0)); } \
inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(wasm_##zsuffix##_splat((_Tps)v)); } \
template <> inline _Tpvec v_setzero_() { return v_setzero_##suffix(); } \
template <> inline _Tpvec v_setall_(_Tp v) { return v_setall_##suffix(v); } \
template<typename _Tpvec0> inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0& a) \
{ return _Tpvec(a.val); }
@ -2767,6 +2778,20 @@ inline void v_pack_store(hfloat* ptr, const v_float32x4& v)
inline void v_cleanup() {}
#include "intrin_math.hpp"
inline v_float32x4 v_exp(const v_float32x4& x) { return v_exp_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_log(const v_float32x4& x) { return v_log_default_32f<v_float32x4, v_int32x4>(x); }
inline void v_sincos(const v_float32x4& x, v_float32x4& s, v_float32x4& c) { v_sincos_default_32f<v_float32x4, v_int32x4>(x, s, c); }
inline v_float32x4 v_sin(const v_float32x4& x) { return v_sin_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_cos(const v_float32x4& x) { return v_cos_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float32x4 v_erf(const v_float32x4& x) { return v_erf_default_32f<v_float32x4, v_int32x4>(x); }
inline v_float64x2 v_exp(const v_float64x2& x) { return v_exp_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_log(const v_float64x2& x) { return v_log_default_64f<v_float64x2, v_int64x2>(x); }
inline void v_sincos(const v_float64x2& x, v_float64x2& s, v_float64x2& c) { v_sincos_default_64f<v_float64x2, v_int64x2>(x, s, c); }
inline v_float64x2 v_sin(const v_float64x2& x) { return v_sin_default_64f<v_float64x2, v_int64x2>(x); }
inline v_float64x2 v_cos(const v_float64x2& x) { return v_cos_default_64f<v_float64x2, v_int64x2>(x); }
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond

View File

@ -568,6 +568,22 @@ typedef OutputArray OutputArrayOfArrays;
typedef const _InputOutputArray& InputOutputArray;
typedef InputOutputArray InputOutputArrayOfArrays;
/** @brief Returns an empty InputArray or OutputArray.
This function is used to provide an "empty" or "null" array when certain functions
take optional input or output arrays that you don't want to provide.
Many OpenCV functions accept optional arguments as `cv::InputArray` or `cv::OutputArray`.
When you don't want to pass any data for these optional parameters, you can use `cv::noArray()`
to indicate that you are omitting them.
@return An empty `cv::InputArray` or `cv::OutputArray` that can be used as a placeholder.
@note This is often used when a function has optional arrays, and you do not want to
provide a specific input or output array.
@see cv::InputArray, cv::OutputArray
*/
CV_EXPORTS InputOutputArray noArray();
/////////////////////////////////// MatAllocator //////////////////////////////////////

View File

@ -155,10 +155,10 @@ inline Size _InputArray::getSz() const { return sz; }
inline _InputArray::_InputArray() { init(0 + NONE, 0); }
inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }
inline _InputArray::_InputArray(const Mat& m) { init(+MAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(+STD_VECTOR_MAT+ACCESS_READ, &vec); }
inline _InputArray::_InputArray(const UMat& m) { init(+UMAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(+STD_VECTOR_UMAT+ACCESS_READ, &vec); }
template<typename _Tp> inline
_InputArray::_InputArray(const std::vector<_Tp>& vec)
@ -170,7 +170,7 @@ _InputArray::_InputArray(const std::array<_Tp, _Nm>& arr)
template<std::size_t _Nm> inline
_InputArray::_InputArray(const std::array<Mat, _Nm>& arr)
{ init(STD_ARRAY_MAT + ACCESS_READ, arr.data(), Size(1, _Nm)); }
{ init(+STD_ARRAY_MAT + ACCESS_READ, arr.data(), Size(1, _Nm)); }
inline
_InputArray::_InputArray(const std::vector<bool>& vec)
@ -200,16 +200,16 @@ inline _InputArray::_InputArray(const double& val)
{ init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); }
inline _InputArray::_InputArray(const cuda::GpuMat& d_mat)
{ init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
{ init(+CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
inline _InputArray::_InputArray(const std::vector<cuda::GpuMat>& d_mat)
{ init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);}
{ init(+STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);}
inline _InputArray::_InputArray(const ogl::Buffer& buf)
{ init(OPENGL_BUFFER + ACCESS_READ, &buf); }
{ init(+OPENGL_BUFFER + ACCESS_READ, &buf); }
inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
{ init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
{ init(+CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
template<typename _Tp> inline
_InputArray _InputArray::rawIn(const std::vector<_Tp>& vec)
@ -253,12 +253,12 @@ inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::
////////////////////////////////////////////////////////////////////////////////////////
inline _OutputArray::_OutputArray() { init(NONE + ACCESS_WRITE, 0); }
inline _OutputArray::_OutputArray() { init(+NONE + ACCESS_WRITE, 0); }
inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags + ACCESS_WRITE, _obj); }
inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(UMat& m) { init(UMAT + ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(Mat& m) { init(+MAT+ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(+STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(UMat& m) { init(+UMAT + ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(+STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
template<typename _Tp> inline
_OutputArray::_OutputArray(std::vector<_Tp>& vec)
@ -270,7 +270,7 @@ _OutputArray::_OutputArray(std::array<_Tp, _Nm>& arr)
template<std::size_t _Nm> inline
_OutputArray::_OutputArray(std::array<Mat, _Nm>& arr)
{ init(STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)); }
{ init(+STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)); }
template<typename _Tp> inline
_OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
@ -325,16 +325,16 @@ _OutputArray::_OutputArray(const _Tp* vec, int n)
{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); }
inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat)
{ init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
{ init(+CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
inline _OutputArray::_OutputArray(std::vector<cuda::GpuMat>& d_mat)
{ init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);}
{ init(+STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);}
inline _OutputArray::_OutputArray(ogl::Buffer& buf)
{ init(OPENGL_BUFFER + ACCESS_WRITE, &buf); }
{ init(+OPENGL_BUFFER + ACCESS_WRITE, &buf); }
inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem)
{ init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
{ init(+CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
inline _OutputArray::_OutputArray(const Mat& m)
{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); }
@ -403,10 +403,10 @@ std::vector<std::vector<_Tp> >& _OutputArray::getVecVecRef() const
inline _InputOutputArray::_InputOutputArray() { init(0+ACCESS_RW, 0); }
inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags+ACCESS_RW, _obj); }
inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); }
inline _InputOutputArray::_InputOutputArray(Mat& m) { init(+MAT+ACCESS_RW, &m); }
inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(+STD_VECTOR_MAT+ACCESS_RW, &vec); }
inline _InputOutputArray::_InputOutputArray(UMat& m) { init(+UMAT+ACCESS_RW, &m); }
inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(+STD_VECTOR_UMAT+ACCESS_RW, &vec); }
template<typename _Tp> inline
_InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
@ -418,7 +418,7 @@ _InputOutputArray::_InputOutputArray(std::array<_Tp, _Nm>& arr)
template<std::size_t _Nm> inline
_InputOutputArray::_InputOutputArray(std::array<Mat, _Nm>& arr)
{ init(STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)); }
{ init(+STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)); }
template<typename _Tp> inline
_InputOutputArray::_InputOutputArray(std::vector<std::vector<_Tp> >& vec)
@ -473,13 +473,13 @@ _InputOutputArray::_InputOutputArray(const _Tp* vec, int n)
{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); }
inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat)
{ init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
{ init(+CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf)
{ init(OPENGL_BUFFER + ACCESS_RW, &buf); }
{ init(+OPENGL_BUFFER + ACCESS_RW, &buf); }
inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem)
{ init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
{ init(+CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
inline _InputOutputArray::_InputOutputArray(const Mat& m)
{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); }
@ -622,7 +622,7 @@ Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
template<typename _Tp, int m, int n> inline
Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
if( !copyData )

View File

@ -524,7 +524,7 @@ The generic function partition implements an \f$O(N^2)\f$ algorithm for splittin
into one or more equivalency classes, as described in
<http://en.wikipedia.org/wiki/Disjoint-set_data_structure> . The function returns the number of
equivalency classes.
@param _vec Set of elements stored as a vector.
@param vec Set of elements stored as a vector.
@param labels Output vector of labels. It contains as many elements as vec. Each label labels[i] is
a 0-based cluster index of `vec[i]`.
@param predicate Equivalence predicate (pointer to a boolean function of two arguments or an
@ -534,11 +534,11 @@ may or may not be in the same class.
@ingroup core_cluster
*/
template<typename _Tp, class _EqPredicate> int
partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
partition( const std::vector<_Tp>& vec, std::vector<int>& labels,
_EqPredicate predicate=_EqPredicate())
{
int i, j, N = (int)_vec.size();
const _Tp* vec = &_vec[0];
int i, j, N = (int)vec.size();
const _Tp* _vec = &vec[0];
const int PARENT=0;
const int RANK=1;
@ -564,7 +564,7 @@ partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
for( j = 0; j < N; j++ )
{
if( i == j || !predicate(vec[i], vec[j]))
if( i == j || !predicate(_vec[i], _vec[j]))
continue;
int root2 = j;

View File

@ -53,50 +53,6 @@
# error persistence.hpp header must be compiled as C++
#endif
//! @addtogroup core_c
//! @{
/** @brief "black box" representation of the file storage associated with a file on disk.
Several functions that are described below take CvFileStorage\* as inputs and allow the user to
save or to load hierarchical collections that consist of scalar values, standard CXCore objects
(such as matrices, sequences, graphs), and user-defined objects.
OpenCV can read and write data in XML (<http://www.w3c.org/XML>), YAML (<http://www.yaml.org>) or
JSON (<http://www.json.org/>) formats. Below is an example of 3x3 floating-point identity matrix A,
stored in XML and YAML files
using CXCore functions:
XML:
@code{.xml}
<?xml version="1.0">
<opencv_storage>
<A type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>f</dt>
<data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data>
</A>
</opencv_storage>
@endcode
YAML:
@code{.yaml}
%YAML:1.0
A: !!opencv-matrix
rows: 3
cols: 3
dt: f
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
@endcode
As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses
indentation for that purpose (similar to the Python programming language).
The same functions can read and write data in both formats; the particular format is determined by
the extension of the opened file, ".xml" for XML files, ".yml" or ".yaml" for YAML and ".json" for
JSON.
*/
//! @} core_c
#include "opencv2/core/types.hpp"
#include "opencv2/core/mat.hpp"
@ -283,13 +239,14 @@ element is a structure of 2 integers, followed by a single-precision floating-po
equivalent notations of the above specification are `iif`, `2i1f` and so forth. Other examples: `u`
means that the array consists of bytes, and `2d` means the array consists of pairs of doubles.
@see @ref samples/cpp/filestorage.cpp
@see @ref samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp
*/
//! @{
/** @example samples/cpp/filestorage.cpp
/** @example samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp
A complete example using the FileStorage interface
Check @ref tutorial_file_input_output_with_xml_yml "the corresponding tutorial" for more details
*/
////////////////////////// XML & YAML I/O //////////////////////////
@ -322,10 +279,10 @@ public:
};
enum State
{
UNDEFINED = 0,
VALUE_EXPECTED = 1,
NAME_EXPECTED = 2,
INSIDE_MAP = 4
UNDEFINED = 0, //!< Initial or uninitialized state.
VALUE_EXPECTED = 1, //!< Expecting a value in the current position.
NAME_EXPECTED = 2, //!< Expecting a key/name in the current position.
INSIDE_MAP = 4 //!< Indicates being inside a map (a set of key-value pairs).
};
/** @brief The constructors.

View File

@ -134,6 +134,36 @@ namespace cv { namespace cuda
template<> struct NPPTypeTraits<CV_32F> { typedef Npp32f npp_type; };
template<> struct NPPTypeTraits<CV_64F> { typedef Npp64f npp_type; };
#define nppSafeCall(expr) cv::cuda::checkNppError(expr, __FILE__, __LINE__, CV_Func)
// NppStreamContext is introduced in NPP version 10100 included in CUDA toolkit 10.1 (CUDA_VERSION == 10010) however not all of the NPP functions called internally by OpenCV
// - have an NppStreamContext argument (e.g. nppiHistogramEvenGetBufferSize_8u_C1R_Ctx in CUDA 12.3) and/or
// - have a corresponding function in the supplied library (e.g. nppiEvenLevelsHost_32s_Ctx is not present in nppist.lib or libnppist.so as of CUDA 12.6)
// Because support for these functions has gradually been introduced without being mentioned in the release notes this flag is set to a version of NPP (version 12205 included in CUDA toolkit 12.4) which is known to work.
#define USE_NPP_STREAM_CTX NPP_VERSION >= 12205
#if USE_NPP_STREAM_CTX
class NppStreamHandler
{
public:
inline explicit NppStreamHandler(cudaStream_t newStream)
{
nppStreamContext = {};
nppSafeCall(nppGetStreamContext(&nppStreamContext));
nppStreamContext.hStream = newStream;
cudaSafeCall(cudaStreamGetFlags(nppStreamContext.hStream, &nppStreamContext.nStreamFlags));
}
inline explicit NppStreamHandler(Stream& newStream) : NppStreamHandler(StreamAccessor::getStream(newStream)) {}
inline operator NppStreamContext() const {
return nppStreamContext;
}
inline NppStreamContext get() { return nppStreamContext; }
private:
NppStreamContext nppStreamContext;
};
#else
class NppStreamHandler
{
public:
@ -157,9 +187,9 @@ namespace cv { namespace cuda
private:
cudaStream_t oldStream;
};
#endif
}}
#define nppSafeCall(expr) cv::cuda::checkNppError(expr, __FILE__, __LINE__, CV_Func)
#define cuSafeCall(expr) cv::cuda::checkCudaDriverApiError(expr, __FILE__, __LINE__, CV_Func)
#endif // HAVE_CUDA

View File

@ -31,7 +31,7 @@
#include <iostream>
namespace cv
{
//! @addtogroup core
//! @addtogroup core_quaternion
//! @{
//! Unit quaternion flag

View File

@ -176,7 +176,38 @@ extern "C" typedef int (*ErrorCallback)( int status, const char* func_name,
*/
CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, void* userdata=0, void** prevUserdata=0);
/** @brief Generates a unique temporary file name.
This function generates a full, unique file path for a temporary file,
which can be used to create temporary files for various purposes.
@param suffix (optional) The desired file extension or suffix for the temporary file (e.g., ".png", ".txt").
If no suffix is provided (suffix = 0), the file will not have a specific extension.
@return cv::String A full unique path for the temporary file.
@note
- The function does not create the file, it only generates the name.
- The file name is unique for the system session.
- Works cross-platform (Windows, Linux, macOS).
*/
CV_EXPORTS String tempfile( const char* suffix = 0);
/** @brief Searches for files matching the specified pattern in a directory.
This function searches for files that match a given pattern (e.g., `*.jpg`)
in the specified directory. The search can be limited to the directory itself
or be recursive, including subdirectories.
@param pattern The file search pattern, which can include wildcards like `*`
(for matching multiple characters) or `?` (for matching a single character).
@param result Output vector where the file paths matching the search
pattern will be stored.
@param recursive (optional) Boolean flag indicating whether to search
subdirectories recursively. If true, the search will include all subdirectories.
The default value is `false`.
*/
CV_EXPORTS void glob(String pattern, std::vector<String>& result, bool recursive = false);
/** @brief OpenCV will try to set the number of threads for subsequent parallel regions.
@ -309,11 +340,12 @@ public:
//! stops counting ticks.
CV_WRAP void stop()
{
int64 time = cv::getTickCount();
const int64 time = cv::getTickCount();
if (startTime == 0)
return;
++counter;
sumTime += (time - startTime);
lastTime = time - startTime;
sumTime += lastTime;
startTime = 0;
}
@ -336,11 +368,35 @@ public:
}
//! returns passed time in seconds.
CV_WRAP double getTimeSec() const
CV_WRAP double getTimeSec() const
{
return (double)getTimeTicks() / getTickFrequency();
}
//! returns counted ticks of the last iteration.
CV_WRAP int64 getLastTimeTicks() const
{
return lastTime;
}
//! returns passed time of the last iteration in microseconds.
CV_WRAP double getLastTimeMicro() const
{
return getLastTimeMilli()*1e3;
}
//! returns passed time of the last iteration in milliseconds.
CV_WRAP double getLastTimeMilli() const
{
return getLastTimeSec()*1e3;
}
//! returns passed time of the last iteration in seconds.
CV_WRAP double getLastTimeSec() const
{
return (double)getLastTimeTicks() / getTickFrequency();
}
//! returns internal counter value.
CV_WRAP int64 getCounter() const
{
@ -373,15 +429,17 @@ public:
//! resets internal values.
CV_WRAP void reset()
{
startTime = 0;
sumTime = 0;
counter = 0;
sumTime = 0;
startTime = 0;
lastTime = 0;
}
private:
int64 counter;
int64 sumTime;
int64 startTime;
int64 lastTime;
};
/** @brief output operator

View File

@ -42,6 +42,12 @@
#include "precomp.hpp"
#if defined (__APPLE__) || defined(MACOSX)
#define GL_SHARING_EXTENSION "cl_APPLE_gl_sharing"
#else
#define GL_SHARING_EXTENSION "cl_khr_gl_sharing"
#endif
#ifdef HAVE_OPENGL
# include "gl_core_3_1.hpp"
# ifdef HAVE_CUDA
@ -1635,94 +1641,148 @@ Context& initializeContextFromGL()
#elif !defined(HAVE_OPENCL_OPENGL_SHARING)
NO_OPENCL_SHARING_ERROR;
#else
cl_uint numPlatforms;
cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
cl_uint platformsCnt = 0;
cl_uint devCnt = 0;
cl_device_id* devices = nullptr;
cl_uint devUsed = 0;
cl_context context = nullptr;
cl_int status = clGetPlatformIDs(0, NULL, &platformsCnt);
if (status != CL_SUCCESS)
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status));
if (numPlatforms == 0)
if (platformsCnt == 0)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
std::vector<cl_platform_id> platforms(numPlatforms);
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
std::vector<cl_platform_id> platforms(platformsCnt);
status = clGetPlatformIDs(platformsCnt, &platforms[0], NULL);
if (status != CL_SUCCESS)
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get number of platforms: %d", status));
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platforms: %d", status));
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
bool sharingSupported = false;
int found = -1;
cl_device_id device = NULL;
cl_context context = NULL;
for (unsigned int i = 0; (!sharingSupported && (i < platformsCnt)); ++i) {
status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, 0, NULL, &devCnt);
if (status != CL_SUCCESS)
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: No devices available: %d", status));
for (int i = 0; i < (int)numPlatforms; i++)
{
// query platform extension: presence of "cl_khr_gl_sharing" extension is required
{
AutoBuffer<char> extensionStr;
try {
devices = new cl_device_id[devCnt];
size_t extensionSize;
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &extensionSize);
if (status == CL_SUCCESS)
{
extensionStr.allocate(extensionSize+1);
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, extensionSize, (char*)extensionStr.data(), NULL);
}
status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, devCnt, devices, NULL);
if (status != CL_SUCCESS)
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform extension string: %d", status));
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't get platform devices: %d", status));
if (!strstr((const char*)extensionStr.data(), "cl_khr_gl_sharing"))
continue;
for (unsigned int j = 0; (!sharingSupported && (j < devCnt)); ++j) {
size_t extensionSize;
status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
if (status != CL_SUCCESS)
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: No devices available: %d", status));
if(extensionSize > 0)
{
char* extensions = nullptr;
try {
extensions = new char[extensionSize];
status = clGetDeviceInfo(devices[j], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize);
if (status != CL_SUCCESS)
continue;
} catch(...) {
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Exception thrown during device extensions gathering");
}
std::string devString;
if(extensions != nullptr) {
devString = extensions;
delete[] extensions;
}
else {
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Unexpected error during device extensions gathering");
}
size_t oldPos = 0;
size_t spacePos = devString.find(' ', oldPos); // extensions string is space delimited
while (spacePos != devString.npos) {
if (strcmp(GL_SHARING_EXTENSION,
devString.substr(oldPos, spacePos - oldPos).c_str())
== 0) {
// Device supports context sharing with OpenGL
devUsed = i;
sharingSupported = true;
break;
}
do {
oldPos = spacePos + 1;
spacePos = devString.find(' ', oldPos);
} while (spacePos == oldPos);
}
}
}
} catch(...) {
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Exception thrown during device information gathering");
if(devices != nullptr) {
delete[] devices;
}
continue;
}
clGetGLContextInfoKHR_fn clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetGLContextInfoKHR");
if (!clGetGLContextInfoKHR)
continue;
cl_context_properties properties[] =
{
#if defined(_WIN32)
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
if (sharingSupported) {
// Define OS-specific context properties and create the OpenCL context
#if defined (__APPLE__)
CGLContextObj cglContext = CGLGetCurrentContext();
CGLShareGroupObj cglShareGroup = CGLGetShareGroup(cglContext);
cl_context_properties props[] =
{
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)cglShareGroup,
0
};
context = clCreateContext(props, 0,0, NULL, NULL, &ciErrNum);
#elif defined(__ANDROID__)
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_GL_CONTEXT_KHR, (cl_context_properties)eglGetCurrentContext(),
CL_EGL_DISPLAY_KHR, (cl_context_properties)eglGetCurrentDisplay(),
cl_context_properties props[] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
0
};
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status);
#elif defined(_WIN32)
cl_context_properties props[] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
0
};
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status);
#elif defined(__linux__)
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
cl_context_properties props[] =
{
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
0
};
context = clCreateContext(props, 1, &devices[devUsed], NULL, NULL, &status);
#endif
0
};
// query device
device = NULL;
status = clGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), (void*)&device, NULL);
if (status != CL_SUCCESS)
continue;
// create context
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
clReleaseDevice(device);
}
if (status != CL_SUCCESS)
CV_Error_(cv::Error::OpenCLInitError, ("OpenCL: Can't create context for OpenGL interop: %d", status));
else
{
found = i;
break;
}
}
if (found < 0)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for OpenGL interop");
cl_platform_id platform = platforms[found];
cl_platform_id platform = platforms[devUsed];
std::string platformName = PlatformInfo(&platform).name();
OpenCLExecutionContext clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
clReleaseDevice(device);
OpenCLExecutionContext clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, devices[devUsed]);
clReleaseDevice(devices[devUsed]);
clReleaseContext(context);
clExecCtx.bind();
return const_cast<Context&>(clExecCtx.getContext());

View File

@ -307,14 +307,20 @@ template<typename R> struct TheTest
#else
#error "Configuration error"
#endif
R setall_res3 = v_setall_<R>((LaneType)7);
R setall_resz = v_setzero_<R>();
#if CV_SIMD_WIDTH > 0
Data<R> setall_res1_; v_store(setall_res1_.d, setall_res1);
Data<R> setall_res2_; v_store(setall_res2_.d, setall_res2);
Data<R> setall_res3_; v_store(setall_res3_.d, setall_res3);
Data<R> setall_resz_; v_store(setall_resz_.d, setall_resz);
for (int i = 0; i < VTraits<R>::vlanes(); ++i)
{
SCOPED_TRACE(cv::format("i=%d", i));
EXPECT_EQ((LaneType)5, setall_res1_[i]);
EXPECT_EQ((LaneType)6, setall_res2_[i]);
EXPECT_EQ((LaneType)7, setall_res3_[i]);
EXPECT_EQ((LaneType)0, setall_resz_[i]);
}
#endif
@ -2084,6 +2090,100 @@ template<typename R> struct TheTest
return *this;
}
void __test_sincos(LaneType diff_thr, LaneType flt_min) {
int n = VTraits<R>::vlanes();
// Test each value for a period, from -PI to PI
const LaneType step = (LaneType) 0.01;
for (LaneType i = (LaneType)0; i <= (LaneType)M_PI;) {
Data<R> dataPosPI, dataNegPI;
for (int j = 0; j < n; ++j) {
dataPosPI[j] = i;
dataNegPI[j] = LaneType(-1*i);
i = LaneType(i + step);
}
R posPI = dataPosPI, negPI = dataNegPI, sinPos, cosPos, sinNeg, cosNeg;
v_sincos(posPI, sinPos, cosPos);
v_sincos(negPI, sinNeg, cosNeg);
Data<R> resSinPos = sinPos, resCosPos = cosPos, resSinNeg = sinNeg, resCosNeg = cosNeg;
for (int j = 0; j < n; ++j) {
LaneType std_sin_pos = (LaneType) std::sin(dataPosPI[j]);
LaneType std_cos_pos = (LaneType) std::cos(dataPosPI[j]);
LaneType std_sin_neg = (LaneType) std::sin(dataNegPI[j]);
LaneType std_cos_neg = (LaneType) std::cos(dataNegPI[j]);
SCOPED_TRACE(cv::format("Period test value: %lf and %lf", (double) dataPosPI[j], (double) dataNegPI[j]));
EXPECT_LT(std::abs(resSinPos[j] - std_sin_pos), diff_thr * (std::abs(std_sin_pos) + flt_min * 100));
EXPECT_LT(std::abs(resCosPos[j] - std_cos_pos), diff_thr * (std::abs(std_cos_pos) + flt_min * 100));
EXPECT_LT(std::abs(resSinNeg[j] - std_sin_neg), diff_thr * (std::abs(std_sin_neg) + flt_min * 100));
EXPECT_LT(std::abs(resCosNeg[j] - std_cos_neg), diff_thr * (std::abs(std_cos_neg) + flt_min * 100));
}
}
// Test special values
std::vector<LaneType> specialValues = {(LaneType) 0, (LaneType) M_PI, (LaneType) (M_PI / 2), (LaneType) INFINITY, (LaneType) -INFINITY, (LaneType) NAN};
const int testRandNum = 10000;
const double specialValueProbability = 0.1; // 10% chance to insert a special value
cv::RNG_MT19937 rng;
for (int i = 0; i < testRandNum; i++) {
Data<R> dataRand;
for (int j = 0; j < n; ++j) {
if (rng.uniform(0.f, 1.f) <= specialValueProbability) {
// Insert a special value
int specialValueIndex = rng.uniform(0, (int) specialValues.size());
dataRand[j] = specialValues[specialValueIndex];
} else {
// Generate uniform random data in [-1000, 1000]
dataRand[j] = (LaneType) rng.uniform(-1000, 1000);
}
}
// Compare with std::sin and std::cos
R x = dataRand, s, c;
v_sincos(x, s, c);
Data<R> resSin = s, resCos = c;
for (int j = 0; j < n; ++j) {
SCOPED_TRACE(cv::format("Random test value: %lf", (double) dataRand[j]));
LaneType std_sin = (LaneType) std::sin(dataRand[j]);
LaneType std_cos = (LaneType) std::cos(dataRand[j]);
// input NaN, +INF, -INF -> output NaN
if (std::isnan(dataRand[j]) || std::isinf(dataRand[j])) {
EXPECT_TRUE(std::isnan(resSin[j]));
EXPECT_TRUE(std::isnan(resCos[j]));
} else if(dataRand[j] == 0) {
// sin(0) -> 0, cos(0) -> 1
EXPECT_EQ(resSin[j], 0);
EXPECT_EQ(resCos[j], 1);
} else {
EXPECT_LT(std::abs(resSin[j] - std_sin), diff_thr * (std::abs(std_sin) + flt_min * 100));
EXPECT_LT(std::abs(resCos[j] - std_cos), diff_thr * (std::abs(std_cos) + flt_min * 100));
}
}
}
}
// BUG: https://github.com/opencv/opencv/issues/26362
TheTest &test_sincos_fp16() {
#if 0 // CV_SIMD_FP16
hfloat flt16_min;
uint16_t flt16_min_hex = 0x0400;
std::memcpy(&flt16_min, &flt16_min_hex, sizeof(hfloat));
__test_sincos((hfloat) 1e-3, flt16_min);
#endif
return *this;
}
TheTest &test_sincos_fp32() {
__test_sincos(1e-6f, FLT_MIN);
return *this;
}
TheTest &test_sincos_fp64() {
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
__test_sincos(1e-11, DBL_MIN);
#endif
return *this;
}
};
#define DUMP_ENTRY(type) printf("SIMD%d: %s\n", 8*VTraits<v_uint8>::vlanes(), CV__TRACE_FUNCTION);
@ -2399,6 +2499,7 @@ void test_hal_intrin_float32()
.test_pack_triplets()
.test_exp_fp32()
.test_log_fp32()
.test_sincos_fp32()
.test_erf_fp32()
#if CV_SIMD_WIDTH == 32
.test_extract<4>().test_extract<5>().test_extract<6>().test_extract<7>()
@ -2433,6 +2534,7 @@ void test_hal_intrin_float64()
.test_extract_highest()
.test_exp_fp64()
.test_log_fp64()
.test_sincos_fp64()
//.test_broadcast_element<0>().test_broadcast_element<1>()
#if CV_SIMD_WIDTH == 32
.test_extract<2>().test_extract<3>()
@ -2476,6 +2578,7 @@ void test_hal_intrin_float16()
.test_extract_n<0>().test_extract_n<1>()
.test_exp_fp16()
.test_log_fp16()
.test_sincos_fp16()
#else
std::cout << "SKIP: CV_SIMD_FP16 || CV_SIMD_SCALABLE_FP16 is not available" << std::endl;
#endif

View File

@ -1,7 +1,7 @@
set(ade_src_dir "${OpenCV_BINARY_DIR}/3rdparty/ade")
set(ade_filename "v0.1.2d.zip")
set(ade_subdir "ade-0.1.2d")
set(ade_md5 "dbb095a8bf3008e91edbbf45d8d34885")
set(ade_filename "v0.1.2e.zip")
set(ade_subdir "ade-0.1.2e")
set(ade_md5 "962ce79e0b95591f226431f7b5f152cd")
ocv_download(FILENAME ${ade_filename}
HASH ${ade_md5}
URL

View File

@ -54,6 +54,9 @@ public:
GAPI_WRAP
PyParams& cfgSessionOptions(const std::map<std::string, std::string>& options);
GAPI_WRAP
PyParams& cfgOptLevel(const int opt_level);
GBackend backend() const;
std::string tag() const;
cv::util::any params() const;

View File

@ -15,6 +15,7 @@
#include <opencv2/gapi/opencv_includes.hpp>
#include <opencv2/gapi/util/any.hpp>
#include <opencv2/gapi/util/optional.hpp>
#include <opencv2/core/cvdef.h> // GAPI_EXPORTS
#include <opencv2/gapi/gkernel.hpp> // GKernelPackage
@ -354,6 +355,7 @@ struct ParamDesc {
std::map<std::string, std::string> session_options;
std::vector<cv::gapi::onnx::ep::EP> execution_providers;
bool disable_mem_pattern;
cv::util::optional<int> opt_level;
};
} // namespace detail
@ -648,6 +650,17 @@ public:
return *this;
}
/** @brief Configures optimization level for ONNX Runtime.
@param opt_level [optimization level]: Valid values are 0 (disable), 1 (basic), 2 (extended), 99 (all).
Please see onnxruntime_c_api.h (enum GraphOptimizationLevel) for the full list of all optimization levels.
@return the reference on modified object.
*/
Params<Net>& cfgOptLevel(const int opt_level) {
desc.opt_level = cv::util::make_optional(opt_level);
return *this;
}
// BEGIN(G-API's network parametrization API)
GBackend backend() const { return cv::gapi::onnx::backend(); }
std::string tag() const { return Net::tag(); }
@ -675,7 +688,7 @@ public:
@param model_path path to model file (.onnx file).
*/
Params(const std::string& tag, const std::string& model_path)
: desc{model_path, 0u, 0u, {}, {}, {}, {}, {}, {}, {}, {}, {}, true, {}, {}, {}, {}, false}, m_tag(tag) {}
: desc{ model_path, 0u, 0u, {}, {}, {}, {}, {}, {}, {}, {}, {}, true, {}, {}, {}, {}, false, {} }, m_tag(tag) {}
/** @see onnx::Params::cfgMeanStdDev. */
void cfgMeanStdDev(const std::string &layer,
@ -724,6 +737,11 @@ public:
desc.session_options.insert(options.begin(), options.end());
}
/** @see onnx::Params::cfgOptLevel. */
void cfgOptLevel(const int opt_level) {
desc.opt_level = cv::util::make_optional(opt_level);
}
// BEGIN(G-API's network parametrization API)
GBackend backend() const { return cv::gapi::onnx::backend(); }
std::string tag() const { return m_tag; }

View File

@ -63,6 +63,12 @@ cv::gapi::onnx::PyParams::cfgSessionOptions(const std::map<std::string, std::str
return *this;
}
cv::gapi::onnx::PyParams&
cv::gapi::onnx::PyParams::cfgOptLevel(const int opt_level) {
m_priv->cfgOptLevel(opt_level);
return *this;
}
cv::gapi::GBackend cv::gapi::onnx::PyParams::backend() const {
return m_priv->backend();
}

View File

@ -701,6 +701,26 @@ namespace cv {
namespace gimpl {
namespace onnx {
static GraphOptimizationLevel convertToGraphOptimizationLevel(const int opt_level) {
switch (opt_level) {
case ORT_DISABLE_ALL:
return ORT_DISABLE_ALL;
case ORT_ENABLE_BASIC:
return ORT_ENABLE_BASIC;
case ORT_ENABLE_EXTENDED:
return ORT_ENABLE_EXTENDED;
case ORT_ENABLE_ALL:
return ORT_ENABLE_ALL;
default:
if (opt_level > ORT_ENABLE_ALL) { // relax constraint
return ORT_ENABLE_ALL;
}
else {
cv::util::throw_error(std::invalid_argument("Invalid argument opt_level = " + std::to_string(opt_level)));
}
}
}
ONNXCompiled::ONNXCompiled(const gapi::onnx::detail::ParamDesc &pp)
: params(pp) {
// Validate input parameters before allocating any resources
@ -726,6 +746,10 @@ ONNXCompiled::ONNXCompiled(const gapi::onnx::detail::ParamDesc &pp)
if (pp.disable_mem_pattern) {
session_options.DisableMemPattern();
}
if (pp.opt_level.has_value()) {
session_options.SetGraphOptimizationLevel(convertToGraphOptimizationLevel(pp.opt_level.value()));
}
this_env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "");
#ifndef _WIN32
this_session = Ort::Session(this_env, params.model_path.data(), session_options);

View File

@ -405,7 +405,7 @@ The function imencode compresses the image and stores it in the memory buffer th
result. See cv::imwrite for the list of supported formats and flags description.
@param ext File extension that defines the output format. Must include a leading period.
@param img Image to be written.
@param img Image to be compressed.
@param buf Output buffer resized to fit the compressed image.
@param params Format-specific parameters. See cv::imwrite and cv::ImwriteFlags.
*/
@ -413,6 +413,20 @@ CV_EXPORTS_W bool imencode( const String& ext, InputArray img,
CV_OUT std::vector<uchar>& buf,
const std::vector<int>& params = std::vector<int>());
/** @brief Encodes array of images into a memory buffer.
The function is analog to cv::imencode for in-memory multi-page image compression.
See cv::imwrite for the list of supported formats and flags description.
@param ext File extension that defines the output format. Must include a leading period.
@param imgs Vector of images to be written.
@param buf Output buffer resized to fit the compressed data.
@param params Format-specific parameters. See cv::imwrite and cv::ImwriteFlags.
*/
CV_EXPORTS_W bool imencodemulti( const String& ext, InputArrayOfArrays imgs,
CV_OUT std::vector<uchar>& buf,
const std::vector<int>& params = std::vector<int>());
/** @brief Checks if the specified image file can be decoded by OpenCV.
The function haveImageReader checks if OpenCV is capable of reading the specified file.

View File

@ -142,8 +142,7 @@ static constexpr size_t kAvifSignatureSize = 500;
AvifDecoder::AvifDecoder() {
m_buf_supported = true;
channels_ = 0;
decoder_ = avifDecoderCreate();
decoder_->strictFlags = AVIF_STRICT_DISABLED;
decoder_ = nullptr;
}
AvifDecoder::~AvifDecoder() {
@ -181,6 +180,11 @@ bool AvifDecoder::checkSignature(const String &signature) const {
ImageDecoder AvifDecoder::newDecoder() const { return makePtr<AvifDecoder>(); }
bool AvifDecoder::readHeader() {
if (decoder_)
return true;
decoder_ = avifDecoderCreate();
decoder_->strictFlags = AVIF_STRICT_DISABLED;
if (!m_buf.empty()) {
CV_Assert(m_buf.type() == CV_8UC1);
CV_Assert(m_buf.rows == 1);

View File

@ -171,7 +171,7 @@ public:
{
n = size - pos;
}
memcpy(buffer, buf.ptr() + pos, n);
std::memcpy(buffer, buf.ptr() + pos, n);
helper->m_buf_pos += n;
return n;
}
@ -848,9 +848,9 @@ bool TiffDecoder::readData( Mat& img )
switch ( convert_flag )
{
case MAKE_FLAG( 1, 1 ): // GRAY to GRAY
memcpy( (void*) img_line_buffer,
(void*) bstart,
tile_width * sizeof(uchar) );
std::memcpy( (void*) img_line_buffer,
(void*) bstart,
tile_width * sizeof(uchar) );
break;
case MAKE_FLAG( 1, 3 ): // GRAY to BGR
@ -867,9 +867,9 @@ bool TiffDecoder::readData( Mat& img )
case MAKE_FLAG( 3, 3 ): // RGB to BGR
if (m_use_rgb)
memcpy( (void*) img_line_buffer,
(void*) bstart,
tile_width * sizeof(uchar) );
std::memcpy( (void*) img_line_buffer,
(void*) bstart,
tile_width * sizeof(uchar) );
else
icvCvt_BGR2RGB_8u_C3R( bstart, 0,
img_line_buffer, 0,
@ -979,7 +979,7 @@ bool TiffDecoder::readData( Mat& img )
{
CV_CheckEQ(wanted_channels, 3, "");
if (m_use_rgb)
memcpy(buffer16, img.ptr<ushort>(img_y + i, x), tile_width * sizeof(ushort));
std::memcpy(buffer16, img.ptr<ushort>(img_y + i, x), tile_width * sizeof(ushort));
else
icvCvt_RGB2BGR_16u_C3R(buffer16, 0,
img.ptr<ushort>(img_y + i, x), 0,
@ -1011,9 +1011,9 @@ bool TiffDecoder::readData( Mat& img )
CV_CheckEQ(wanted_channels, 1, "");
if( ncn == 1 )
{
memcpy(img.ptr<ushort>(img_y + i, x),
buffer16,
tile_width*sizeof(ushort));
std::memcpy(img.ptr<ushort>(img_y + i, x),
buffer16,
tile_width*sizeof(ushort));
}
else
{
@ -1118,10 +1118,16 @@ public:
/*map=*/0, /*unmap=*/0 );
}
static tmsize_t read( thandle_t /*handle*/, void* /*buffer*/, tmsize_t /*n*/ )
static tmsize_t read( thandle_t handle, void* buffer, tmsize_t n )
{
// Not used for encoding.
return 0;
// Used for imencodemulti() to stores multi-images.
TiffEncoderBufHelper *helper = reinterpret_cast<TiffEncoderBufHelper*>(handle);
size_t begin = (size_t)helper->m_buf_pos;
size_t end = begin + n;
CV_CheckGT( helper->m_buf->size(), end , "do not be over-run buffer");
std::memcpy(buffer, &(*helper->m_buf)[begin], n);
helper->m_buf_pos = end;
return n;
}
static tmsize_t write( thandle_t handle, void* buffer, tmsize_t n )
@ -1133,7 +1139,7 @@ public:
{
helper->m_buf->resize(end);
}
memcpy(&(*helper->m_buf)[begin], buffer, n);
std::memcpy(&(*helper->m_buf)[begin], buffer, n);
helper->m_buf_pos = end;
return n;
}
@ -1350,7 +1356,7 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
{
case 1:
{
memcpy(buffer, img.ptr(y), scanlineSize);
std::memcpy(buffer, img.ptr(y), scanlineSize);
break;
}

View File

@ -723,6 +723,7 @@ static bool imwrite_( const String& filename, const std::vector<Mat>& img_vec,
Mat temp;
if( !encoder->isFormatSupported(image.depth()) )
{
CV_LOG_ONCE_WARNING(NULL, "Unsupported depth image for selected encoder is fallbacked to CV_8U.");
CV_Assert( encoder->isFormatSupported(CV_8U) );
image.convertTo( temp, CV_8U );
image = temp;
@ -769,10 +770,12 @@ static bool imwrite_( const String& filename, const std::vector<Mat>& img_vec,
catch (const cv::Exception& e)
{
CV_LOG_ERROR(NULL, "imwrite_('" << filename << "'): can't write data: " << e.what());
code = false;
}
catch (...)
{
CV_LOG_ERROR(NULL, "imwrite_('" << filename << "'): can't write data: unknown exception");
code = false;
}
return code;
@ -960,7 +963,7 @@ imdecodemulti_(const Mat& buf, int flags, std::vector<Mat>& mats, int start, int
ImageDecoder decoder = findDecoder(buf_row);
if (!decoder)
return 0;
return false;
// Try to decode image by RGB instead of BGR.
if (flags & IMREAD_COLOR_RGB && flags != IMREAD_UNCHANGED)
@ -977,7 +980,7 @@ imdecodemulti_(const Mat& buf, int flags, std::vector<Mat>& mats, int start, int
filename = tempfile();
FILE* f = fopen(filename.c_str(), "wb");
if (!f)
return 0;
return false;
size_t bufSize = buf_row.total() * buf.elemSize();
if (fwrite(buf_row.ptr(), 1, bufSize, f) != bufSize)
{
@ -1103,49 +1106,80 @@ bool imdecodemulti(InputArray _buf, int flags, CV_OUT std::vector<Mat>& mats, co
}
}
bool imencode( const String& ext, InputArray _image,
bool imencode( const String& ext, InputArray _img,
std::vector<uchar>& buf, const std::vector<int>& params )
{
CV_TRACE_FUNCTION();
Mat image = _image.getMat();
CV_Assert(!image.empty());
int channels = image.channels();
CV_Assert( channels == 1 || channels == 3 || channels == 4 );
ImageEncoder encoder = findEncoder( ext );
if( !encoder )
CV_Error( Error::StsError, "could not find encoder for the specified extension" );
if( !encoder->isFormatSupported(image.depth()) )
std::vector<Mat> img_vec;
CV_Assert(!_img.empty());
if (_img.isMatVector() || _img.isUMatVector())
_img.getMatVector(img_vec);
else
img_vec.push_back(_img.getMat());
CV_Assert(!img_vec.empty());
const bool isMultiImg = img_vec.size() > 1;
std::vector<Mat> write_vec;
for (size_t page = 0; page < img_vec.size(); page++)
{
CV_Assert( encoder->isFormatSupported(CV_8U) );
Mat image = img_vec[page];
CV_Assert(!image.empty());
const int channels = image.channels();
CV_Assert( channels == 1 || channels == 3 || channels == 4 );
Mat temp;
image.convertTo(temp, CV_8U);
image = temp;
if( !encoder->isFormatSupported(image.depth()) )
{
CV_LOG_ONCE_WARNING(NULL, "Unsupported depth image for selected encoder is fallbacked to CV_8U.");
CV_Assert( encoder->isFormatSupported(CV_8U) );
image.convertTo( temp, CV_8U );
image = temp;
}
write_vec.push_back(image);
}
CV_Check(params.size(), (params.size() & 1) == 0, "Encoding 'params' must be key-value pairs");
CV_CheckLE(params.size(), (size_t)(CV_IO_MAX_IMAGE_PARAMS*2), "");
bool code;
if( encoder->setDestination(buf) )
bool code = false;
String filename;
if( !encoder->setDestination(buf) )
{
code = encoder->write(image, params);
filename = tempfile();
code = encoder->setDestination(filename);
CV_Assert( code );
}
try {
if (!isMultiImg)
code = encoder->write(write_vec[0], params);
else
code = encoder->writemulti(write_vec, params);
encoder->throwOnEror();
CV_Assert( code );
}
else
catch (const cv::Exception& e)
{
String filename = tempfile();
code = encoder->setDestination(filename);
CV_Assert( code );
code = encoder->write(image, params);
encoder->throwOnEror();
CV_Assert( code );
CV_LOG_ERROR(NULL, "imencode(): can't encode data: " << e.what());
code = false;
}
catch (...)
{
CV_LOG_ERROR(NULL, "imencode(): can't encode data: unknown exception");
code = false;
}
if( !filename.empty() && code )
{
FILE* f = fopen( filename.c_str(), "rb" );
CV_Assert(f != 0);
fseek( f, 0, SEEK_END );
@ -1159,6 +1193,12 @@ bool imencode( const String& ext, InputArray _image,
return code;
}
bool imencodemulti( const String& ext, InputArrayOfArrays imgs,
std::vector<uchar>& buf, const std::vector<int>& params)
{
return imencode(ext, imgs, buf, params);
}
bool haveImageReader( const String& filename )
{
ImageDecoder decoder = cv::findDecoder(filename);

View File

@ -161,14 +161,14 @@ TEST_P(Imgcodecs_Avif_Image_EncodeDecodeSuite, imencode_imdecode) {
// Encode.
std::vector<unsigned char> buf;
if (!IsBitDepthValid()) {
EXPECT_THROW(cv::imencode(".avif", img_original, buf, encoding_params_),
cv::Exception);
return;
}
bool result = true;
EXPECT_NO_THROW(
result = cv::imencode(".avif", img_original, buf, encoding_params_););
if (!IsBitDepthValid()) {
EXPECT_FALSE(result);
return;
}
EXPECT_TRUE(result);
// Read back.
@ -337,11 +337,20 @@ TEST_P(Imgcodecs_Avif_Animation_WriteDecodeSuite, encode_decode) {
std::vector<unsigned char> buf(size);
EXPECT_TRUE(file.read(reinterpret_cast<char*>(buf.data()), size));
file.close();
EXPECT_EQ(0, remove(output.c_str()));
std::vector<cv::Mat> anim;
ASSERT_TRUE(cv::imdecodemulti(buf, imread_mode_, anim));
ValidateRead(anim_original, anim);
if (imread_mode_ == IMREAD_UNCHANGED) {
ImageCollection collection(output, IMREAD_UNCHANGED);
anim.clear();
for (auto&& i : collection)
anim.push_back(i);
ValidateRead(anim_original, anim);
}
EXPECT_EQ(0, remove(output.c_str()));
}
INSTANTIATE_TEST_CASE_P(

View File

@ -314,4 +314,27 @@ TEST(Imgcodecs_EXR, read_RGBA_unchanged)
EXPECT_EQ(0, remove(filenameOutput.c_str()));
}
// See https://github.com/opencv/opencv/pull/26211
// ( related with https://github.com/opencv/opencv/issues/26207 )
TEST(Imgcodecs_EXR, imencode_regression_26207_extra)
{
// CV_8U is not supported depth for EXR Encoder.
const cv::Mat src(100, 100, CV_8UC1, cv::Scalar::all(0));
std::vector<uchar> buf;
bool ret = false;
EXPECT_ANY_THROW(ret = imencode(".exr", src, buf));
EXPECT_FALSE(ret);
}
TEST(Imgcodecs_EXR, imwrite_regression_26207_extra)
{
// CV_8U is not supported depth for EXR Encoder.
const cv::Mat src(100, 100, CV_8UC1, cv::Scalar::all(0));
const string filename = cv::tempfile(".exr");
bool ret = false;
EXPECT_ANY_THROW(ret = imwrite(filename, src));
EXPECT_FALSE(ret);
remove(filename.c_str());
}
}} // namespace

View File

@ -520,8 +520,78 @@ TEST(ImgCodecs, multipage_collection_two_iterator_operatorpp)
EXPECT_TRUE(cv::norm(img1, img[i], NORM_INF) == 0);
}
}
// See https://github.com/opencv/opencv/issues/26207
TEST(Imgcodecs, imencodemulti_regression_26207)
{
vector<Mat> imgs;
const cv::Mat img(100, 100, CV_8UC1, cv::Scalar::all(0));
imgs.push_back(img);
std::vector<uchar> buf;
bool ret = false;
// Encode single image
EXPECT_NO_THROW(ret = imencode(".tiff", img, buf));
EXPECT_TRUE(ret);
EXPECT_NO_THROW(ret = imencode(".tiff", imgs, buf));
EXPECT_TRUE(ret);
EXPECT_NO_THROW(ret = imencodemulti(".tiff", imgs, buf));
EXPECT_TRUE(ret);
// Encode multiple images
imgs.push_back(img.clone());
EXPECT_NO_THROW(ret = imencode(".tiff", imgs, buf));
EXPECT_TRUE(ret);
EXPECT_NO_THROW(ret = imencodemulti(".tiff", imgs, buf));
EXPECT_TRUE(ret);
// Count stored images from buffer.
// imcount() doesn't support buffer, so encoded buffer outputs to file temporary.
const size_t len = buf.size();
const string filename = cv::tempfile(".tiff");
FILE *f = fopen(filename.c_str(), "wb");
EXPECT_NE(f, nullptr);
EXPECT_EQ(len, fwrite(&buf[0], 1, len, f));
fclose(f);
EXPECT_EQ(2, (int)imcount(filename));
EXPECT_EQ(0, remove(filename.c_str()));
}
#endif
// See https://github.com/opencv/opencv/pull/26211
// ( related with https://github.com/opencv/opencv/issues/26207 )
TEST(Imgcodecs, imencode_regression_26207_extra)
{
// CV_32F is not supported depth for BMP Encoder.
// Encoded buffer contains CV_8U image which is fallbacked.
const cv::Mat src(100, 100, CV_32FC1, cv::Scalar::all(0));
std::vector<uchar> buf;
bool ret = false;
EXPECT_NO_THROW(ret = imencode(".bmp", src, buf));
EXPECT_TRUE(ret);
cv::Mat dst;
EXPECT_NO_THROW(dst = imdecode(buf, IMREAD_GRAYSCALE));
EXPECT_FALSE(dst.empty());
EXPECT_EQ(CV_8UC1, dst.type());
}
TEST(Imgcodecs, imwrite_regression_26207_extra)
{
// CV_32F is not supported depth for BMP Encoder.
// Encoded buffer contains CV_8U image which is fallbacked.
const cv::Mat src(100, 100, CV_32FC1, cv::Scalar::all(0));
const string filename = cv::tempfile(".bmp");
bool ret = false;
EXPECT_NO_THROW(ret = imwrite(filename, src));
EXPECT_TRUE(ret);
cv::Mat dst;
EXPECT_NO_THROW(dst = imread(filename, IMREAD_GRAYSCALE));
EXPECT_FALSE(dst.empty());
EXPECT_EQ(CV_8UC1, dst.type());
EXPECT_EQ(0, remove(filename.c_str()));
}
TEST(Imgcodecs_Params, imwrite_regression_22752)
{

View File

@ -48,7 +48,7 @@
/**
@defgroup imgproc Image Processing
This module includes image-processing functions.
This module offers a comprehensive suite of image processing functions, enabling tasks such as those listed above.
@{
@defgroup imgproc_filter Image Filtering

View File

@ -64,7 +64,7 @@ CollectPolyEdges( Mat& img, const Point2l* v, int npts,
int shift, Point offset=Point() );
static void
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type);
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
static void
PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
@ -1051,7 +1051,7 @@ EllipseEx( Mat& img, Point2l center, Size2l axes,
v.push_back(center);
std::vector<PolyEdge> edges;
CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT );
FillEdgeCollection( img, edges, color, line_type );
FillEdgeCollection( img, edges, color );
}
}
@ -1299,15 +1299,11 @@ CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>&
if (t0.y != t1.y)
{
pt0c.y = t0.y; pt1c.y = t1.y;
pt0c.x = (int64)(t0.x) << XY_SHIFT;
pt1c.x = (int64)(t1.x) << XY_SHIFT;
}
}
else
{
pt0c.x += XY_ONE >> 1;
pt1c.x += XY_ONE >> 1;
}
pt0c.x = (int64)(t0.x) << XY_SHIFT;
pt1c.x = (int64)(t1.x) << XY_SHIFT;
}
else
{
@ -1349,7 +1345,7 @@ struct CmpEdges
/**************** helper macros and functions for sequence/contour processing ***********/
static void
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type)
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
{
PolyEdge tmp;
int i, y, total = (int)edges.size();
@ -1358,12 +1354,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, i
int y_max = INT_MIN, y_min = INT_MAX;
int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
int pix_size = (int)img.elemSize();
int delta;
if (line_type < LINE_AA)
delta = 0;
else
delta = XY_ONE - 1;
int delta = XY_ONE - 1;
if( total < 2 )
return;
@ -2051,7 +2042,7 @@ void fillPoly( InputOutputArray _img, const Point** pts, const int* npts, int nc
}
}
FillEdgeCollection(img, edges, buf, line_type);
FillEdgeCollection(img, edges, buf);
}
void polylines( InputOutputArray _img, const Point* const* pts, const int* npts, int ncontours, bool isClosed,

View File

@ -2508,7 +2508,7 @@ private:
#endif
static bool ipp_warpAffine( InputArray _src, OutputArray _dst, int interpolation, int borderType, InputArray _M, int flags )
static bool ipp_warpAffine( InputArray _src, OutputArray _dst, int interpolation, int borderType, const Scalar & borderValue, InputArray _M, int flags )
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP();
@ -2527,7 +2527,7 @@ static bool ipp_warpAffine( InputArray _src, OutputArray _dst, int interpolation
Mat dst = _dst.getMat();
::ipp::IwiImage iwSrc = ippiGetImage(src);
::ipp::IwiImage iwDst = ippiGetImage(dst);
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType));
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), ippiGetValue(borderValue));
IwTransDirection iwTransDirection;
if(!ippBorder)
return false;
@ -2570,7 +2570,7 @@ static bool ipp_warpAffine( InputArray _src, OutputArray _dst, int interpolation
return true;
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(interpolation);
CV_UNUSED(borderType); CV_UNUSED(_M); CV_UNUSED(flags);
CV_UNUSED(borderType); CV_UNUSED(borderValue); CV_UNUSED(_M); CV_UNUSED(flags);
return false;
#endif
}
@ -2795,7 +2795,7 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 2 && M0.cols == 3 );
M0.convertTo(matM, matM.type());
CV_IPP_RUN_FAST(ipp_warpAffine(src, dst, interpolation, borderType, matM, flags));
CV_IPP_RUN_FAST(ipp_warpAffine(src, dst, interpolation, borderType, borderValue, matM, flags));
if( !(flags & WARP_INVERSE_MAP) )
{

View File

@ -857,6 +857,74 @@ TEST(Drawing, ttf_text)
}
#endif
TEST(Drawing, fillpoly_contours)
{
const int imgSize = 50;
const int type = CV_8UC1;
const int shift = 0;
const Scalar cl = Scalar::all(255);
const cv::LineTypes lineType = LINE_8;
// check that contours of fillPoly and polylines match
{
cv::Mat img(imgSize, imgSize, type);
img = 0;
std::vector<std::vector<cv::Point>> polygonPoints{
{ {44, 27}, {7, 37}, {7, 19}, {38, 19} }
};
cv::fillPoly(img, polygonPoints, cl, lineType, shift);
cv::polylines(img, polygonPoints, true, 0, 1, lineType, shift);
{
cv::Mat labelImage(img.size(), CV_32S);
int labels = cv::connectedComponents(img, labelImage, 4);
EXPECT_EQ(2, labels) << "filling went over the border";
}
}
// check that line generated with fillPoly and polylines match
{
cv::Mat img1(imgSize, imgSize, type), img2(imgSize, imgSize, type);
img1 = 0;
img2 = 0;
std::vector<std::vector<cv::Point>> polygonPoints{
{ {44, 27}, {38, 19} }
};
cv::fillPoly(img1, polygonPoints, cl, lineType, shift);
cv::polylines(img2, polygonPoints, true, cl, 1, lineType, shift);
EXPECT_MAT_N_DIFF(img1, img2, 0);
}
}
TEST(Drawing, fillpoly_match_lines)
{
const int imgSize = 49;
const int type = CV_8UC1;
const int shift = 0;
const Scalar cl = Scalar::all(255);
const cv::LineTypes lineType = LINE_8;
cv::Mat img1(imgSize, imgSize, type), img2(imgSize, imgSize, type);
for (int x1 = 0; x1 < imgSize; x1 += imgSize / 2)
{
for (int y1 = 0; y1 < imgSize; y1 += imgSize / 2)
{
for (int x2 = 0; x2 < imgSize; x2++)
{
for (int y2 = 0; y2 < imgSize; y2++)
{
img1 = 0;
img2 = 0;
std::vector<std::vector<cv::Point>> polygonPoints{
{ {x1, y1}, {x2, y2} }
};
cv::fillPoly(img1, polygonPoints, cl, lineType, shift);
cv::polylines(img2, polygonPoints, true, cl, 1, lineType, shift);
EXPECT_MAT_N_DIFF(img1, img2, 0);
}
}
}
}
}
TEST(Drawing, fillpoly_fully)
{

View File

@ -1,19 +1,19 @@
{
"name": "opencv_js_perf",
"description": "Perfermance tests for opencv js bindings",
"description": "Performance tests for opencv js bindings",
"version": "1.0.0",
"dependencies" : {
"benchmark" : "latest"
"dependencies": {
"benchmark": "latest"
},
"repository": {
"type": "git",
"url": "https://github.com/opencv/opencv.git"
"type": "git",
"url": "https://github.com/opencv/opencv.git"
},
"keywords": [],
"author": "",
"license": "Apache 2.0 License",
"bugs": {
"url": "https://github.com/opencv/opencv/issues"
"url": "https://github.com/opencv/opencv/issues"
},
"homepage": "https://github.com/opencv/opencv"
}
}

View File

@ -155,6 +155,22 @@ public:
* @param target_id the id of target device
*/
CV_WRAP static Ptr<FaceRecognizerSF> create(CV_WRAP_FILE_PATH const String& model, CV_WRAP_FILE_PATH const String& config, int backend_id = 0, int target_id = 0);
/**
* @brief Creates an instance of this class from a buffer containing the model weights and configuration.
* @param framework Name of the framework (ONNX, etc.)
* @param bufferModel A buffer containing the binary model weights.
* @param bufferConfig A buffer containing the network configuration.
* @param backend_id The id of the backend.
* @param target_id The id of the target device.
*
* @return A pointer to the created instance of FaceRecognizerSF.
*/
CV_WRAP static Ptr<FaceRecognizerSF> create(const String& framework,
const std::vector<uchar>& bufferModel,
const std::vector<uchar>& bufferConfig,
int backend_id = 0,
int target_id = 0);
};
//! @}

View File

@ -26,6 +26,19 @@ public:
net.setPreferableBackend(backend_id);
net.setPreferableTarget(target_id);
}
FaceRecognizerSFImpl(const String& framework,
const std::vector<uchar>& bufferModel,
const std::vector<uchar>& bufferConfig,
int backend_id, int target_id)
{
net = dnn::readNet(framework, bufferModel, bufferConfig);
CV_Assert(!net.empty());
net.setPreferableBackend(backend_id);
net.setPreferableTarget(target_id);
}
void alignCrop(InputArray _src_img, InputArray _face_mat, OutputArray _aligned_img) const override
{
Mat face_mat = _face_mat.getMat();
@ -189,4 +202,17 @@ Ptr<FaceRecognizerSF> FaceRecognizerSF::create(const String& model, const String
#endif
}
Ptr<FaceRecognizerSF> FaceRecognizerSF::create(const String& framework,
const std::vector<uchar>& bufferModel,
const std::vector<uchar>& bufferConfig,
int backend_id, int target_id)
{
#ifdef HAVE_OPENCV_DNN
return makePtr<FaceRecognizerSFImpl>(framework, bufferModel, bufferConfig, backend_id, target_id);
#else
CV_UNUSED(bufferModel); CV_UNUSED(bufferConfig); CV_UNUSED(backend_id); CV_UNUSED(target_id);
CV_Error(cv::Error::StsNotImplemented, "cv::FaceRecognizerSF requires enabled 'dnn' module");
#endif
}
} // namespace cv

View File

@ -27,7 +27,9 @@
//! @{
/**
@brief Lucas-Kanade optical flow for single pyramid layer. See calcOpticalFlowPyrLK
@brief Lucas-Kanade optical flow for single pyramid layer. See calcOpticalFlowPyrLK.
@note OpenCV builds pyramid levels with `win_size` padding. Out-of-bound access to source
image data is legal within `+-win_size` range.
@param prev_data previous frame image data
@param prev_data_step previous frame image data step
@param prev_deriv_data previous frame Schaar derivatives
@ -67,6 +69,29 @@ inline int hal_ni_LKOpticalFlowLevel(const uchar *prev_data, size_t prev_data_st
#define cv_hal_LKOpticalFlowLevel hal_ni_LKOpticalFlowLevel
//! @endcond
/**
@brief Computes Schaar derivatives with inteleaved layout xyxy...
@note OpenCV builds pyramid levels with `win_size` padding. Out-of-bound access to source
image data is legal within `+-win_size` range.
@param src_data source image data
@param src_step source image step
@param dst_data destination buffer data
@param dst_step destination buffer step
@param width image width
@param height image height
@param cn source image channels
**/
inline int hal_ni_ScharrDeriv(const uchar* src_data, size_t src_step,
short* dst_data, size_t dst_step,
int width, int height, int cn)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
//! @cond IGNORED
#define cv_hal_ScharrDeriv hal_ni_ScharrDeriv
//! @endcond
//! @}
#if defined(__clang__)

View File

@ -62,6 +62,9 @@ static void calcScharrDeriv(const cv::Mat& src, cv::Mat& dst)
int rows = src.rows, cols = src.cols, cn = src.channels(), depth = src.depth();
CV_Assert(depth == CV_8U);
dst.create(rows, cols, CV_MAKETYPE(DataType<deriv_type>::depth, cn*2));
CALL_HAL(ScharrDeriv, cv_hal_ScharrDeriv, src.data, src.step, (short*)dst.data, dst.step, cols, rows, cn);
parallel_for_(Range(0, rows), cv::detail::ScharrDerivInvoker(src, dst), cv::getNumThreads());
}

View File

@ -53,7 +53,7 @@
#include <unistd.h> // -D_FORTIFY_SOURCE=2 workaround: https://github.com/opencv/opencv/issues/15020
#endif
#include "opencv2/core/cvdef.h"
#include "opencv2/videoio.hpp"
#include "opencv2/core/utility.hpp"

View File

@ -1,193 +0,0 @@
/*
* filestorage_sample demonstrate the usage of the opencv serialization functionality
*/
#include "opencv2/core.hpp"
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::cerr;
using std::ostream;
using namespace cv;
static void help(char** av)
{
cout << "\nfilestorage_sample demonstrate the usage of the opencv serialization functionality.\n"
<< "usage:\n"
<< av[0] << " outputfile.yml.gz\n"
<< "\n outputfile above can have many different extensions, see below."
<< "\nThis program demonstrates the use of FileStorage for serialization, that is in use << and >> in OpenCV\n"
<< "For example, how to create a class and have it serialize, but also how to use it to read and write matrices.\n"
<< "FileStorage allows you to serialize to various formats specified by the file end type."
<< "\nYou should try using different file extensions.(e.g. yaml yml xml xml.gz yaml.gz etc...)\n" << endl;
}
struct MyData
{
MyData() :
A(0), X(0), id()
{
}
explicit MyData(int) :
A(97), X(CV_PI), id("mydata1234")
{
}
int A;
double X;
string id;
void write(FileStorage& fs) const //Write serialization for this class
{
fs << "{" << "A" << A << "X" << X << "id" << id << "}";
}
void read(const FileNode& node) //Read serialization for this class
{
A = (int)node["A"];
X = (double)node["X"];
id = (string)node["id"];
}
};
//These write and read functions must exist as per the inline functions in operations.hpp
static void write(FileStorage& fs, const std::string&, const MyData& x){
x.write(fs);
}
static void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){
if(node.empty())
x = default_value;
else
x.read(node);
}
static ostream& operator<<(ostream& out, const MyData& m){
out << "{ id = " << m.id << ", ";
out << "X = " << m.X << ", ";
out << "A = " << m.A << "}";
return out;
}
int main(int ac, char** av)
{
cv::CommandLineParser parser(ac, av,
"{@input||}{help h ||}"
);
if (parser.has("help"))
{
help(av);
return 0;
}
string filename = parser.get<string>("@input");
if (filename.empty())
{
help(av);
return 1;
}
//write
{
FileStorage fs(filename, FileStorage::WRITE);
cout << "writing images\n";
fs << "images" << "[";
fs << "image1.jpg" << "myfi.png" << "baboon.jpg";
cout << "image1.jpg" << " myfi.png" << " baboon.jpg" << endl;
fs << "]";
cout << "writing mats\n";
Mat R =Mat_<double>::eye(3, 3),T = Mat_<double>::zeros(3, 1);
cout << "R = " << R << "\n";
cout << "T = " << T << "\n";
fs << "R" << R;
fs << "T" << T;
cout << "writing MyData struct\n";
MyData m(1);
fs << "mdata" << m;
cout << m << endl;
}
//read
{
FileStorage fs(filename, FileStorage::READ);
if (!fs.isOpened())
{
cerr << "failed to open " << filename << endl;
help(av);
return 1;
}
FileNode n = fs["images"];
if (n.type() != FileNode::SEQ)
{
cerr << "images is not a sequence! FAIL" << endl;
return 1;
}
cout << "reading images\n";
FileNodeIterator it = n.begin(), it_end = n.end();
for (; it != it_end; ++it)
{
cout << (string)*it << "\n";
}
Mat R, T;
cout << "reading R and T" << endl;
fs["R"] >> R;
fs["T"] >> T;
cout << "R = " << R << "\n";
cout << "T = " << T << endl;
MyData m;
fs["mdata"] >> m;
cout << "read mdata\n";
cout << m << endl;
cout << "attempting to read mdata_b\n"; //Show default behavior for empty matrix
fs["mdata_b"] >> m;
cout << "read mdata_b\n";
cout << m << endl;
}
cout << "Try opening " << filename << " to see the serialized data." << endl << endl;
//read from string
{
cout << "Read data from string\n";
string dataString =
"%YAML:1.0\n"
"mdata:\n"
" A: 97\n"
" X: 3.1415926535897931e+00\n"
" id: mydata1234\n";
MyData m;
FileStorage fs(dataString, FileStorage::READ | FileStorage::MEMORY);
cout << "attempting to read mdata_b from string\n"; //Show default behavior for empty matrix
fs["mdata"] >> m;
cout << "read mdata\n";
cout << m << endl;
}
//write to string
{
cout << "Write data to string\n";
FileStorage fs(filename, FileStorage::WRITE | FileStorage::MEMORY | FileStorage::FORMAT_YAML);
cout << "writing MyData struct\n";
MyData m(1);
fs << "mdata" << m;
cout << m << endl;
string createdString = fs.releaseAndGetString();
cout << "Created string:\n" << createdString << "\n";
}
return 0;
}

View File

@ -8,14 +8,14 @@ using namespace std;
static void help(char** av)
{
cout << endl
<< av[0] << " shows the usage of the OpenCV serialization functionality." << endl
<< av[0] << " shows the usage of the OpenCV serialization functionality." << endl << endl
<< "usage: " << endl
<< av[0] << " outputfile.yml.gz" << endl
<< "The output file may be either XML (xml) or YAML (yml/yaml). You can even compress it by "
<< "specifying this in its extension like xml.gz yaml.gz etc... " << endl
<< av[0] << " [output file name] (default outputfile.yml.gz)" << endl << endl
<< "The output file may be XML (xml), YAML (yml/yaml), or JSON (json)." << endl
<< "You can even compress it by specifying this in its extension like xml.gz yaml.gz etc... " << endl
<< "With FileStorage you can serialize objects in OpenCV by using the << and >> operators" << endl
<< "For example: - create a class and have it serialized" << endl
<< " - use it to read and write matrices." << endl;
<< " - use it to read and write matrices." << endl << endl;
}
class MyData
@ -68,13 +68,16 @@ static ostream& operator<<(ostream& out, const MyData& m)
int main(int ac, char** av)
{
string filename;
if (ac != 2)
{
help(av);
return 1;
filename = "outputfile.yml.gz";
}
else
filename = av[1];
string filename = av[1];
{ //write
//! [iomati]
Mat R = Mat_<uchar>::eye(3, 3),
@ -118,7 +121,7 @@ int main(int ac, char** av)
//! [close]
fs.release(); // explicit close
//! [close]
cout << "Write Done." << endl;
cout << "Write operation to file:" << filename << " completed successfully." << endl;
}
{//read

View File

@ -78,6 +78,7 @@ int main()
tm.start();
// do something ...
tm.stop();
cout << "Last iteration: " << tm.getLastTimeSec() << endl;
}
cout << "Average time per iteration in seconds: " << tm.getAvgTimeSec() << endl;
cout << "Average FPS: " << tm.getFPS() << endl;

View File

@ -9,10 +9,10 @@ def help(filename):
'''
{0} shows the usage of the OpenCV serialization functionality. \n\n
usage:\n
python3 {0} outputfile.yml.gz\n\n
The output file may be either in XML, YAML or JSON. You can even compress it\n
by specifying this in its extension like xml.gz yaml.gz etc... With\n
FileStorage you can serialize objects in OpenCV.\n\n
python3 {0} [output file name] (default outputfile.yml.gz)\n\n
The output file may be XML (xml), YAML (yml/yaml), or JSON (json).\n
You can even compress it by specifying this in its extension like xml.gz yaml.gz etc...\n
With FileStorage you can serialize objects in OpenCV.\n\n
For example: - create a class and have it serialized\n
- use it to read and write matrices.\n
'''.format(filename)
@ -49,7 +49,9 @@ class MyData:
def main(argv):
if len(argv) != 2:
help(argv[0])
exit(1)
filename = 'outputfile.yml.gz'
else :
filename = argv[1]
# write
## [iomati]
@ -60,8 +62,6 @@ def main(argv):
m = MyData()
## [customIOi]
filename = argv[1]
## [open]
s = cv.FileStorage(filename, cv.FileStorage_WRITE)
# or:
@ -98,7 +98,7 @@ def main(argv):
## [close]
s.release()
## [close]
print ('Write Done.')
print ('Write operation to file:', filename, 'completed successfully.')
# read
print ('\nReading: ')