Merge pull request #4018 from vpisarev:imgproc_video_fixes
This commit is contained in:
commit
a85bb091c8
@ -4714,8 +4714,8 @@ SparseMat::Hdr::Hdr( int _dims, const int* _sizes, int _type )
|
|||||||
refcount = 1;
|
refcount = 1;
|
||||||
|
|
||||||
dims = _dims;
|
dims = _dims;
|
||||||
valueOffset = (int)alignSize(sizeof(SparseMat::Node) +
|
valueOffset = (int)alignSize(sizeof(SparseMat::Node) - MAX_DIM*sizeof(int) +
|
||||||
sizeof(int)*std::max(dims - CV_MAX_DIM, 0), CV_ELEM_SIZE1(_type));
|
dims*sizeof(int), CV_ELEM_SIZE1(_type));
|
||||||
nodeSize = alignSize(valueOffset +
|
nodeSize = alignSize(valueOffset +
|
||||||
CV_ELEM_SIZE(_type), (int)sizeof(size_t));
|
CV_ELEM_SIZE(_type), (int)sizeof(size_t));
|
||||||
|
|
||||||
@ -4816,7 +4816,8 @@ void SparseMat::copyTo( SparseMat& m ) const
|
|||||||
void SparseMat::copyTo( Mat& m ) const
|
void SparseMat::copyTo( Mat& m ) const
|
||||||
{
|
{
|
||||||
CV_Assert( hdr );
|
CV_Assert( hdr );
|
||||||
m.create( dims(), hdr->size, type() );
|
int ndims = dims();
|
||||||
|
m.create( ndims, hdr->size, type() );
|
||||||
m = Scalar(0);
|
m = Scalar(0);
|
||||||
|
|
||||||
SparseMatConstIterator from = begin();
|
SparseMatConstIterator from = begin();
|
||||||
@ -4825,7 +4826,7 @@ void SparseMat::copyTo( Mat& m ) const
|
|||||||
for( i = 0; i < N; i++, ++from )
|
for( i = 0; i < N; i++, ++from )
|
||||||
{
|
{
|
||||||
const Node* n = from.node();
|
const Node* n = from.node();
|
||||||
copyElem( from.ptr, m.ptr(n->idx), esz);
|
copyElem( from.ptr, (ndims > 1 ? m.ptr(n->idx) : m.ptr(n->idx[0])), esz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5114,7 +5115,8 @@ uchar* SparseMat::newNode(const int* idx, size_t hashval)
|
|||||||
if( !hdr->freeList )
|
if( !hdr->freeList )
|
||||||
{
|
{
|
||||||
size_t i, nsz = hdr->nodeSize, psize = hdr->pool.size(),
|
size_t i, nsz = hdr->nodeSize, psize = hdr->pool.size(),
|
||||||
newpsize = std::max(psize*2, 8*nsz);
|
newpsize = std::max(psize*3/2, 8*nsz);
|
||||||
|
newpsize = (newpsize/nsz)*nsz;
|
||||||
hdr->pool.resize(newpsize);
|
hdr->pool.resize(newpsize);
|
||||||
uchar* pool = &hdr->pool[0];
|
uchar* pool = &hdr->pool[0];
|
||||||
hdr->freeList = std::max(psize, nsz);
|
hdr->freeList = std::max(psize, nsz);
|
||||||
|
@ -504,54 +504,21 @@ static int countNonZero_(const T* src, int len )
|
|||||||
return nz;
|
return nz;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CV_SSE2
|
|
||||||
|
|
||||||
static const uchar * initPopcountTable()
|
|
||||||
{
|
|
||||||
static uchar tab[256];
|
|
||||||
static volatile bool initialized = false;
|
|
||||||
if( !initialized )
|
|
||||||
{
|
|
||||||
// we compute inverse popcount table,
|
|
||||||
// since we pass (img[x] == 0) mask as index in the table.
|
|
||||||
unsigned int j = 0u;
|
|
||||||
#if CV_POPCNT
|
|
||||||
if (checkHardwareSupport(CV_CPU_POPCNT))
|
|
||||||
{
|
|
||||||
for( ; j < 256u; j++ )
|
|
||||||
tab[j] = (uchar)(8 - _mm_popcnt_u32(j));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for( ; j < 256u; j++ )
|
|
||||||
{
|
|
||||||
int val = 0;
|
|
||||||
for( int mask = 1; mask < 256; mask += mask )
|
|
||||||
val += (j & mask) == 0;
|
|
||||||
tab[j] = (uchar)val;
|
|
||||||
}
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tab;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int countNonZero8u( const uchar* src, int len )
|
static int countNonZero8u( const uchar* src, int len )
|
||||||
{
|
{
|
||||||
int i=0, nz = 0;
|
int i=0, nz = 0;
|
||||||
#if CV_SSE2
|
#if CV_SSE2
|
||||||
if(USE_SSE2)//5x-6x
|
if(USE_SSE2)//5x-6x
|
||||||
{
|
{
|
||||||
__m128i pattern = _mm_setzero_si128 ();
|
__m128i v_zero = _mm_setzero_si128();
|
||||||
static const uchar * tab = initPopcountTable();
|
__m128i sum = _mm_setzero_si128();
|
||||||
|
|
||||||
for (; i<=len-16; i+=16)
|
for (; i<=len-16; i+=16)
|
||||||
{
|
{
|
||||||
__m128i r0 = _mm_loadu_si128((const __m128i*)(src+i));
|
__m128i r0 = _mm_loadu_si128((const __m128i*)(src+i));
|
||||||
int val = _mm_movemask_epi8(_mm_cmpeq_epi8(r0, pattern));
|
sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_cmpeq_epi8(r0, v_zero)), v_zero));
|
||||||
nz += tab[val & 255] + tab[val >> 8];
|
|
||||||
}
|
}
|
||||||
|
nz = i - _mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum)));
|
||||||
}
|
}
|
||||||
#elif CV_NEON
|
#elif CV_NEON
|
||||||
int len0 = len & -16, blockSize1 = (1 << 8) - 16, blockSize0 = blockSize1 << 6;
|
int len0 = len & -16, blockSize1 = (1 << 8) - 16, blockSize0 = blockSize1 << 6;
|
||||||
@ -598,15 +565,15 @@ static int countNonZero16u( const ushort* src, int len )
|
|||||||
if (USE_SSE2)
|
if (USE_SSE2)
|
||||||
{
|
{
|
||||||
__m128i v_zero = _mm_setzero_si128 ();
|
__m128i v_zero = _mm_setzero_si128 ();
|
||||||
static const uchar * tab = initPopcountTable();
|
__m128i sum = _mm_setzero_si128();
|
||||||
|
|
||||||
for ( ; i <= len - 8; i += 8)
|
for ( ; i <= len - 8; i += 8)
|
||||||
{
|
{
|
||||||
__m128i v_src = _mm_loadu_si128((const __m128i*)(src + i));
|
__m128i r0 = _mm_loadu_si128((const __m128i*)(src + i));
|
||||||
int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_cmpeq_epi16(v_src, v_zero), v_zero));
|
sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_cmpeq_epi16(r0, v_zero)), v_zero));
|
||||||
nz += tab[val];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nz = i - (_mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))) >> 1);
|
||||||
src += i;
|
src += i;
|
||||||
}
|
}
|
||||||
#elif CV_NEON
|
#elif CV_NEON
|
||||||
@ -649,20 +616,15 @@ static int countNonZero32s( const int* src, int len )
|
|||||||
if (USE_SSE2)
|
if (USE_SSE2)
|
||||||
{
|
{
|
||||||
__m128i v_zero = _mm_setzero_si128 ();
|
__m128i v_zero = _mm_setzero_si128 ();
|
||||||
static const uchar * tab = initPopcountTable();
|
__m128i sum = _mm_setzero_si128();
|
||||||
|
|
||||||
for ( ; i <= len - 8; i += 8)
|
for ( ; i <= len - 4; i += 4)
|
||||||
{
|
{
|
||||||
__m128i v_src = _mm_loadu_si128((const __m128i*)(src + i));
|
__m128i r0 = _mm_loadu_si128((const __m128i*)(src + i));
|
||||||
__m128i v_dst0 = _mm_cmpeq_epi32(v_src, v_zero);
|
sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_cmpeq_epi32(r0, v_zero)), v_zero));
|
||||||
|
|
||||||
v_src = _mm_loadu_si128((const __m128i*)(src + i + 4));
|
|
||||||
__m128i v_dst1 = _mm_cmpeq_epi32(v_src, v_zero);
|
|
||||||
|
|
||||||
int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_packs_epi32(v_dst0, v_dst1), v_zero));
|
|
||||||
nz += tab[val];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nz = i - (_mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))) >> 2);
|
||||||
src += i;
|
src += i;
|
||||||
}
|
}
|
||||||
#elif CV_NEON
|
#elif CV_NEON
|
||||||
@ -706,19 +668,17 @@ static int countNonZero32f( const float* src, int len )
|
|||||||
#if CV_SSE2
|
#if CV_SSE2
|
||||||
if (USE_SSE2)
|
if (USE_SSE2)
|
||||||
{
|
{
|
||||||
__m128i v_zero_i = _mm_setzero_si128();
|
|
||||||
__m128 v_zero_f = _mm_setzero_ps();
|
__m128 v_zero_f = _mm_setzero_ps();
|
||||||
static const uchar * tab = initPopcountTable();
|
__m128i v_zero = _mm_setzero_si128 ();
|
||||||
|
__m128i sum = _mm_setzero_si128();
|
||||||
|
|
||||||
for ( ; i <= len - 8; i += 8)
|
for ( ; i <= len - 4; i += 4)
|
||||||
{
|
{
|
||||||
__m128i v_dst0 = _mm_castps_si128(_mm_cmpeq_ps(_mm_loadu_ps(src + i), v_zero_f));
|
__m128 r0 = _mm_loadu_ps(src + i);
|
||||||
__m128i v_dst1 = _mm_castps_si128(_mm_cmpeq_ps(_mm_loadu_ps(src + i + 4), v_zero_f));
|
sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_castps_si128(_mm_cmpeq_ps(r0, v_zero_f))), v_zero));
|
||||||
|
|
||||||
int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_packs_epi32(v_dst0, v_dst1), v_zero_i));
|
|
||||||
nz += tab[val];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nz = i - (_mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))) >> 2);
|
||||||
src += i;
|
src += i;
|
||||||
}
|
}
|
||||||
#elif CV_NEON
|
#elif CV_NEON
|
||||||
@ -758,32 +718,7 @@ static int countNonZero32f( const float* src, int len )
|
|||||||
|
|
||||||
static int countNonZero64f( const double* src, int len )
|
static int countNonZero64f( const double* src, int len )
|
||||||
{
|
{
|
||||||
int i = 0, nz = 0;
|
return countNonZero_(src, len);
|
||||||
#if CV_SSE2
|
|
||||||
if (USE_SSE2)
|
|
||||||
{
|
|
||||||
__m128i v_zero_i = _mm_setzero_si128();
|
|
||||||
__m128d v_zero_d = _mm_setzero_pd();
|
|
||||||
static const uchar * tab = initPopcountTable();
|
|
||||||
|
|
||||||
for ( ; i <= len - 8; i += 8)
|
|
||||||
{
|
|
||||||
__m128i v_dst0 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i), v_zero_d));
|
|
||||||
__m128i v_dst1 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i + 2), v_zero_d));
|
|
||||||
__m128i v_dst2 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i + 4), v_zero_d));
|
|
||||||
__m128i v_dst3 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i + 6), v_zero_d));
|
|
||||||
|
|
||||||
v_dst0 = _mm_packs_epi32(v_dst0, v_dst1);
|
|
||||||
v_dst1 = _mm_packs_epi32(v_dst2, v_dst3);
|
|
||||||
|
|
||||||
int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_packs_epi32(v_dst0, v_dst1), v_zero_i));
|
|
||||||
nz += tab[val];
|
|
||||||
}
|
|
||||||
|
|
||||||
src += i;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return nz + countNonZero_(src, len - i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*CountNonZeroFunc)(const uchar*, int);
|
typedef int (*CountNonZeroFunc)(const uchar*, int);
|
||||||
|
@ -1248,3 +1248,27 @@ TEST(Core_SVD, orthogonality)
|
|||||||
ASSERT_LT(norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5);
|
ASSERT_LT(norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(Core_SparseMat, footprint)
|
||||||
|
{
|
||||||
|
int n = 1000000;
|
||||||
|
int sz[] = { n, n };
|
||||||
|
SparseMat m(2, sz, CV_64F);
|
||||||
|
|
||||||
|
int nodeSize0 = (int)m.hdr->nodeSize;
|
||||||
|
double dataSize0 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
|
||||||
|
printf("before: node size=%d bytes, data size=%.0f Mbytes\n", nodeSize0, dataSize0);
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
m.ref<double>(i, i) = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dataSize1 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6;
|
||||||
|
double threshold = (n*nodeSize0*1.6 + n*2.*sizeof(size_t))*1e-6;
|
||||||
|
printf("after: data size=%.0f Mbytes, threshold=%.0f MBytes\n", dataSize1, threshold);
|
||||||
|
|
||||||
|
ASSERT_LE((int)m.hdr->nodeSize, 32);
|
||||||
|
ASSERT_LE(dataSize1, threshold);
|
||||||
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace cv { namespace hal {
|
|||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
|
|
||||||
template<typename _Tp> static inline int
|
template<typename _Tp> static inline int
|
||||||
LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n)
|
LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n, _Tp eps)
|
||||||
{
|
{
|
||||||
int i, j, k, p = 1;
|
int i, j, k, p = 1;
|
||||||
astep /= sizeof(A[0]);
|
astep /= sizeof(A[0]);
|
||||||
@ -63,7 +63,7 @@ LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n)
|
|||||||
if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) )
|
if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) )
|
||||||
k = j;
|
k = j;
|
||||||
|
|
||||||
if( std::abs(A[k*astep + i]) < std::numeric_limits<_Tp>::epsilon() )
|
if( std::abs(A[k*astep + i]) < eps )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( k != i )
|
if( k != i )
|
||||||
@ -111,13 +111,13 @@ LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n)
|
|||||||
|
|
||||||
int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n)
|
int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n)
|
||||||
{
|
{
|
||||||
return LUImpl(A, astep, m, b, bstep, n);
|
return LUImpl(A, astep, m, b, bstep, n, FLT_EPSILON*10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n)
|
int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n)
|
||||||
{
|
{
|
||||||
return LUImpl(A, astep, m, b, bstep, n);
|
return LUImpl(A, astep, m, b, bstep, n, DBL_EPSILON*100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3455,7 +3455,7 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
bool symmetrical = (this->symmetryType & KERNEL_SYMMETRICAL) != 0;
|
bool symmetrical = (this->symmetryType & KERNEL_SYMMETRICAL) != 0;
|
||||||
bool is_1_2_1 = ky[0] == 2 && ky[1] == 1;
|
bool is_1_2_1 = ky[0] == 2 && ky[1] == 1;
|
||||||
bool is_1_m2_1 = ky[0] == -2 && ky[1] == 1;
|
bool is_1_m2_1 = ky[0] == -2 && ky[1] == 1;
|
||||||
bool is_m1_0_1 = ky[1] == 1 || ky[1] == -1;
|
bool is_m1_0_1 = ky[0] == 0 && (ky[1] == 1 || ky[1] == -1);
|
||||||
ST f0 = ky[0], f1 = ky[1];
|
ST f0 = ky[0], f1 = ky[1];
|
||||||
ST _delta = this->delta;
|
ST _delta = this->delta;
|
||||||
CastOp castOp = this->castOp0;
|
CastOp castOp = this->castOp0;
|
||||||
@ -3486,13 +3486,12 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
D[i+2] = castOp(s0);
|
D[i+2] = castOp(s0);
|
||||||
D[i+3] = castOp(s1);
|
D[i+3] = castOp(s1);
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
for( ; i < width; i ++ )
|
for( ; i < width; i ++ )
|
||||||
{
|
{
|
||||||
ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta;
|
ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta;
|
||||||
D[i] = castOp(s0);
|
D[i] = castOp(s0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if( is_1_m2_1 )
|
else if( is_1_m2_1 )
|
||||||
{
|
{
|
||||||
@ -3509,17 +3508,16 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
D[i+2] = castOp(s0);
|
D[i+2] = castOp(s0);
|
||||||
D[i+3] = castOp(s1);
|
D[i+3] = castOp(s1);
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
for( ; i < width; i ++ )
|
for( ; i < width; i ++ )
|
||||||
{
|
{
|
||||||
ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta;
|
ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta;
|
||||||
D[i] = castOp(s0);
|
D[i] = castOp(s0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if CV_ENABLE_UNROLLED
|
#if CV_ENABLE_UNROLLED
|
||||||
for( ; i <= width - 4; i += 4 )
|
for( ; i <= width - 4; i += 4 )
|
||||||
{
|
{
|
||||||
ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta;
|
ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta;
|
||||||
@ -3532,16 +3530,13 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
D[i+2] = castOp(s0);
|
D[i+2] = castOp(s0);
|
||||||
D[i+3] = castOp(s1);
|
D[i+3] = castOp(s1);
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
for( ; i < width; i ++ )
|
for( ; i < width; i ++ )
|
||||||
{
|
{
|
||||||
ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta;
|
ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta;
|
||||||
D[i] = castOp(s0);
|
D[i] = castOp(s0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
for( ; i < width; i++ )
|
|
||||||
D[i] = castOp((S0[i] + S2[i])*f1 + S1[i]*f0 + _delta);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3549,7 +3544,7 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
{
|
{
|
||||||
if( f1 < 0 )
|
if( f1 < 0 )
|
||||||
std::swap(S0, S2);
|
std::swap(S0, S2);
|
||||||
#if CV_ENABLE_UNROLLED
|
#if CV_ENABLE_UNROLLED
|
||||||
for( ; i <= width - 4; i += 4 )
|
for( ; i <= width - 4; i += 4 )
|
||||||
{
|
{
|
||||||
ST s0 = S2[i] - S0[i] + _delta;
|
ST s0 = S2[i] - S0[i] + _delta;
|
||||||
@ -3562,19 +3557,18 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
D[i+2] = castOp(s0);
|
D[i+2] = castOp(s0);
|
||||||
D[i+3] = castOp(s1);
|
D[i+3] = castOp(s1);
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
for( ; i < width; i ++ )
|
for( ; i < width; i ++ )
|
||||||
{
|
{
|
||||||
ST s0 = S2[i] - S0[i] + _delta;
|
ST s0 = S2[i] - S0[i] + _delta;
|
||||||
D[i] = castOp(s0);
|
D[i] = castOp(s0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if( f1 < 0 )
|
if( f1 < 0 )
|
||||||
std::swap(S0, S2);
|
std::swap(S0, S2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if CV_ENABLE_UNROLLED
|
#if CV_ENABLE_UNROLLED
|
||||||
for( ; i <= width - 4; i += 4 )
|
for( ; i <= width - 4; i += 4 )
|
||||||
{
|
{
|
||||||
ST s0 = (S2[i] - S0[i])*f1 + _delta;
|
ST s0 = (S2[i] - S0[i])*f1 + _delta;
|
||||||
@ -3588,10 +3582,9 @@ struct SymmColumnSmallFilter : public SymmColumnFilter<CastOp, VecOp>
|
|||||||
D[i+3] = castOp(s1);
|
D[i+3] = castOp(s1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
for( ; i < width; i++ )
|
||||||
|
D[i] = castOp((S2[i] - S0[i])*f1 + _delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
for( ; i < width; i++ )
|
|
||||||
D[i] = castOp((S2[i] - S0[i])*f1 + _delta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3805,20 +3805,20 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy,
|
|||||||
typedef typename CastOp::rtype T;
|
typedef typename CastOp::rtype T;
|
||||||
typedef typename CastOp::type1 WT;
|
typedef typename CastOp::type1 WT;
|
||||||
Size ssize = _src.size(), dsize = _dst.size();
|
Size ssize = _src.size(), dsize = _dst.size();
|
||||||
int cn = _src.channels();
|
int k, cn = _src.channels();
|
||||||
const AT* wtab = (const AT*)_wtab;
|
const AT* wtab = (const AT*)_wtab;
|
||||||
const T* S0 = _src.ptr<T>();
|
const T* S0 = _src.ptr<T>();
|
||||||
size_t sstep = _src.step/sizeof(S0[0]);
|
size_t sstep = _src.step/sizeof(S0[0]);
|
||||||
Scalar_<T> cval(saturate_cast<T>(_borderValue[0]),
|
T cval[CV_CN_MAX];
|
||||||
saturate_cast<T>(_borderValue[1]),
|
|
||||||
saturate_cast<T>(_borderValue[2]),
|
|
||||||
saturate_cast<T>(_borderValue[3]));
|
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
CastOp castOp;
|
CastOp castOp;
|
||||||
VecOp vecOp;
|
VecOp vecOp;
|
||||||
|
|
||||||
|
for( k = 0; k < cn; k++ )
|
||||||
|
cval[k] = saturate_cast<T>(_borderValue[k & 3]);
|
||||||
|
|
||||||
unsigned width1 = std::max(ssize.width-1, 0), height1 = std::max(ssize.height-1, 0);
|
unsigned width1 = std::max(ssize.width-1, 0), height1 = std::max(ssize.height-1, 0);
|
||||||
CV_Assert( cn <= 4 && ssize.area() > 0 );
|
CV_Assert( ssize.area() > 0 );
|
||||||
#if CV_SSE2
|
#if CV_SSE2
|
||||||
if( _src.type() == CV_8UC3 )
|
if( _src.type() == CV_8UC3 )
|
||||||
width1 = std::max(ssize.width-2, 0);
|
width1 = std::max(ssize.width-2, 0);
|
||||||
@ -3882,7 +3882,7 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy,
|
|||||||
WT t2 = S[2]*w[0] + S[5]*w[1] + S[sstep+2]*w[2] + S[sstep+5]*w[3];
|
WT t2 = S[2]*w[0] + S[5]*w[1] + S[sstep+2]*w[2] + S[sstep+5]*w[3];
|
||||||
D[0] = castOp(t0); D[1] = castOp(t1); D[2] = castOp(t2);
|
D[0] = castOp(t0); D[1] = castOp(t1); D[2] = castOp(t2);
|
||||||
}
|
}
|
||||||
else
|
else if( cn == 4 )
|
||||||
for( ; dx < X1; dx++, D += 4 )
|
for( ; dx < X1; dx++, D += 4 )
|
||||||
{
|
{
|
||||||
int sx = XY[dx*2], sy = XY[dx*2+1];
|
int sx = XY[dx*2], sy = XY[dx*2+1];
|
||||||
@ -3895,6 +3895,18 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy,
|
|||||||
t1 = S[3]*w[0] + S[7]*w[1] + S[sstep+3]*w[2] + S[sstep+7]*w[3];
|
t1 = S[3]*w[0] + S[7]*w[1] + S[sstep+3]*w[2] + S[sstep+7]*w[3];
|
||||||
D[2] = castOp(t0); D[3] = castOp(t1);
|
D[2] = castOp(t0); D[3] = castOp(t1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
for( ; dx < X1; dx++, D += cn )
|
||||||
|
{
|
||||||
|
int sx = XY[dx*2], sy = XY[dx*2+1];
|
||||||
|
const AT* w = wtab + FXY[dx]*4;
|
||||||
|
const T* S = S0 + sy*sstep + sx*cn;
|
||||||
|
for( k = 0; k < cn; k++ )
|
||||||
|
{
|
||||||
|
WT t0 = S[k]*w[0] + S[k+cn]*w[1] + S[sstep+k]*w[2] + S[sstep+k+cn]*w[3];
|
||||||
|
D[k] = castOp(t0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3948,7 +3960,7 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy,
|
|||||||
else
|
else
|
||||||
for( ; dx < X1; dx++, D += cn )
|
for( ; dx < X1; dx++, D += cn )
|
||||||
{
|
{
|
||||||
int sx = XY[dx*2], sy = XY[dx*2+1], k;
|
int sx = XY[dx*2], sy = XY[dx*2+1];
|
||||||
if( borderType == BORDER_CONSTANT &&
|
if( borderType == BORDER_CONSTANT &&
|
||||||
(sx >= ssize.width || sx+1 < 0 ||
|
(sx >= ssize.width || sx+1 < 0 ||
|
||||||
sy >= ssize.height || sy+1 < 0) )
|
sy >= ssize.height || sy+1 < 0) )
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include "test_precomp.hpp"
|
#include "test_precomp.hpp"
|
||||||
|
#include "opencv2/highgui.hpp"
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -429,4 +430,64 @@ TEST(Core_Drawing, polylines)
|
|||||||
int cnt = countNonZero(img);
|
int cnt = countNonZero(img);
|
||||||
ASSERT_EQ(cnt, 21);
|
ASSERT_EQ(cnt, 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//rotate/flip a quadrant appropriately
|
||||||
|
static void rot(int n, int *x, int *y, int rx, int ry)
|
||||||
|
{
|
||||||
|
if (ry == 0) {
|
||||||
|
if (rx == 1) {
|
||||||
|
*x = n-1 - *x;
|
||||||
|
*y = n-1 - *y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Swap x and y
|
||||||
|
int t = *x;
|
||||||
|
*x = *y;
|
||||||
|
*y = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d2xy(int n, int d, int *x, int *y)
|
||||||
|
{
|
||||||
|
int rx, ry, s, t=d;
|
||||||
|
*x = *y = 0;
|
||||||
|
for (s=1; s<n; s*=2)
|
||||||
|
{
|
||||||
|
rx = 1 & (t/2);
|
||||||
|
ry = 1 & (t ^ rx);
|
||||||
|
rot(s, x, y, rx, ry);
|
||||||
|
*x += s * rx;
|
||||||
|
*y += s * ry;
|
||||||
|
t /= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Imgproc_FindContours, hilbert)
|
||||||
|
{
|
||||||
|
int n = 64, n2 = n*n, scale = 10, w = (n + 2)*scale;
|
||||||
|
Point ofs(scale, scale);
|
||||||
|
Mat img(w, w, CV_8U);
|
||||||
|
img.setTo(Scalar::all(0));
|
||||||
|
|
||||||
|
Point p(0,0);
|
||||||
|
for( int i = 0; i < n2; i++ )
|
||||||
|
{
|
||||||
|
Point q(0,0);
|
||||||
|
d2xy(n2, i, &q.x, &q.y);
|
||||||
|
line(img, p*scale + ofs, q*scale + ofs, Scalar::all(255));
|
||||||
|
p = q;
|
||||||
|
}
|
||||||
|
dilate(img, img, Mat());
|
||||||
|
vector<vector<Point> > contours;
|
||||||
|
findContours(img, contours, noArray(), RETR_LIST, CHAIN_APPROX_SIMPLE);
|
||||||
|
printf("ncontours = %d, contour[0].npoints=%d\n", (int)contours.size(), (int)contours[0].size());
|
||||||
|
img.setTo(Scalar::all(0));
|
||||||
|
|
||||||
|
drawContours(img, contours, 0, Scalar::all(255), 1);
|
||||||
|
//imshow("hilbert", img);
|
||||||
|
//waitKey();
|
||||||
|
ASSERT_EQ(1, (int)contours.size());
|
||||||
|
ASSERT_EQ(9832, (int)contours[0].size());
|
||||||
|
}
|
||||||
|
|
||||||
/* End of file. */
|
/* End of file. */
|
||||||
|
@ -1918,3 +1918,37 @@ TEST(Imgproc_Blur, borderTypes)
|
|||||||
EXPECT_EQ(expected_dst.size(), dst.size());
|
EXPECT_EQ(expected_dst.size(), dst.size());
|
||||||
EXPECT_DOUBLE_EQ(0.0, cvtest::norm(expected_dst, dst, NORM_INF));
|
EXPECT_DOUBLE_EQ(0.0, cvtest::norm(expected_dst, dst, NORM_INF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Imgproc_Morphology, iterated)
|
||||||
|
{
|
||||||
|
RNG& rng = theRNG();
|
||||||
|
for( int iter = 0; iter < 30; iter++ )
|
||||||
|
{
|
||||||
|
int width = rng.uniform(5, 33);
|
||||||
|
int height = rng.uniform(5, 33);
|
||||||
|
int cn = rng.uniform(1, 5);
|
||||||
|
int iterations = rng.uniform(1, 11);
|
||||||
|
int op = rng.uniform(0, 2);
|
||||||
|
Mat src(height, width, CV_8UC(cn)), dst0, dst1, dst2;
|
||||||
|
|
||||||
|
randu(src, 0, 256);
|
||||||
|
if( op == 0 )
|
||||||
|
dilate(src, dst0, Mat(), Point(-1,-1), iterations);
|
||||||
|
else
|
||||||
|
erode(src, dst0, Mat(), Point(-1,-1), iterations);
|
||||||
|
|
||||||
|
for( int i = 0; i < iterations; i++ )
|
||||||
|
if( op == 0 )
|
||||||
|
dilate(i == 0 ? src : dst1, dst1, Mat(), Point(-1,-1), 1);
|
||||||
|
else
|
||||||
|
erode(i == 0 ? src : dst1, dst1, Mat(), Point(-1,-1), 1);
|
||||||
|
|
||||||
|
Mat kern = getStructuringElement(MORPH_RECT, Size(3,3));
|
||||||
|
if( op == 0 )
|
||||||
|
dilate(src, dst2, kern, Point(-1,-1), iterations);
|
||||||
|
else
|
||||||
|
erode(src, dst2, kern, Point(-1,-1), iterations);
|
||||||
|
ASSERT_EQ(0.0, norm(dst0, dst1, NORM_INF));
|
||||||
|
ASSERT_EQ(0.0, norm(dst0, dst2, NORM_INF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1632,4 +1632,64 @@ TEST(Resize, Area_half)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Imgproc_Warp, multichannel)
|
||||||
|
{
|
||||||
|
RNG& rng = theRNG();
|
||||||
|
for( int iter = 0; iter < 30; iter++ )
|
||||||
|
{
|
||||||
|
int width = rng.uniform(3, 333);
|
||||||
|
int height = rng.uniform(3, 333);
|
||||||
|
int cn = rng.uniform(1, 10);
|
||||||
|
Mat src(height, width, CV_8UC(cn)), dst;
|
||||||
|
//randu(src, 0, 256);
|
||||||
|
src.setTo(0.);
|
||||||
|
|
||||||
|
Mat rot = getRotationMatrix2D(Point2f(0.f, 0.f), 1, 1);
|
||||||
|
warpAffine(src, dst, rot, src.size());
|
||||||
|
ASSERT_EQ(0.0, norm(dst, NORM_INF));
|
||||||
|
Mat rot2 = Mat::eye(3, 3, rot.type());
|
||||||
|
rot.copyTo(rot2.rowRange(0, 2));
|
||||||
|
warpPerspective(src, dst, rot2, src.size());
|
||||||
|
ASSERT_EQ(0.0, norm(dst, NORM_INF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Imgproc_GetAffineTransform, singularity)
|
||||||
|
{
|
||||||
|
Point2f A_sample[3];
|
||||||
|
A_sample[0] = Point2f(8.f, 9.f);
|
||||||
|
A_sample[1] = Point2f(40.f, 41.f);
|
||||||
|
A_sample[2] = Point2f(47.f, 48.f);
|
||||||
|
Point2f B_sample[3];
|
||||||
|
B_sample[0] = Point2f(7.37465f, 11.8295f);
|
||||||
|
B_sample[1] = Point2f(15.0113f, 12.8994f);
|
||||||
|
B_sample[2] = Point2f(38.9943f, 9.56297f);
|
||||||
|
Mat trans = getAffineTransform(A_sample, B_sample);
|
||||||
|
ASSERT_EQ(0.0, norm(trans, NORM_INF));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Imgproc_Remap, DISABLED_memleak)
|
||||||
|
{
|
||||||
|
Mat src;
|
||||||
|
const int N = 400;
|
||||||
|
src.create(N, N, CV_8U);
|
||||||
|
randu(src, 0, 256);
|
||||||
|
Mat map_x, map_y, dst;
|
||||||
|
dst.create( src.size(), src.type() );
|
||||||
|
map_x.create( src.size(), CV_32FC1 );
|
||||||
|
map_y.create( src.size(), CV_32FC1 );
|
||||||
|
randu(map_x, 0., N+0.);
|
||||||
|
randu(map_y, 0., N+0.);
|
||||||
|
|
||||||
|
for( int iter = 0; iter < 10000; iter++ )
|
||||||
|
{
|
||||||
|
if(iter % 100 == 0)
|
||||||
|
{
|
||||||
|
putchar('.');
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
remap(src, dst, map_x, map_y, CV_INTER_LINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* End of file. */
|
/* End of file. */
|
||||||
|
@ -90,7 +90,9 @@ public:
|
|||||||
|
|
||||||
for(int i = 0, x = step_x / 2; i < x_points; i++, x += step_x) {
|
for(int i = 0, x = step_x / 2; i < x_points; i++, x += step_x) {
|
||||||
for(int j = 0, y = step_y / 2; j < y_points; j++, y += step_y) {
|
for(int j = 0, y = step_y / 2; j < y_points; j++, y += step_y) {
|
||||||
sample_points.push_back(Point(x, y));
|
if( 0 <= x && x < images[0].cols &&
|
||||||
|
0 <= y && y < images[0].rows )
|
||||||
|
sample_points.push_back(Point(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,42 +50,50 @@ static void fastNlMeansDenoising_( const Mat& src, Mat& dst, const std::vector<f
|
|||||||
int templateWindowSize, int searchWindowSize)
|
int templateWindowSize, int searchWindowSize)
|
||||||
{
|
{
|
||||||
int hn = (int)h.size();
|
int hn = (int)h.size();
|
||||||
|
double granularity = (double)std::max(1., (double)dst.total()/(1 << 17));
|
||||||
|
|
||||||
switch (CV_MAT_CN(src.type())) {
|
switch (CV_MAT_CN(src.type())) {
|
||||||
case 1:
|
case 1:
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<ST, IT, UIT, D, int>(
|
FastNlMeansDenoisingInvoker<ST, IT, UIT, D, int>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (hn == 1)
|
if (hn == 1)
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, int>(
|
FastNlMeansDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, int>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
else
|
else
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, Vec2i>(
|
FastNlMeansDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, Vec2i>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (hn == 1)
|
if (hn == 1)
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, int>(
|
FastNlMeansDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, int>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
else
|
else
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, Vec3i>(
|
FastNlMeansDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, Vec3i>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (hn == 1)
|
if (hn == 1)
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, int>(
|
FastNlMeansDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, int>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
else
|
else
|
||||||
parallel_for_(cv::Range(0, src.rows),
|
parallel_for_(cv::Range(0, src.rows),
|
||||||
FastNlMeansDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, Vec4i>(
|
FastNlMeansDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, Vec4i>(
|
||||||
src, dst, templateWindowSize, searchWindowSize, &h[0]));
|
src, dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CV_Error(Error::StsBadArg,
|
CV_Error(Error::StsBadArg,
|
||||||
@ -237,6 +245,7 @@ static void fastNlMeansDenoisingMulti_( const std::vector<Mat>& srcImgs, Mat& ds
|
|||||||
int templateWindowSize, int searchWindowSize)
|
int templateWindowSize, int searchWindowSize)
|
||||||
{
|
{
|
||||||
int hn = (int)h.size();
|
int hn = (int)h.size();
|
||||||
|
double granularity = (double)std::max(1., (double)dst.total()/(1 << 16));
|
||||||
|
|
||||||
switch (srcImgs[0].type())
|
switch (srcImgs[0].type())
|
||||||
{
|
{
|
||||||
@ -244,43 +253,50 @@ static void fastNlMeansDenoisingMulti_( const std::vector<Mat>& srcImgs, Mat& ds
|
|||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<uchar, IT, UIT, D, int>(
|
FastNlMeansMultiDenoisingInvoker<uchar, IT, UIT, D, int>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
case CV_8UC2:
|
case CV_8UC2:
|
||||||
if (hn == 1)
|
if (hn == 1)
|
||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, int>(
|
FastNlMeansMultiDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, int>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
else
|
else
|
||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, Vec2i>(
|
FastNlMeansMultiDenoisingInvoker<Vec<ST, 2>, IT, UIT, D, Vec2i>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
case CV_8UC3:
|
case CV_8UC3:
|
||||||
if (hn == 1)
|
if (hn == 1)
|
||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, int>(
|
FastNlMeansMultiDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, int>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
else
|
else
|
||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, Vec3i>(
|
FastNlMeansMultiDenoisingInvoker<Vec<ST, 3>, IT, UIT, D, Vec3i>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
case CV_8UC4:
|
case CV_8UC4:
|
||||||
if (hn == 1)
|
if (hn == 1)
|
||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, int>(
|
FastNlMeansMultiDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, int>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
else
|
else
|
||||||
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
parallel_for_(cv::Range(0, srcImgs[0].rows),
|
||||||
FastNlMeansMultiDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, Vec4i>(
|
FastNlMeansMultiDenoisingInvoker<Vec<ST, 4>, IT, UIT, D, Vec4i>(
|
||||||
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
srcImgs, imgToDenoiseIndex, temporalWindowSize,
|
||||||
dst, templateWindowSize, searchWindowSize, &h[0]));
|
dst, templateWindowSize, searchWindowSize, &h[0]),
|
||||||
|
granularity);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CV_Error(Error::StsBadArg,
|
CV_Error(Error::StsBadArg,
|
||||||
|
@ -47,6 +47,12 @@
|
|||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
|
inline void log_(const Mat& src, Mat& dst)
|
||||||
|
{
|
||||||
|
max(src, Scalar::all(1e-4), dst);
|
||||||
|
log(dst, dst);
|
||||||
|
}
|
||||||
|
|
||||||
class TonemapImpl : public Tonemap
|
class TonemapImpl : public Tonemap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -122,7 +128,7 @@ public:
|
|||||||
Mat gray_img;
|
Mat gray_img;
|
||||||
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
||||||
Mat log_img;
|
Mat log_img;
|
||||||
log(gray_img, log_img);
|
log_(gray_img, log_img);
|
||||||
float mean = expf(static_cast<float>(sum(log_img)[0]) / log_img.total());
|
float mean = expf(static_cast<float>(sum(log_img)[0]) / log_img.total());
|
||||||
gray_img /= mean;
|
gray_img /= mean;
|
||||||
log_img.release();
|
log_img.release();
|
||||||
@ -205,7 +211,7 @@ public:
|
|||||||
Mat gray_img;
|
Mat gray_img;
|
||||||
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
||||||
Mat log_img;
|
Mat log_img;
|
||||||
log(gray_img, log_img);
|
log_(gray_img, log_img);
|
||||||
Mat map_img;
|
Mat map_img;
|
||||||
bilateralFilter(log_img, map_img, -1, sigma_color, sigma_space);
|
bilateralFilter(log_img, map_img, -1, sigma_color, sigma_space);
|
||||||
|
|
||||||
@ -289,7 +295,7 @@ public:
|
|||||||
Mat gray_img;
|
Mat gray_img;
|
||||||
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
||||||
Mat log_img;
|
Mat log_img;
|
||||||
log(gray_img, log_img);
|
log_(gray_img, log_img);
|
||||||
|
|
||||||
float log_mean = static_cast<float>(sum(log_img)[0] / log_img.total());
|
float log_mean = static_cast<float>(sum(log_img)[0] / log_img.total());
|
||||||
double log_min, log_max;
|
double log_min, log_max;
|
||||||
@ -383,7 +389,7 @@ public:
|
|||||||
Mat gray_img;
|
Mat gray_img;
|
||||||
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
cvtColor(img, gray_img, COLOR_RGB2GRAY);
|
||||||
Mat log_img;
|
Mat log_img;
|
||||||
log(gray_img, log_img);
|
log_(gray_img, log_img);
|
||||||
|
|
||||||
std::vector<Mat> x_contrast, y_contrast;
|
std::vector<Mat> x_contrast, y_contrast;
|
||||||
getContrast(log_img, x_contrast, y_contrast);
|
getContrast(log_img, x_contrast, y_contrast);
|
||||||
|
@ -156,3 +156,14 @@ TEST(Photo_White, issue_2646)
|
|||||||
|
|
||||||
ASSERT_EQ(0, nonWhitePixelsCount);
|
ASSERT_EQ(0, nonWhitePixelsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Photo_Denoising, speed)
|
||||||
|
{
|
||||||
|
string imgname = string(cvtest::TS::ptr()->get_data_path()) + "shared/5MP.png";
|
||||||
|
Mat src = imread(imgname, 0), dst;
|
||||||
|
|
||||||
|
double t = (double)getTickCount();
|
||||||
|
fastNlMeansDenoising(src, dst, 5, 7, 21);
|
||||||
|
t = (double)getTickCount() - t;
|
||||||
|
printf("execution time: %gms\n", t*1000./getTickFrequency());
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user