📄 cvfilter.cpp
字号:
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
{
f = kx[k];
s0 += f*(s[j] + s[-j]); s1 += f*(s[j+1] + s[-j+1]);
s2 += f*(s[j+2] + s[-j+2]); s3 += f*(s[j+3] + s[-j+3]);
}
dst[i] = s0; dst[i+1] = s1;
dst[i+2] = s2; dst[i+3] = s3;
}
for( ; i < width; i++, s++ )
{
int s0 = kx[0]*s[0];
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
s0 += kx[k]*(s[j] + s[-j]);
dst[i] = s0;
}
}
else
{
if( ksize == 3 && kx[0] == 0 && kx[1] == 1 )
for( ; i <= width - 2; i += 2, s += 2 )
{
int s0 = s[cn] - s[-cn], s1 = s[1+cn] - s[1-cn];
dst[i] = s0; dst[i+1] = s1;
}
else
for( ; i <= width - 4; i += 4, s += 4 )
{
int s0 = 0, s1 = 0, s2 = 0, s3 = 0;
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
{
int f = kx[k];
s0 += f*(s[j] - s[-j]); s1 += f*(s[j+1] - s[-j+1]);
s2 += f*(s[j+2] - s[-j+2]); s3 += f*(s[j+3] - s[-j+3]);
}
dst[i] = s0; dst[i+1] = s1;
dst[i+2] = s2; dst[i+3] = s3;
}
for( ; i < width; i++, s++ )
{
int s0 = kx[0]*s[0];
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
s0 += kx[k]*(s[j] - s[-j]);
dst[i] = s0;
}
}
}
#define ICV_FILTER_ROW( flavor, srctype, dsttype, load_macro ) \
static void \
icvFilterRow_##flavor(const srctype* src, dsttype* dst, void*params)\
{ \
const CvSepFilter* state = (const CvSepFilter*)params; \
const CvMat* _kx = state->get_x_kernel(); \
const dsttype* kx = (const dsttype*)(_kx->data.ptr); \
int ksize = _kx->cols + _kx->rows - 1; \
int i = 0, k, width = state->get_width(); \
int cn = CV_MAT_CN(state->get_src_type()); \
const srctype* s; \
\
width *= cn; \
\
for( ; i <= width - 4; i += 4 ) \
{ \
double f = kx[0]; \
double s0=f*load_macro(src[i]), s1=f*load_macro(src[i+1]), \
s2=f*load_macro(src[i+2]), s3=f*load_macro(src[i+3]);\
for( k = 1, s = src + i + cn; k < ksize; k++, s += cn ) \
{ \
f = kx[k]; \
s0 += f*load_macro(s[0]); \
s1 += f*load_macro(s[1]); \
s2 += f*load_macro(s[2]); \
s3 += f*load_macro(s[3]); \
} \
dst[i] = (dsttype)s0; dst[i+1] = (dsttype)s1; \
dst[i+2] = (dsttype)s2; dst[i+3] = (dsttype)s3; \
} \
\
for( ; i < width; i++ ) \
{ \
double s0 = (double)kx[0]*load_macro(src[i]); \
for( k = 1, s = src + i + cn; k < ksize; k++, s += cn ) \
s0 += (double)kx[k]*load_macro(s[0]); \
dst[i] = (dsttype)s0; \
} \
}
ICV_FILTER_ROW( 8u32f, uchar, float, CV_8TO32F )
ICV_FILTER_ROW( 16s32f, short, float, CV_NOP )
ICV_FILTER_ROW( 16u32f, ushort, float, CV_NOP )
ICV_FILTER_ROW( 32f, float, float, CV_NOP )
#define ICV_FILTER_ROW_SYMM( flavor, srctype, dsttype, load_macro ) \
static void \
icvFilterRowSymm_##flavor( const srctype* src, \
dsttype* dst, void* params ) \
{ \
const CvSepFilter* state = (const CvSepFilter*)params; \
const CvMat* _kx = state->get_x_kernel(); \
const dsttype* kx = (const dsttype*)(_kx->data.ptr); \
int ksize = _kx->cols + _kx->rows - 1; \
int i = 0, j, k, width = state->get_width(); \
int cn = CV_MAT_CN(state->get_src_type()); \
int is_symm=state->get_x_kernel_flags()&CvSepFilter::SYMMETRICAL;\
int ksize2 = ksize/2, ksize2n = ksize2*cn; \
const srctype* s = src + ksize2n; \
\
kx += ksize2; \
width *= cn; \
\
if( is_symm ) \
{ \
for( ; i <= width - 4; i += 4, s += 4 ) \
{ \
double f = kx[0]; \
double s0=f*load_macro(s[0]), s1=f*load_macro(s[1]), \
s2=f*load_macro(s[2]), s3=f*load_macro(s[3]); \
for( k = 1, j = cn; k <= ksize2; k++, j += cn ) \
{ \
f = kx[k]; \
s0 += f*load_macro(s[j] + s[-j]); \
s1 += f*load_macro(s[j+1] + s[-j+1]); \
s2 += f*load_macro(s[j+2] + s[-j+2]); \
s3 += f*load_macro(s[j+3] + s[-j+3]); \
} \
\
dst[i] = (dsttype)s0; dst[i+1] = (dsttype)s1; \
dst[i+2] = (dsttype)s2; dst[i+3] = (dsttype)s3; \
} \
\
for( ; i < width; i++, s++ ) \
{ \
double s0 = (double)kx[0]*load_macro(s[0]); \
for( k = 1, j = cn; k <= ksize2; k++, j += cn ) \
s0 += (double)kx[k]*load_macro(s[j] + s[-j]); \
dst[i] = (dsttype)s0; \
} \
} \
else \
{ \
for( ; i <= width - 4; i += 4, s += 4 ) \
{ \
double s0 = 0, s1 = 0, s2 = 0, s3 = 0; \
for( k = 1, j = cn; k <= ksize2; k++, j += cn ) \
{ \
double f = kx[k]; \
s0 += f*load_macro(s[j] - s[-j]); \
s1 += f*load_macro(s[j+1] - s[-j+1]); \
s2 += f*load_macro(s[j+2] - s[-j+2]); \
s3 += f*load_macro(s[j+3] - s[-j+3]); \
} \
\
dst[i] = (dsttype)s0; dst[i+1] = (dsttype)s1; \
dst[i+2] = (dsttype)s2; dst[i+3] = (dsttype)s3; \
} \
\
for( ; i < width; i++, s++ ) \
{ \
double s0 = 0; \
for( k = 1, j = cn; k <= ksize2; k++, j += cn ) \
s0 += (double)kx[k]*load_macro(s[j] - s[-j]); \
dst[i] = (dsttype)s0; \
} \
} \
}
ICV_FILTER_ROW_SYMM( 8u32f, uchar, float, CV_8TO32F )
ICV_FILTER_ROW_SYMM( 16s32f, short, float, CV_NOP )
ICV_FILTER_ROW_SYMM( 16u32f, ushort, float, CV_NOP )
static void
icvFilterRowSymm_32f( const float* src, float* dst, void* params )
{
const CvSepFilter* state = (const CvSepFilter*)params;
const CvMat* _kx = state->get_x_kernel();
const float* kx = _kx->data.fl;
int ksize = _kx->cols + _kx->rows - 1;
int i = 0, j, k, width = state->get_width();
int cn = CV_MAT_CN(state->get_src_type());
int ksize2 = ksize/2, ksize2n = ksize2*cn;
int is_symm = state->get_x_kernel_flags() & CvSepFilter::SYMMETRICAL;
const float* s = src + ksize2n;
kx += ksize2;
width *= cn;
if( is_symm )
{
if( ksize == 3 && fabs(kx[0]-2.) <= FLT_EPSILON && fabs(kx[1]-1.) <= FLT_EPSILON )
for( ; i <= width - 2; i += 2, s += 2 )
{
float s0 = s[-cn] + s[0]*2 + s[cn], s1 = s[1-cn] + s[1]*2 + s[1+cn];
dst[i] = s0; dst[i+1] = s1;
}
else if( ksize == 3 && fabs(kx[0]-10.) <= FLT_EPSILON && fabs(kx[1]-3.) <= FLT_EPSILON )
for( ; i <= width - 2; i += 2, s += 2 )
{
float s0 = s[0]*10 + (s[-cn] + s[cn])*3, s1 = s[1]*10 + (s[1-cn] + s[1+cn])*3;
dst[i] = s0; dst[i+1] = s1;
}
else
for( ; i <= width - 4; i += 4, s += 4 )
{
double f = kx[0];
double s0 = f*s[0], s1 = f*s[1], s2 = f*s[2], s3 = f*s[3];
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
{
f = kx[k];
s0 += f*(s[j] + s[-j]); s1 += f*(s[j+1] + s[-j+1]);
s2 += f*(s[j+2] + s[-j+2]); s3 += f*(s[j+3] + s[-j+3]);
}
dst[i] = (float)s0; dst[i+1] = (float)s1;
dst[i+2] = (float)s2; dst[i+3] = (float)s3;
}
for( ; i < width; i++, s++ )
{
double s0 = (double)kx[0]*s[0];
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
s0 += (double)kx[k]*(s[j] + s[-j]);
dst[i] = (float)s0;
}
}
else
{
if( ksize == 3 && fabs(kx[0]) <= FLT_EPSILON && fabs(kx[1]-1.) <= FLT_EPSILON )
for( ; i <= width - 2; i += 2, s += 2 )
{
float s0 = s[cn] - s[-cn], s1 = s[1+cn] - s[1-cn];
dst[i] = s0; dst[i+1] = s1;
}
else
for( ; i <= width - 4; i += 4, s += 4 )
{
double s0 = 0, s1 = 0, s2 = 0, s3 = 0;
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
{
double f = kx[k];
s0 += f*(s[j] - s[-j]); s1 += f*(s[j+1] - s[-j+1]);
s2 += f*(s[j+2] - s[-j+2]); s3 += f*(s[j+3] - s[-j+3]);
}
dst[i] = (float)s0; dst[i+1] = (float)s1;
dst[i+2] = (float)s2; dst[i+3] = (float)s3;
}
for( ; i < width; i++, s++ )
{
double s0 = (double)kx[0]*s[0];
for( k = 1, j = cn; k <= ksize2; k++, j += cn )
s0 += (double)kx[k]*(s[j] - s[-j]);
dst[i] = (float)s0;
}
}
}
static void
icvFilterColSymm_32s8u( const int** src, uchar* dst, int dst_step, int count, void* params )
{
const CvSepFilter* state = (const CvSepFilter*)params;
const CvMat* _ky = state->get_y_kernel();
const int* ky = _ky->data.i;
int ksize = _ky->cols + _ky->rows - 1, ksize2 = ksize/2;
int i, k, width = state->get_width();
int cn = CV_MAT_CN(state->get_src_type());
width *= cn;
src += ksize2;
ky += ksize2;
for( ; count--; dst += dst_step, src++ )
{
if( ksize == 3 )
{
const int* sptr0 = src[-1], *sptr1 = src[0], *sptr2 = src[1];
int k0 = ky[0], k1 = ky[1];
for( i = 0; i <= width - 2; i += 2 )
{
int s0 = sptr1[i]*k0 + (sptr0[i] + sptr2[i])*k1;
int s1 = sptr1[i+1]*k0 + (sptr0[i+1] + sptr2[i+1])*k1;
s0 = CV_DESCALE(s0, FILTER_BITS*2);
s1 = CV_DESCALE(s1, FILTER_BITS*2);
dst[i] = (uchar)s0; dst[i+1] = (uchar)s1;
}
}
else if( ksize == 5 )
{
const int* sptr0 = src[-2], *sptr1 = src[-1],
*sptr2 = src[0], *sptr3 = src[1], *sptr4 = src[2];
int k0 = ky[0], k1 = ky[1], k2 = ky[2];
for( i = 0; i <= width - 2; i += 2 )
{
int s0 = sptr2[i]*k0 + (sptr1[i] + sptr3[i])*k1 + (sptr0[i] + sptr4[i])*k2;
int s1 = sptr2[i+1]*k0 + (sptr1[i+1] + sptr3[i+1])*k1 + (sptr0[i+1] + sptr4[i+1])*k2;
s0 = CV_DESCALE(s0, FILTER_BITS*2);
s1 = CV_DESCALE(s1, FILTER_BITS*2);
dst[i] = (uchar)s0; dst[i+1] = (uchar)s1;
}
}
else
for( i = 0; i <= width - 4; i += 4 )
{
int f = ky[0];
const int* sptr = src[0] + i, *sptr2;
int s0 = f*sptr[0], s1 = f*sptr[1], s2 = f*sptr[2], s3 = f*sptr[3];
for( k = 1; k <= ksize2; k++ )
{
sptr = src[k] + i;
sptr2 = src[-k] + i;
f = ky[k];
s0 += f*(sptr[0] + sptr2[0]);
s1 += f*(sptr[1] + sptr2[1]);
s2 += f*(sptr[2] + sptr2[2]);
s3 += f*(sptr[3] + sptr2[3]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -