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

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2024-04-16 15:43:06 +03:00
68 changed files with 2220 additions and 306 deletions
+2 -2
View File
@@ -1666,8 +1666,7 @@ void ChessBoardDetector::findQuadNeighbors()
continue;
const float dist = normL2Sqr<float>(pt - all_quads_pts[neighbor_idx]);
if (dist < min_dist &&
dist <= cur_quad.edge_len * thresh_scale &&
if (dist <= cur_quad.edge_len * thresh_scale &&
dist <= q_k.edge_len * thresh_scale)
{
// check edge lengths, make sure they're compatible
@@ -1684,6 +1683,7 @@ void ChessBoardDetector::findQuadNeighbors()
closest_corner_idx = j;
closest_quad = &q_k;
min_dist = dist;
break;
}
}
@@ -933,7 +933,9 @@ inline hfloat hfloatFromBits(ushort w) {
#endif
}
#if !defined(__OPENCV_BUILD) && !(defined __STDCPP_FLOAT16_T__) && !(defined __ARM_NEON)
typedef hfloat float16_t;
#endif
class bfloat
{
+2 -2
View File
@@ -15,7 +15,7 @@
#import <Foundation/Foundation.h>
#ifdef AVAILABLE_IMGCODECS
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE || TARGET_OS_VISION
#import <UIKit/UIKit.h>
#elif TARGET_OS_MAC
#import <AppKit/AppKit.h>
@@ -197,7 +197,7 @@ CV_EXPORTS @interface Mat : NSObject
- (instancetype)initWithCGImage:(CGImageRef)image;
- (instancetype)initWithCGImage:(CGImageRef)image alphaExist:(BOOL)alphaExist;
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE || TARGET_OS_VISION
- (UIImage*)toUIImage;
- (instancetype)initWithUIImage:(UIImage*)image;
+1 -1
View File
@@ -951,7 +951,7 @@ template<typename T> int putData(NSArray<NSNumber*>* indices, cv::Mat* mat, int
return [MatConverters convertCGImageRefToMat:image alphaExist:alphaExist];
}
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE || TARGET_OS_VISION
-(UIImage*)toUIImage {
return [MatConverters converMatToUIImage:self];
@@ -4,15 +4,16 @@ import numpy as np
import cv2 as cv
from typing import TYPE_CHECKING, Any
# Same as cv2.typing.NumPyArrayGeneric, but avoids circular dependencies
# Same as cv2.typing.NumPyArrayNumeric, but avoids circular dependencies
if TYPE_CHECKING:
_NumPyArrayGeneric = np.ndarray[Any, np.dtype[np.generic]]
_NumPyArrayNumeric = np.ndarray[Any, np.dtype[np.integer[Any] | np.floating[Any]]]
else:
_NumPyArrayGeneric = np.ndarray
_NumPyArrayNumeric = np.ndarray
# NumPy documentation: https://numpy.org/doc/stable/user/basics.subclassing.html
class Mat(_NumPyArrayGeneric):
class Mat(_NumPyArrayNumeric):
'''
cv.Mat wrapper for numpy array.
+17 -5
View File
@@ -98,9 +98,11 @@ char* doubleToString( char* buf, size_t bufSize, double value, bool explicitZero
}
else
{
static const char* fmt = "%.16e";
// binary64 has 52 bit fraction with hidden bit.
// 53 * log_10(2) is 15.955. So "%.16f" should be fine, but its test fails.
snprintf( buf, bufSize, "%.17g", value );
char* ptr = buf;
snprintf( buf, bufSize, fmt, value );
if( *ptr == '+' || *ptr == '-' )
ptr++;
for( ; cv_isdigit(*ptr); ptr++ )
@@ -140,11 +142,21 @@ char* floatToString( char* buf, size_t bufSize, float value, bool halfprecision,
}
else
{
char* ptr = buf;
if (halfprecision)
snprintf(buf, bufSize, "%.4e", value);
{
// bfloat16 has 7 bit fraction with hidden bit.
// binary16 has 10 bit fraction with hidden bit.
// 11 * log_10(2) is 3.311. So "%.4f" should be fine, but its test fails.
snprintf(buf, bufSize, "%.5g", value);
}
else
snprintf(buf, bufSize, "%.8e", value);
{
// binray32 has 23 bit fraction with hidden bit.
// 24 * log_10(2) is 7.225. So "%.8f" should be fine, but its test fails.
snprintf(buf, bufSize, "%.9g", value);
}
char* ptr = buf;
if( *ptr == '+' || *ptr == '-' )
ptr++;
for( ; cv_isdigit(*ptr); ptr++ )
+57 -39
View File
@@ -1191,11 +1191,7 @@ TEST(Core_InputOutput, FileStorage_DMatch)
EXPECT_NO_THROW(fs << "d" << d);
cv::String fs_result = fs.releaseAndGetString();
#if defined _MSC_VER && _MSC_VER <= 1800 /* MSVC 2013 and older */
EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5000000000000000e+000 ]\n");
#else
EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5000000000000000e+00 ]\n");
#endif
EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5 ]\n");
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
@@ -1222,25 +1218,14 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector)
EXPECT_NO_THROW(fs << "dv" << dv);
cv::String fs_result = fs.releaseAndGetString();
#if defined _MSC_VER && _MSC_VER <= 1800 /* MSVC 2013 and older */
EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n"
"---\n"
"dv:\n"
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
" - [ 1, 2, 3, -1.5 ]\n"
" - [ 2, 3, 4, 1.5 ]\n"
" - [ 3, 2, 1, 0.5 ]\n"
);
#else
EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n"
"---\n"
"dv:\n"
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
);
#endif
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
@@ -1280,33 +1265,18 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector)
EXPECT_NO_THROW(fs << "dvv" << dvv);
cv::String fs_result = fs.releaseAndGetString();
#ifndef OPENCV_TRAITS_ENABLE_DEPRECATED
#if defined _MSC_VER && _MSC_VER <= 1800 /* MSVC 2013 and older */
EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n"
"---\n"
"dvv:\n"
" -\n"
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
" - [ 1, 2, 3, -1.5 ]\n"
" - [ 2, 3, 4, 1.5 ]\n"
" - [ 3, 2, 1, 0.5 ]\n"
" -\n"
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
" - [ 3, 2, 1, 0.5 ]\n"
" - [ 1, 2, 3, -1.5 ]\n"
);
#else
EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n"
"---\n"
"dvv:\n"
" -\n"
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
" -\n"
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
);
#endif
#endif // OPENCV_TRAITS_ENABLE_DEPRECATED
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
@@ -1988,5 +1958,53 @@ TEST(Core_InputOutput, FileStorage_invalid_path_regression_21448_JSON)
fs.release();
}
// see https://github.com/opencv/opencv/issues/25073
typedef testing::TestWithParam< std::string > Core_InputOutput_regression_25073;
TEST_P(Core_InputOutput_regression_25073, my_double)
{
cv::String res = "";
double my_double = 0.5;
FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
EXPECT_NO_THROW( fs << "my_double" << my_double );
EXPECT_NO_THROW( fs << "my_int" << 5 );
EXPECT_NO_THROW( res = fs.releaseAndGetString() );
EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5"
EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.000000000000000000e-01"
fs.release();
}
TEST_P(Core_InputOutput_regression_25073, my_float)
{
cv::String res = "";
float my_float = 0.5;
FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
EXPECT_NO_THROW( fs << "my_float" << my_float );
EXPECT_NO_THROW( fs << "my_int" << 5 );
EXPECT_NO_THROW( res = fs.releaseAndGetString() );
EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5"
EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.00000000e-01",
fs.release();
}
TEST_P(Core_InputOutput_regression_25073, my_hfloat)
{
cv::String res = "";
cv::hfloat my_hfloat(0.5);
FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
EXPECT_NO_THROW( fs << "my_hfloat" << my_hfloat );
EXPECT_NO_THROW( fs << "my_int" << 5 );
EXPECT_NO_THROW( res = fs.releaseAndGetString() );
EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5".
EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.0000e-01".
fs.release();
}
INSTANTIATE_TEST_CASE_P( /*nothing*/,
Core_InputOutput_regression_25073,
Values("test.json", "test.xml", "test.yml") );
}} // namespace
+1
View File
@@ -50,6 +50,7 @@ function(ocv_create_builtin_dnn_plugin name target)
endforeach()
if(WIN32)
add_definitions(-D_USE_MATH_DEFINES)
set(OPENCV_PLUGIN_VERSION "${OPENCV_DLLVERSION}" CACHE STRING "")
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
set(OPENCV_PLUGIN_ARCH "_64" CACHE STRING "")
@@ -494,10 +494,9 @@ void convBlockMR1_F32(int np, const float * a, const float * b, float *c, const
void convBlock_F16(int np, const char * _a, const char * _b, char * _c, int ldc, bool init_c, int width,
const int convMR_fp16, const int convNR_fp16)
{
typedef __fp16 float16_t;
const float16_t* a = (const float16_t*)_a;
const float16_t* b = (const float16_t*)_b;
float16_t* c = (float16_t*)_c;
const __fp16* a = (const __fp16*)_a;
const __fp16* b = (const __fp16*)_b;
__fp16* c = (__fp16*)_c;
CV_Assert(convMR_fp16 == 8 && convNR_fp16 == 24);
float16x8_t c00 = vdupq_n_f16(0), c01 = c00, c02 = c00;
@@ -638,12 +637,11 @@ void convBlock_F16(int np, const char * _a, const char * _b, char * _c, int ldc,
void convBlockMR1_F16(int np, const char* _a, const char* _b, float *c, const float _bias, bool init_c,
const float minval, const float maxval, bool ifMinMaxAct, const int width, const int convNR_FP16)
{
typedef __fp16 float16_t;
CV_Assert(convNR_FP16 == 24); // CONV_NR_FP16 = 24
const float16_t* a = (const float16_t*)_a;
const float16_t* b = (const float16_t*)_b;
const __fp16* a = (const __fp16*)_a;
const __fp16* b = (const __fp16*)_b;
const float16_t bias = (float16_t)_bias;
const __fp16 bias = (__fp16)_bias;
float16x8_t c0 = vdupq_n_f16(bias), c1 = c0, c2 = c0;
@@ -85,7 +85,7 @@ int runWinograd63(InputArray _input, InputArray _fusedAddMat, OutputArray _outpu
// works at FP 16.
CONV_WINO_ATOM = CONV_WINO_ATOM_F16;
CONV_WINO_NATOMS = CONV_WINO_NATOMS_F16;
esz = sizeof(float16_t);
esz = sizeof(__fp16);
}
#endif
@@ -435,10 +435,9 @@ void winofunc_AtXA_8x8_F32(const float* inptr, int inpstep,
void winofunc_accum_F16(const char* _inwptr, const char* _wptr, char* _outbuf, int Cg, int iblock,
const int winoIblock, const int winoKblock, const int winoAtomF16, const int winoNatomF16)
{
typedef __fp16 float16_t;
const float16_t* inwptr = (const float16_t*)_inwptr;
const float16_t* wptr = (const float16_t*)_wptr;
float16_t* outbuf = (float16_t*)_outbuf;
const __fp16* inwptr = (const __fp16*)_inwptr;
const __fp16* wptr = (const __fp16*)_wptr;
__fp16* outbuf = (__fp16*)_outbuf;
CV_Assert(winoIblock == 6 && winoKblock == 4 && winoAtomF16 == 8);
@@ -591,8 +590,7 @@ void winofunc_accum_F16(const char* _inwptr, const char* _wptr, char* _outbuf, i
void winofunc_BtXB_8x8_F16(const float * inptr, int inpstep,
char * _outptr, int Cg, const int winoIblock, const int winoAtomF16)
{
typedef __fp16 float16_t;
float16_t* outptr = (float16_t*)_outptr;
__fp16* outptr = (__fp16*)_outptr;
float32x4_t x00 = vld1q_f32(inptr), x01 = vld1q_f32(inptr + 4);
float32x4_t x10 = vld1q_f32(inptr + inpstep), x11 = vld1q_f32(inptr + inpstep + 4);
float32x4_t x20 = vld1q_f32(inptr + inpstep*2), x21 = vld1q_f32(inptr + inpstep*2 + 4);
@@ -757,8 +755,7 @@ void winofunc_AtXA_8x8_F16(const char* _inptr, int inpstep,
float * bpptr, int bpstep, float* outptr, int outstep,
float bias, float minval, float maxval, bool ifMinMaxAct)
{
typedef __fp16 float16_t;
const float16_t* inptr = (const float16_t*)_inptr;
const __fp16* inptr = (const __fp16*)_inptr;
float32x4_t x00 = vcvt_f32_f16(vld1_f16(inptr)), x01 = vcvt_f32_f16(vld1_f16(inptr + 4));
float32x4_t x10 = vcvt_f32_f16(vld1_f16(inptr + inpstep)), x11 = vcvt_f32_f16(vld1_f16(inptr + inpstep + 4));
@@ -26,7 +26,7 @@ void convBlockMR1_F32(int np, const float* a, const float* b, float *c, const fl
#ifdef CONV_ARM_FP16
// Fast convert float 32 to float16
static inline void _cvt32f16f(const float* src, float16_t* dst, int len)
static inline void _cvt32f16f(const float* src, __fp16* dst, int len)
{
int j = 0;
const int VECSZ = 4;
@@ -60,7 +60,7 @@ static inline void _cvt32f16f(const float* src, float16_t* dst, int len)
vst1_f16(dst_FP16 + j, hv);
}
for( ; j < len; j++ )
dst[j] = float16_t(src[j]);
dst[j] = __fp16(src[j]);
}
#endif
@@ -74,12 +74,12 @@ float* FastConv::getWeightsWino()
return alignPtr(weightsWinoBuf.data(), VEC_ALIGN);
}
float16_t* FastConv::getWeightsFP16()
hfloat* FastConv::getWeightsFP16()
{
return alignPtr(weightsBuf_FP16.data(), VEC_ALIGN);
}
float16_t* FastConv::getWeightsWinoFP16()
hfloat* FastConv::getWeightsWinoFP16()
{
return alignPtr(weightsWinoBuf_FP16.data(), VEC_ALIGN);
}
@@ -209,7 +209,7 @@ Ptr<FastConv> initFastConv(
if (conv->useFP16)
{
conv->weightsBuf_FP16.resize(nweights + VEC_ALIGN);
auto weightsPtr_FP16 = conv->getWeightsFP16();
auto weightsPtr_FP16 = (__fp16*)conv->getWeightsFP16();
parallel_for_(Range(0, C), [&](const Range& r0){
for(int c = r0.start; c < r0.end; c++)
@@ -269,11 +269,11 @@ Ptr<FastConv> initFastConv(
float* wptrWino = nullptr;
#ifdef CONV_ARM_FP16
float16_t* wptrWino_FP16 = nullptr;
__fp16* wptrWino_FP16 = nullptr;
if (conv->useFP16)
{
conv->weightsWinoBuf_FP16.resize(nweights + VEC_ALIGN);
wptrWino_FP16 = conv->getWeightsWinoFP16();
wptrWino_FP16 = (__fp16*)conv->getWeightsWinoFP16();
}
else
#endif
@@ -323,7 +323,7 @@ Ptr<FastConv> initFastConv(
#ifdef CONV_ARM_FP16
if (conv->useFP16)
{
float16_t* wptr = wptrWino_FP16 + (g*Kg_nblocks + ki) * Cg *CONV_WINO_KBLOCK*CONV_WINO_AREA +
__fp16* wptr = wptrWino_FP16 + (g*Kg_nblocks + ki) * Cg *CONV_WINO_KBLOCK*CONV_WINO_AREA +
(c*CONV_WINO_KBLOCK + dk)*CONV_WINO_ATOM_F16;
for (int i = 0; i < CONV_WINO_NATOMS_F16; i++,
wptr += Cg * CONV_WINO_KBLOCK * CONV_WINO_ATOM_F16)
@@ -331,7 +331,7 @@ Ptr<FastConv> initFastConv(
CV_Assert(wptrWino_FP16 <= wptr && wptr + CONV_WINO_ATOM_F16 <= wptrWino_FP16 + nweights);
for (int j = 0; j < CONV_WINO_ATOM_F16; j++)
{
wptr[j] = (float16_t)kernelTm[i * CONV_WINO_ATOM_F16 + j];
wptr[j] = (__fp16)kernelTm[i * CONV_WINO_ATOM_F16 + j];
}
}
}
@@ -367,12 +367,12 @@ Ptr<FastConv> initFastConv(
int numStripsMR_FP16 = (Kg + CONV_MR_FP16 - 1) / CONV_MR_FP16;
int Kg_aligned_FP16 = numStripsMR_FP16 * CONV_MR_FP16;
size_t nweights_FP16 = ngroups * Kg_aligned_FP16 * DkHkWkCg;
float16_t* weightsPtr_FP16 = nullptr;
__fp16* weightsPtr_FP16 = nullptr;
if (conv->useFP16)
{
conv->weightsBuf_FP16.resize(nweights_FP16 + VEC_ALIGN);
weightsPtr_FP16 = conv->getWeightsFP16();
weightsPtr_FP16 = (__fp16*)conv->getWeightsFP16();
}
else
#endif
@@ -394,7 +394,7 @@ Ptr<FastConv> initFastConv(
int startK = si * CONV_MR_FP16;
CV_Assert(startK < Kg_aligned_FP16);
float16_t* packed_wptr = weightsPtr_FP16 + DkHkWkCg * (startK + g * Kg_aligned_FP16);
__fp16* packed_wptr = weightsPtr_FP16 + DkHkWkCg * (startK + g * Kg_aligned_FP16);
int dk = Kg - startK < CONV_MR_FP16 ? Kg - startK : CONV_MR_FP16; // check if we need zero padding.
int k_idx = g*Kg + startK;
@@ -405,9 +405,9 @@ Ptr<FastConv> initFastConv(
const float* wptr = srcWeights + wstep * k_idx + c*Hk*Wk*Dk + hwd;
int k = 0;
for(; k < dk; k++, wptr += wstep)
packed_wptr[k] = (float16_t)(*wptr);
packed_wptr[k] = (__fp16)(*wptr);
for(; k < CONV_MR_FP16; k++)
packed_wptr[k] = (float16_t)0.f;
packed_wptr[k] = (__fp16)0.f;
}
}
}});
@@ -467,8 +467,8 @@ static inline void packData8(char*& inpbuf, float*& inptrIn, int& in_w, int& x0,
float* inptrInC = (float* )inptrIn;
#ifdef CONV_ARM_FP16
float16_t* inpbufC_FP16 = (float16_t *)inpbufC;
if (esz == sizeof(float16_t))
__fp16* inpbufC_FP16 = (__fp16 *)inpbufC;
if (esz == sizeof(__fp16))
{
if (stride_w == 1)
{
@@ -565,16 +565,16 @@ static inline void packData2(char *& inpbuf, float*& inptrIn, int& in_w, int& x0
float* inptrInC = inptrIn;
#ifdef CONV_ARM_FP16
float16_t* inpbufC_FP16 = (float16_t *)inpbufC;
if (esz == sizeof(float16_t))
__fp16* inpbufC_FP16 = (__fp16 *)inpbufC;
if (esz == sizeof(__fp16))
{
for (int k = 0; k < ksize; k++)
{
int k1 = ofstab[k];
float v0 = inptrInC[k1];
float v1 = inptrInC[k1 + stride_w];
inpbufC_FP16[k*CONV_NR_FP16] = (float16_t)v0;
inpbufC_FP16[k*CONV_NR_FP16+1] = (float16_t)v1;
inpbufC_FP16[k*CONV_NR_FP16] = (__fp16)v0;
inpbufC_FP16[k*CONV_NR_FP16+1] = (__fp16)v1;
}
} else
#endif
@@ -630,7 +630,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
if (useFP16)
{
for (int c = 0; c < Cg; c++, inptr += inp_planesize, inpbuf += CONV_NR_esz)
_cvt32f16f(inptr, (float16_t *)inpbuf, CONV_NR);
_cvt32f16f(inptr, (__fp16 *)inpbuf, CONV_NR);
}
else
#endif
@@ -644,7 +644,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
{
for (int c = 0; c < Cg; c++, inptr += inp_planesize, inpbuf += CONV_NR_esz)
{
_cvt32f16f(inptr, (float16_t *)inpbuf, slice_len);
_cvt32f16f(inptr, (__fp16 *)inpbuf, slice_len);
}
}
else
@@ -704,11 +704,11 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
#ifdef CONV_ARM_FP16
if (useFP16)
{
float16_t* inpbufC = (float16_t *)inpbuf + s0;
__fp16* inpbufC = (__fp16 *)inpbuf + s0;
for (int w = w0; w < w1; w++)
{
int imgofs = w*dilation_w;
inpbufC[w*CONV_NR] = (float16_t)inptrInC[imgofs];
inpbufC[w*CONV_NR] = (__fp16)inptrInC[imgofs];
}
}
else
@@ -765,14 +765,14 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
#ifdef CONV_ARM_FP16
if (useFP16)
{
float16_t* inpbufC = (float16_t *)inpbuf + s0;
__fp16* inpbufC = (__fp16 *)inpbuf + s0;
for (int h = h0; h < h1; h++)
{
for (int w = w0; w < w1; w++)
{
int imgofs = h*(dilation_h*Wi) + w*dilation_w;
inpbufC[(h*Wk + w)*CONV_NR] = (float16_t)inptrInC[imgofs];
inpbufC[(h*Wk + w)*CONV_NR] = (__fp16)inptrInC[imgofs];
}
}
}
@@ -838,7 +838,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
#ifdef CONV_ARM_FP16
if (useFP16)
{
float16_t* inpbufC = (float16_t* )inpbuf + s0;
__fp16* inpbufC = (__fp16* )inpbuf + s0;
for ( int d = d0; d < d1; d++)
{
@@ -847,7 +847,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
for (int w = w0; w < w1; w++)
{
int imgofs = d*dilation_d*HWi + h*(dilation_h*Wi) + w*dilation_w;
inpbufC[((d*Hk + h)*Wk + w)*CONV_NR] = (float16_t)inptrInC[imgofs];
inpbufC[((d*Hk + h)*Wk + w)*CONV_NR] = (__fp16)inptrInC[imgofs];
}
}
}
@@ -889,7 +889,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
{
float* inpbuf_ki = (float* )inpbuf + k * CONV_NR * Cg + i;
#ifdef CONV_ARM_FP16
float16_t * inpbuf_ki_FP16 = (float16_t *)inpbuf + k * CONV_NR * Cg + i;
__fp16 * inpbuf_ki_FP16 = (__fp16 *)inpbuf + k * CONV_NR * Cg + i;
#endif
int zi = z0 * stride_d + dz - pad_front;
@@ -1053,7 +1053,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
if (useFP16)
{
for (int c = 0; c < Cg; c++, inpbuf_ki_FP16 += CONV_NR, inptr_ki += inp_planesize)
inpbuf_ki_FP16[0] = (float16_t)(*inptr_ki);
inpbuf_ki_FP16[0] = (__fp16)(*inptr_ki);
}
else
#endif
@@ -1069,7 +1069,7 @@ static inline void packInputData(char* inpbuf_task, float* inp, const int* ofsta
if (useFP16)
{
for (int c = 0; c < Cg; c++, inpbuf_ki_FP16 += CONV_NR)
inpbuf_ki_FP16[0] = (float16_t)0.f;
inpbuf_ki_FP16[0] = (__fp16)0.f;
}
else
#endif
@@ -1257,7 +1257,7 @@ void runFastConv(InputArray _input, OutputArray _output, const Ptr<FastConv>& co
// works at FP 16.
CONV_NR = CONV_NR_FP16;
CONV_MR = CONV_MR_FP16;
esz = sizeof(float16_t);
esz = sizeof(__fp16);
}
#endif
@@ -1511,7 +1511,7 @@ void runFastConv(InputArray _input, OutputArray _output, const Ptr<FastConv>& co
char *wptr = weights + (k0_block * DkHkWkCg + c0 * CONV_MR) * esz;
float *cptr = cbuf_task + stripe * CONV_NR;
float16_t* cptr_f16 = (float16_t*)cbuf_task + stripe*CONV_NR;
hfloat* cptr_f16 = (hfloat*)cbuf_task + stripe*CONV_NR;
for (int k = k0_block; k < k1_block; k += CONV_MR,
wptr += DkHkWkCg * CONV_MR * esz, cptr += CONV_MR * ldc, cptr_f16 += CONV_MR * ldc)
{
@@ -1547,7 +1547,7 @@ void runFastConv(InputArray _input, OutputArray _output, const Ptr<FastConv>& co
size_t outofs = ((n * ngroups + g) * Kg + k0_block) * out_planesize + zyx0;
const float *cptr = cbuf_task;
const float16_t *cptr_fp16 = (const float16_t *)cbuf_task;
const hfloat *cptr_fp16 = (const hfloat *)cbuf_task;
float *outptr = out + outofs;
const float *pbptr = fusedAddPtr0 ? fusedAddPtr0 + outofs : 0;
@@ -62,10 +62,10 @@ struct FastConv
float* getWeights();
float* getWeightsWino();
std::vector<float16_t> weightsBuf_FP16;
std::vector<float16_t> weightsWinoBuf_FP16;
float16_t* getWeightsFP16();
float16_t* getWeightsWinoFP16();
std::vector<hfloat> weightsBuf_FP16;
std::vector<hfloat> weightsWinoBuf_FP16;
hfloat* getWeightsFP16();
hfloat* getWeightsWinoFP16();
int conv_type;
int conv_dim; // Flag for conv1d, conv2d, or conv3d.
@@ -1745,12 +1745,12 @@ Mat getMatFromTensor(const opencv_onnx::TensorProto& tensor_proto)
#endif
const ::google::protobuf::RepeatedField<int32_t> field = tensor_proto.int32_data();
AutoBuffer<float16_t, 16> aligned_val;
AutoBuffer<hfloat, 16> aligned_val;
size_t sz = tensor_proto.int32_data().size();
aligned_val.allocate(sz);
float16_t* bufPtr = aligned_val.data();
hfloat* bufPtr = aligned_val.data();
float16_t *fp16Ptr = (float16_t *)field.data();
hfloat *fp16Ptr = (hfloat *)field.data();
for (int i = 0; i < sz; i++)
{
bufPtr[i] = fp16Ptr[i*2 + offset];
@@ -1762,11 +1762,11 @@ Mat getMatFromTensor(const opencv_onnx::TensorProto& tensor_proto)
char* val = const_cast<char*>(tensor_proto.raw_data().c_str());
#if CV_STRONG_ALIGNMENT
// Aligned pointer is required.
AutoBuffer<float16_t, 16> aligned_val;
if (!isAligned<sizeof(float16_t)>(val))
AutoBuffer<hfloat, 16> aligned_val;
if (!isAligned<sizeof(hfloat)>(val))
{
size_t sz = tensor_proto.raw_data().size();
aligned_val.allocate(divUp(sz, sizeof(float16_t)));
aligned_val.allocate(divUp(sz, sizeof(hfloat)));
memcpy(aligned_val.data(), val, sz);
val = (char*)aligned_val.data();
}
@@ -58,7 +58,7 @@ public class AKAZEDescriptorExtractorTest extends OpenCVTestCase {
extractor.write(filename);
String truth = "%YAML:1.0\n---\nformat: 3\nname: \"Feature2D.AKAZE\"\ndescriptor: 5\ndescriptor_channels: 3\ndescriptor_size: 0\nthreshold: 1.0000000474974513e-03\noctaves: 4\nsublevels: 4\ndiffusivity: 1\nmax_points: -1\n";
String truth = "%YAML:1.0\n---\nformat: 3\nname: \"Feature2D.AKAZE\"\ndescriptor: 5\ndescriptor_channels: 3\ndescriptor_size: 0\nthreshold: 0.0010000000474974513\noctaves: 4\nsublevels: 4\ndiffusivity: 1\nmax_points: -1\n";
String actual = readFile(filename);
actual = actual.replaceAll("e([+-])0(\\d\\d)", "e$1$2"); // NOTE: workaround for different platforms double representation
assertEquals(truth, actual);
@@ -58,7 +58,7 @@ public class GFTTFeatureDetectorTest extends OpenCVTestCase {
detector.write(filename);
String truth = "%YAML:1.0\n---\nname: \"Feature2D.GFTTDetector\"\nnfeatures: 1000\nqualityLevel: 1.0000000000000000e-02\nminDistance: 1.\nblockSize: 3\ngradSize: 3\nuseHarrisDetector: 0\nk: 4.0000000000000001e-02\n";
String truth = "%YAML:1.0\n---\nname: \"Feature2D.GFTTDetector\"\nnfeatures: 1000\nqualityLevel: 0.01\nminDistance: 1.\nblockSize: 3\ngradSize: 3\nuseHarrisDetector: 0\nk: 0.040000000000000001\n";
String actual = readFile(filename);
actual = actual.replaceAll("e([+-])0(\\d\\d)", "e$1$2"); // NOTE: workaround for different platforms double representation
assertEquals(truth, actual);
@@ -57,7 +57,7 @@ public class KAZEDescriptorExtractorTest extends OpenCVTestCase {
extractor.write(filename);
String truth = "%YAML:1.0\n---\nformat: 3\nname: \"Feature2D.KAZE\"\nextended: 0\nupright: 0\nthreshold: 1.0000000474974513e-03\noctaves: 4\nsublevels: 4\ndiffusivity: 1\n";
String truth = "%YAML:1.0\n---\nformat: 3\nname: \"Feature2D.KAZE\"\nextended: 0\nupright: 0\nthreshold: 0.0010000000474974513\noctaves: 4\nsublevels: 4\ndiffusivity: 1\n";
String actual = readFile(filename);
actual = actual.replaceAll("e([+-])0(\\d\\d)", "e$1$2"); // NOTE: workaround for different platforms double representation
assertEquals(truth, actual);
@@ -61,7 +61,7 @@ public class MSERFeatureDetectorTest extends OpenCVTestCase {
detector.write(filename);
String truth = "%YAML:1.0\n---\nname: \"Feature2D.MSER\"\ndelta: 5\nminArea: 60\nmaxArea: 14400\nmaxVariation: 2.5000000000000000e-01\nminDiversity: 2.0000000000000001e-01\nmaxEvolution: 200\nareaThreshold: 1.0100000000000000e+00\nminMargin: 3.0000000000000001e-03\nedgeBlurSize: 5\npass2Only: 0\n";
String truth = "%YAML:1.0\n---\nname: \"Feature2D.MSER\"\ndelta: 5\nminArea: 60\nmaxArea: 14400\nmaxVariation: 0.25\nminDiversity: 0.20000000000000001\nmaxEvolution: 200\nareaThreshold: 1.01\nminMargin: 0.0030000000000000001\nedgeBlurSize: 5\npass2Only: 0\n";
String actual = readFile(filename);
actual = actual.replaceAll("e([+-])0(\\d\\d)", "e$1$2"); // NOTE: workaround for different platforms double representation
assertEquals(truth, actual);
@@ -111,7 +111,7 @@ public class ORBDescriptorExtractorTest extends OpenCVTestCase {
extractor.write(filename);
String truth = "%YAML:1.0\n---\nname: \"Feature2D.ORB\"\nnfeatures: 500\nscaleFactor: 1.2000000476837158e+00\nnlevels: 8\nedgeThreshold: 31\nfirstLevel: 0\nwta_k: 2\nscoreType: 0\npatchSize: 31\nfastThreshold: 20\n";
String truth = "%YAML:1.0\n---\nname: \"Feature2D.ORB\"\nnfeatures: 500\nscaleFactor: 1.2000000476837158\nnlevels: 8\nedgeThreshold: 31\nfirstLevel: 0\nwta_k: 2\nscoreType: 0\npatchSize: 31\nfastThreshold: 20\n";
// String truth = "%YAML:1.0\n---\n";
String actual = readFile(filename);
actual = actual.replaceAll("e\\+000", "e+00"); // NOTE: workaround for different platforms double representation
@@ -100,7 +100,7 @@ public class SIFTDescriptorExtractorTest extends OpenCVTestCase {
extractor.write(filename);
String truth = "%YAML:1.0\n---\nname: \"Feature2D.SIFT\"\nnfeatures: 0\nnOctaveLayers: 3\ncontrastThreshold: 4.0000000000000001e-02\nedgeThreshold: 10.\nsigma: 1.6000000000000001e+00\ndescriptorType: 5\n";
String truth = "%YAML:1.0\n---\nname: \"Feature2D.SIFT\"\nnfeatures: 0\nnOctaveLayers: 3\ncontrastThreshold: 0.040000000000000001\nedgeThreshold: 10.\nsigma: 1.6000000000000001\ndescriptorType: 5\n";
String actual = readFile(filename);
actual = actual.replaceAll("e([+-])0(\\d\\d)", "e$1$2"); // NOTE: workaround for different platforms double representation
assertEquals(truth, actual);
@@ -133,8 +133,7 @@ public class SIMPLEBLOBFeatureDetectorTest extends OpenCVTestCase {
String filename = OpenCVTestRunner.getTempFileName("xml");
detector.write(filename);
String truth = "<?xml version=\"1.0\"?>\n<opencv_storage>\n<format>3</format>\n<thresholdStep>10.</thresholdStep>\n<minThreshold>50.</minThreshold>\n<maxThreshold>220.</maxThreshold>\n<minRepeatability>2</minRepeatability>\n<minDistBetweenBlobs>10.</minDistBetweenBlobs>\n<filterByColor>1</filterByColor>\n<blobColor>0</blobColor>\n<filterByArea>1</filterByArea>\n<minArea>25.</minArea>\n<maxArea>5000.</maxArea>\n<filterByCircularity>0</filterByCircularity>\n<minCircularity>8.0000001192092896e-01</minCircularity>\n<maxCircularity>3.4028234663852886e+38</maxCircularity>\n<filterByInertia>1</filterByInertia>\n<minInertiaRatio>1.0000000149011612e-01</minInertiaRatio>\n<maxInertiaRatio>3.4028234663852886e+38</maxInertiaRatio>\n<filterByConvexity>1</filterByConvexity>\n<minConvexity>9.4999998807907104e-01</minConvexity>\n<maxConvexity>3.4028234663852886e+38</maxConvexity>\n<collectContours>0</collectContours>\n</opencv_storage>\n";
String truth = "<?xml version=\"1.0\"?>\n<opencv_storage>\n<format>3</format>\n<thresholdStep>10.</thresholdStep>\n<minThreshold>50.</minThreshold>\n<maxThreshold>220.</maxThreshold>\n<minRepeatability>2</minRepeatability>\n<minDistBetweenBlobs>10.</minDistBetweenBlobs>\n<filterByColor>1</filterByColor>\n<blobColor>0</blobColor>\n<filterByArea>1</filterByArea>\n<minArea>25.</minArea>\n<maxArea>5000.</maxArea>\n<filterByCircularity>0</filterByCircularity>\n<minCircularity>0.80000001192092896</minCircularity>\n<maxCircularity>3.4028234663852886e+38</maxCircularity>\n<filterByInertia>1</filterByInertia>\n<minInertiaRatio>0.10000000149011612</minInertiaRatio>\n<maxInertiaRatio>3.4028234663852886e+38</maxInertiaRatio>\n<filterByConvexity>1</filterByConvexity>\n<minConvexity>0.94999998807907104</minConvexity>\n<maxConvexity>3.4028234663852886e+38</maxConvexity>\n<collectContours>0</collectContours>\n</opencv_storage>\n";
assertEquals(truth, readFile(filename));
}
}
+1 -1
View File
@@ -40,7 +40,7 @@
//
//M*/
#include <TargetConditionals.h>
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
#if (TARGET_OS_IOS || TARGET_OS_VISION) && !TARGET_OS_MACCATALYST
#import <UIKit/UIKit.h>
#include "apple_conversions.h"
+16 -16
View File
@@ -6,8 +6,8 @@ See cv::cvtColor and cv::ColorConversionCodes
@todo document other conversion modes
@anchor color_convert_rgb_gray
RGB \emoji arrow_right GRAY
------------------------------
RGB <-> GRAY
------------
Transformations within RGB space like adding/removing the alpha channel, reversing the channel
order, conversion to/from 16-bit RGB color (R5:G6:B5 or R5:G5:B5), as well as conversion
to/from grayscale using:
@@ -22,8 +22,8 @@ More advanced channel reordering can also be done with cv::mixChannels.
@see cv::COLOR_BGR2GRAY, cv::COLOR_RGB2GRAY, cv::COLOR_GRAY2BGR, cv::COLOR_GRAY2RGB
@anchor color_convert_rgb_xyz
RGB \emoji arrow_right CIE XYZ.Rec 709 with D65 white point
--------------------------------------------------------------
RGB <-> CIE XYZ.Rec 709 with D65 white point
--------------------------------------------
\f[\begin{bmatrix} X \\ Y \\ Z
\end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227
\end{bmatrix} \cdot \begin{bmatrix} R \\ G \\ B
@@ -37,8 +37,8 @@ RGB \emoji arrow_right CIE XYZ.Rec 709 with D65 white point
@see cv::COLOR_BGR2XYZ, cv::COLOR_RGB2XYZ, cv::COLOR_XYZ2BGR, cv::COLOR_XYZ2RGB
@anchor color_convert_rgb_ycrcb
RGB \emoji arrow_right YCrCb JPEG (or YCC)
---------------------------------------------
RGB <-> YCrCb JPEG (or YCC)
---------------------------
\f[Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B\f]
\f[Cr \leftarrow (R-Y) \cdot 0.713 + delta\f]
\f[Cb \leftarrow (B-Y) \cdot 0.564 + delta\f]
@@ -51,8 +51,8 @@ Y, Cr, and Cb cover the whole value range.
@see cv::COLOR_BGR2YCrCb, cv::COLOR_RGB2YCrCb, cv::COLOR_YCrCb2BGR, cv::COLOR_YCrCb2RGB
@anchor color_convert_rgb_hsv
RGB \emoji arrow_right HSV
-----------------------------
RGB <-> HSV
-----------
In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and
scaled to fit the 0 to 1 range.
@@ -73,8 +73,8 @@ The values are then converted to the destination data type:
@see cv::COLOR_BGR2HSV, cv::COLOR_RGB2HSV, cv::COLOR_HSV2BGR, cv::COLOR_HSV2RGB
@anchor color_convert_rgb_hls
RGB \emoji arrow_right HLS
-----------------------------
RGB <-> HLS
-----------
In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and
scaled to fit the 0 to 1 range.
@@ -98,8 +98,8 @@ The values are then converted to the destination data type:
@see cv::COLOR_BGR2HLS, cv::COLOR_RGB2HLS, cv::COLOR_HLS2BGR, cv::COLOR_HLS2RGB
@anchor color_convert_rgb_lab
RGB \emoji arrow_right CIE L\*a\*b\*
---------------------------------------
RGB <-> CIE L\*a\*b\*
---------------------
In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and
scaled to fit the 0 to 1 range.
@@ -123,8 +123,8 @@ are then converted to the destination data type:
@see cv::COLOR_BGR2Lab, cv::COLOR_RGB2Lab, cv::COLOR_Lab2BGR, cv::COLOR_Lab2RGB
@anchor color_convert_rgb_luv
RGB \emoji arrow_right CIE L\*u\*v\*
---------------------------------------
RGB <-> CIE L\*u\*v\*
---------------------
In case of 8-bit and 16-bit images, R, G, and B are converted to the floating-point format and
scaled to fit 0 to 1 range.
@@ -150,8 +150,8 @@ sources on the web, primarily from the Charles Poynton site <http://www.poynton.
@see cv::COLOR_BGR2Luv, cv::COLOR_RGB2Luv, cv::COLOR_Luv2BGR, cv::COLOR_Luv2RGB
@anchor color_convert_bayer
Bayer \emoji arrow_right RGB
---------------------------
Bayer -> RGB
------------
The Bayer pattern is widely used in CCD and CMOS cameras. It enables you to get color pictures
from a single plane where R, G, and B pixels (sensors of a particular component) are interleaved
as follows:
@@ -415,6 +415,9 @@ void bilateralFilter( InputArray _src, OutputArray _dst, int d,
Mat src = _src.getMat(), dst = _dst.getMat();
CALL_HAL(bilateralFilter, cv_hal_bilateralFilter, src.data, src.step, dst.data, dst.step, src.cols, src.rows, src.depth(),
src.channels(), d, sigmaColor, sigmaSpace, borderType);
CV_IPP_RUN_FAST(ipp_bilateralFilter(src, dst, d, sigmaColor, sigmaSpace, borderType));
if( src.depth() == CV_8U )
+23
View File
@@ -763,6 +763,29 @@ inline int hal_ni_medianBlur(const uchar* src_data, size_t src_step, uchar* dst_
#define cv_hal_medianBlur hal_ni_medianBlur
//! @endcond
/**
@brief Calculate bilateral filter. See https://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
@param src_data Source image data
@param src_step Source image step
@param dst_data Destination image data
@param dst_step Destination image step
@param width Source image width
@param height Source image height
@param depth Depths of source and destination image. Should support CV_8U and CV_32F
@param cn Number of channels
@param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, it is computed from sigmaSpace
@param sigma_color Filter sigma in the color space
@param sigma_space Filter sigma in the coordinate space. When d>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is proportional to sigmaSpace
@param border_type border mode used to extrapolate pixels outside of the image
*/
inline int hal_ni_bilateralFilter(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int depth, int cn, int d, double sigma_color, double sigma_space, int border_type)
{ return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_bilateralFilter hal_ni_bilateralFilter
//! @endcond
/**
@brief Calculates adaptive threshold
@param src_data Source image data
@@ -0,0 +1,246 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "opencv2/objdetect/aruco_detector.hpp"
namespace opencv_test { namespace {
TEST(CV_ArucoTutorial, can_find_singlemarkersoriginal)
{
string img_path = cvtest::findDataFile("aruco/singlemarkersoriginal.jpg");
Mat image = imread(img_path);
aruco::ArucoDetector detector(aruco::getPredefinedDictionary(aruco::DICT_6X6_250));
vector<int> ids;
vector<vector<Point2f> > corners, rejected;
const size_t N = 6ull;
// corners of ArUco markers with indices goldCornersIds
const int goldCorners[N][8] = { {359,310, 404,310, 410,350, 362,350}, {427,255, 469,256, 477,289, 434,288},
{233,273, 190,273, 196,241, 237,241}, {298,185, 334,186, 335,212, 297,211},
{425,163, 430,186, 394,186, 390,162}, {195,155, 230,155, 227,178, 190,178} };
const int goldCornersIds[N] = { 40, 98, 62, 23, 124, 203};
map<int, const int*> mapGoldCorners;
for (size_t i = 0; i < N; i++)
mapGoldCorners[goldCornersIds[i]] = goldCorners[i];
detector.detectMarkers(image, corners, ids, rejected);
ASSERT_EQ(N, ids.size());
for (size_t i = 0; i < N; i++)
{
int arucoId = ids[i];
ASSERT_EQ(4ull, corners[i].size());
ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end());
for (int j = 0; j < 4; j++)
{
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2]), corners[i][j].x, 1.f);
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2 + 1]), corners[i][j].y, 1.f);
}
}
}
TEST(CV_ArucoTutorial, can_find_gboriginal)
{
string imgPath = cvtest::findDataFile("aruco/gboriginal.jpg");
Mat image = imread(imgPath);
string dictPath = cvtest::findDataFile("aruco/tutorial_dict.yml");
aruco::Dictionary dictionary;
FileStorage fs(dictPath, FileStorage::READ);
dictionary.aruco::Dictionary::readDictionary(fs.root()); // set marker from tutorial_dict.yml
aruco::DetectorParameters detectorParams;
aruco::ArucoDetector detector(dictionary, detectorParams);
vector<int> ids;
vector<vector<Point2f> > corners, rejected;
const size_t N = 35ull;
// corners of ArUco markers with indices 0, 1, ..., 34
const int goldCorners[N][8] = { {252,74, 286,81, 274,102, 238,95}, {295,82, 330,89, 319,111, 282,104},
{338,91, 375,99, 365,121, 327,113}, {383,100, 421,107, 412,130, 374,123},
{429,109, 468,116, 461,139, 421,132}, {235,100, 270,108, 257,130, 220,122},
{279,109, 316,117, 304,140, 266,133}, {324,119, 362,126, 352,150, 313,143},
{371,128, 410,136, 400,161, 360,152}, {418,139, 459,145, 451,170, 410,163},
{216,128, 253,136, 239,161, 200,152}, {262,138, 300,146, 287,172, 248,164},
{309,148, 349,156, 337,183, 296,174}, {358,158, 398,167, 388,194, 346,185},
{407,169, 449,176, 440,205, 397,196}, {196,158, 235,168, 218,195, 179,185},
{243,170, 283,178, 269,206, 228,197}, {293,180, 334,190, 321,218, 279,209},
{343,192, 385,200, 374,230, 330,220}, {395,203, 438,211, 429,241, 384,233},
{174,192, 215,201, 197,231, 156,221}, {223,204, 265,213, 249,244, 207,234},
{275,215, 317,225, 303,257, 259,246}, {327,227, 371,238, 359,270, 313,259},
{381,240, 426,249, 416,282, 369,273}, {151,228, 193,238, 173,271, 130,260},
{202,241, 245,251, 228,285, 183,274}, {255,254, 300,264, 284,299, 238,288},
{310,267, 355,278, 342,314, 295,302}, {366,281, 413,290, 402,327, 353,317},
{125,267, 168,278, 147,314, 102,303}, {178,281, 223,293, 204,330, 157,317},
{233,296, 280,307, 263,346, 214,333}, {291,310, 338,322, 323,363, 274,349},
{349,325, 399,336, 386,378, 335,366} };
map<int, const int*> mapGoldCorners;
for (int i = 0; i < static_cast<int>(N); i++)
mapGoldCorners[i] = goldCorners[i];
detector.detectMarkers(image, corners, ids, rejected);
ASSERT_EQ(N, ids.size());
for (size_t i = 0; i < N; i++)
{
int arucoId = ids[i];
ASSERT_EQ(4ull, corners[i].size());
ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end());
for (int j = 0; j < 4; j++)
{
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j*2]), corners[i][j].x, 1.f);
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j*2+1]), corners[i][j].y, 1.f);
}
}
}
TEST(CV_ArucoTutorial, can_find_choriginal)
{
string imgPath = cvtest::findDataFile("aruco/choriginal.jpg");
Mat image = imread(imgPath);
aruco::ArucoDetector detector(aruco::getPredefinedDictionary(aruco::DICT_6X6_250));
vector< int > ids;
vector< vector< Point2f > > corners, rejected;
const size_t N = 17ull;
// corners of aruco markers with indices goldCornersIds
const int goldCorners[N][8] = { {268,77, 290,80, 286,97, 263,94}, {360,90, 382,93, 379,111, 357,108},
{211,106, 233,109, 228,127, 205,123}, {306,120, 328,124, 325,142, 302,138},
{402,135, 425,139, 423,157, 400,154}, {247,152, 271,155, 267,174, 242,171},
{347,167, 371,171, 369,191, 344,187}, {185,185, 209,189, 203,210, 178,206},
{288,201, 313,206, 309,227, 284,223}, {393,218, 418,222, 416,245, 391,241},
{223,240, 250,244, 244,268, 217,263}, {333,258, 359,262, 356,286, 329,282},
{152,281, 179,285, 171,312, 143,307}, {267,300, 294,305, 289,331, 261,327},
{383,319, 410,324, 408,351, 380,347}, {194,347, 223,352, 216,382, 186,377},
{315,368, 345,373, 341,403, 310,398} };
map<int, const int*> mapGoldCorners;
for (int i = 0; i < static_cast<int>(N); i++)
mapGoldCorners[i] = goldCorners[i];
detector.detectMarkers(image, corners, ids, rejected);
ASSERT_EQ(N, ids.size());
for (size_t i = 0; i < N; i++)
{
int arucoId = ids[i];
ASSERT_EQ(4ull, corners[i].size());
ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end());
for (int j = 0; j < 4; j++)
{
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2]), corners[i][j].x, 1.f);
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2 + 1]), corners[i][j].y, 1.f);
}
}
}
TEST(CV_ArucoTutorial, can_find_chocclusion)
{
string imgPath = cvtest::findDataFile("aruco/chocclusion_original.jpg");
Mat image = imread(imgPath);
aruco::ArucoDetector detector(aruco::getPredefinedDictionary(aruco::DICT_6X6_250));
vector< int > ids;
vector< vector< Point2f > > corners, rejected;
const size_t N = 13ull;
// corners of aruco markers with indices goldCornersIds
const int goldCorners[N][8] = { {301,57, 322,62, 317,79, 295,73}, {391,80, 413,85, 408,103, 386,97},
{242,79, 264,85, 256,102, 234,96}, {334,103, 357,109, 352,126, 329,121},
{428,129, 451,134, 448,152, 425,146}, {274,128, 296,134, 290,153, 266,147},
{371,154, 394,160, 390,180, 366,174}, {208,155, 232,161, 223,181, 199,175},
{309,182, 333,188, 327,209, 302,203}, {411,210, 436,216, 432,238, 407,231},
{241,212, 267,219, 258,242, 232,235}, {167,244, 194,252, 183,277, 156,269},
{202,314, 230,322, 220,349, 191,341} };
map<int, const int*> mapGoldCorners;
const int goldCornersIds[N] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15};
for (int i = 0; i < static_cast<int>(N); i++)
mapGoldCorners[goldCornersIds[i]] = goldCorners[i];
detector.detectMarkers(image, corners, ids, rejected);
ASSERT_EQ(N, ids.size());
for (size_t i = 0; i < N; i++)
{
int arucoId = ids[i];
ASSERT_EQ(4ull, corners[i].size());
ASSERT_TRUE(mapGoldCorners.find(arucoId) != mapGoldCorners.end());
for (int j = 0; j < 4; j++)
{
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2]), corners[i][j].x, 1.f);
EXPECT_NEAR(static_cast<float>(mapGoldCorners[arucoId][j * 2 + 1]), corners[i][j].y, 1.f);
}
}
}
TEST(CV_ArucoTutorial, can_find_diamondmarkers)
{
string imgPath = cvtest::findDataFile("aruco/diamondmarkers.jpg");
Mat image = imread(imgPath);
string dictPath = cvtest::findDataFile("aruco/tutorial_dict.yml");
aruco::Dictionary dictionary;
FileStorage fs(dictPath, FileStorage::READ);
dictionary.aruco::Dictionary::readDictionary(fs.root()); // set marker from tutorial_dict.yml
string detectorPath = cvtest::findDataFile("aruco/detector_params.yml");
fs = FileStorage(detectorPath, FileStorage::READ);
aruco::DetectorParameters detectorParams;
detectorParams.readDetectorParameters(fs.root());
detectorParams.cornerRefinementMethod = aruco::CORNER_REFINE_APRILTAG;
aruco::CharucoBoard charucoBoard(Size(3, 3), 0.4f, 0.25f, dictionary);
aruco::CharucoDetector detector(charucoBoard, aruco::CharucoParameters(), detectorParams);
vector<int> ids;
vector<vector<Point2f> > corners, diamondCorners;
vector<Vec4i> diamondIds;
const size_t N = 12ull;
// corner indices of ArUco markers
const int goldCornersIds[N] = { 4, 12, 11, 3, 12, 10, 12, 10, 10, 11, 2, 11 };
map<int, int> counterGoldCornersIds;
for (int i = 0; i < static_cast<int>(N); i++)
counterGoldCornersIds[goldCornersIds[i]]++;
const size_t diamondsN = 3;
// corners of diamonds with Vec4i indices
const float goldDiamondCorners[diamondsN][8] = {{195.6f,150.9f, 213.5f,201.2f, 136.4f,215.3f, 122.4f,163.5f},
{501.1f,171.3f, 501.9f,208.5f, 446.2f,199.8f, 447.8f,163.3f},
{343.4f,361.2f, 359.7f,328.7f, 400.8f,344.6f, 385.7f,378.4f}};
auto comp = [](const Vec4i& a, const Vec4i& b) {
for (int i = 0; i < 3; i++)
if (a[i] != b[i]) return a[i] < b[i];
return a[3] < b[3];
};
map<Vec4i, const float*, decltype(comp)> goldDiamonds(comp);
goldDiamonds[Vec4i(10, 4, 11, 12)] = goldDiamondCorners[0];
goldDiamonds[Vec4i(10, 3, 11, 12)] = goldDiamondCorners[1];
goldDiamonds[Vec4i(10, 2, 11, 12)] = goldDiamondCorners[2];
detector.detectDiamonds(image, diamondCorners, diamondIds, corners, ids);
map<int, int> counterRes;
ASSERT_EQ(N, ids.size());
for (size_t i = 0; i < N; i++)
{
int arucoId = ids[i];
counterRes[arucoId]++;
}
ASSERT_EQ(counterGoldCornersIds, counterRes); // check the number of ArUco markers
ASSERT_EQ(goldDiamonds.size(), diamondIds.size()); // check the number of diamonds
for (size_t i = 0; i < goldDiamonds.size(); i++)
{
Vec4i diamondId = diamondIds[i];
ASSERT_TRUE(goldDiamonds.find(diamondId) != goldDiamonds.end());
for (int j = 0; j < 4; j++)
{
EXPECT_NEAR(goldDiamonds[diamondId][j * 2], diamondCorners[i][j].x, 0.5f);
EXPECT_NEAR(goldDiamonds[diamondId][j * 2 + 1], diamondCorners[i][j].y, 0.5f);
}
}
}
}} // namespace
+15 -4
View File
@@ -46,6 +46,7 @@
// */
#include <queue>
#include <type_traits>
#include "precomp.hpp"
#include "opencv2/core/core_c.h"
@@ -55,6 +56,16 @@
#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \
((mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type round_cast(float val) {
return cv::saturate_cast<T>(val);
}
template<typename T>
typename std::enable_if<!std::is_floating_point<T>::value, T>::type round_cast(float val) {
return cv::saturate_cast<T>(val + 0.5);
}
inline float
min4( float a, float b, float c, float d )
{
@@ -339,8 +350,8 @@ icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQu
}
}
for (color=0; color<=2; color++) {
sat = (float)((Ia[color]/s[color]+(Jx[color]+Jy[color])/(sqrt(Jx[color]*Jx[color]+Jy[color]*Jy[color])+1.0e-20f)+0.5f));
CV_MAT_3COLOR_ELEM(*out,uchar,i-1,j-1,color) = cv::saturate_cast<uchar>(sat);
sat = (float)(Ia[color]/s[color]+(Jx[color]+Jy[color])/(sqrt(Jx[color]*Jx[color]+Jy[color]*Jy[color])+1.0e-20f));
CV_MAT_3COLOR_ELEM(*out,uchar,i-1,j-1,color) = round_cast<uchar>(sat);
}
CV_MAT_ELEM(*f,uchar,i,j) = BAND;
@@ -449,9 +460,9 @@ icvTeleaInpaintFMM(const CvMat *f, CvMat *t, CvMat *out, int range, CvPriorityQu
}
}
}
sat = (float)((Ia/s+(Jx+Jy)/(sqrt(Jx*Jx+Jy*Jy)+1.0e-20f)+0.5f));
sat = (float)(Ia/s+(Jx+Jy)/(sqrt(Jx*Jx+Jy*Jy)+1.0e-20f));
{
CV_MAT_ELEM(*out,data_type,i-1,j-1) = cv::saturate_cast<data_type>(sat);
CV_MAT_ELEM(*out,data_type,i-1,j-1) = round_cast<data_type>(sat);
}
}
+7 -7
View File
@@ -116,9 +116,9 @@ void CV_InpaintTest::run( int )
TEST(Photo_Inpaint, regression) { CV_InpaintTest test; test.safe_run(); }
typedef testing::TestWithParam<tuple<int> > formats;
typedef testing::TestWithParam<tuple<perf::MatType> > formats;
TEST_P(formats, 1c)
TEST_P(formats, basic)
{
const int type = get<0>(GetParam());
Mat src(100, 100, type);
@@ -126,18 +126,18 @@ TEST_P(formats, 1c)
Mat ref = src.clone();
Mat dst, mask = Mat::zeros(src.size(), CV_8U);
circle(src, Point(50, 50), 5, Scalar(200), 6);
circle(mask, Point(50, 50), 5, Scalar(200), 6);
circle(src, Point(50, 50), 5, Scalar::all(200), 6);
circle(mask, Point(50, 50), 5, Scalar::all(200), 6);
inpaint(src, mask, dst, 10, INPAINT_NS);
Mat dst2;
inpaint(src, mask, dst2, 10, INPAINT_TELEA);
ASSERT_LE(cv::norm(dst, ref, NORM_INF), 3.);
ASSERT_LE(cv::norm(dst2, ref, NORM_INF), 3.);
ASSERT_EQ(cv::norm(dst, ref, NORM_INF), 0.);
ASSERT_EQ(cv::norm(dst2, ref, NORM_INF), 0.);
}
INSTANTIATE_TEST_CASE_P(Photo_Inpaint, formats, testing::Values(CV_32F, CV_16U, CV_8U));
INSTANTIATE_TEST_CASE_P(Photo_Inpaint, formats, testing::Values(CV_32FC1, CV_16UC1, CV_8UC1, CV_8UC3));
TEST(Photo_InpaintBorders, regression)
{
@@ -34,7 +34,10 @@ _PREDEFINED_TYPES = (
PrimitiveTypeNode.str_("char"),
PrimitiveTypeNode.str_("String"),
PrimitiveTypeNode.str_("c_string"),
ConditionalAliasTypeNode.numpy_array_("NumPyArrayGeneric"),
ConditionalAliasTypeNode.numpy_array_(
"NumPyArrayNumeric",
dtype="numpy.integer[_typing.Any] | numpy.floating[_typing.Any]"
),
ConditionalAliasTypeNode.numpy_array_("NumPyArrayFloat32", dtype="numpy.float32"),
ConditionalAliasTypeNode.numpy_array_("NumPyArrayFloat64", dtype="numpy.float64"),
NoneTypeNode("void"),
@@ -42,7 +45,7 @@ _PREDEFINED_TYPES = (
AliasTypeNode.union_(
"Mat",
items=(ASTNodeTypeNode("Mat", module_name="cv2.mat_wrapper"),
AliasRefTypeNode("NumPyArrayGeneric")),
AliasRefTypeNode("NumPyArrayNumeric")),
export_name="MatLike"
),
AliasTypeNode.sequence_("MatShape", PrimitiveTypeNode.int_()),
+2 -2
View File
@@ -221,18 +221,18 @@ cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_file(const std::strin
}
#if !TARGET_OS_VISION
cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
{
#if !TARGET_OS_VISION
CvCaptureCAM* retval = new CvCaptureCAM(index);
if (retval->didStart())
return cv::makePtr<cv::LegacyCapture>(retval);
delete retval;
#endif
return 0;
}
#endif
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc,
double fps, const cv::Size &frameSize,