📄 cvsmooth.cpp
字号:
int s0 = sum[i] + sp[i], s1 = sum[i+1] + sp[i+1];
sum[i] = s0; sum[i+1] = s1;
}
for( ; i < width; i++ )
sum[i] += sp[i];
sum_count++;
}
else
{
const int* sm = src[-ksize+1];
for( i = 0; i <= width - 2; i += 2 )
{
int s0 = sum[i] + sp[i], s1 = sum[i+1] + sp[i+1];
dst[i] = s0; dst[i+1] = s1;
s0 -= sm[i]; s1 -= sm[i+1];
sum[i] = s0; sum[i+1] = s1;
}
for( ; i < width; i++ )
{
int s0 = sum[i] + sp[i];
dst[i] = s0;
sum[i] = s0 - sm[i];
}
dst += dst_step;
}
}
*_sum_count = sum_count;
}
static void
icvSumCol_64f32f( const double** src, float* dst,
int dst_step, int count, void* params )
{
CvBoxFilter* state = (CvBoxFilter*)params;
int ksize = state->get_kernel_size().height;
int i, width = state->get_width();
int cn = CV_MAT_CN(state->get_src_type());
double scale = state->get_scale();
bool normalized = state->is_normalized();
double* sum = (double*)state->get_sum_buf();
int* _sum_count = state->get_sum_count_ptr();
int sum_count = *_sum_count;
dst_step /= sizeof(dst[0]);
width *= cn;
src += sum_count;
count += ksize - 1 - sum_count;
for( ; count--; src++ )
{
const double* sp = src[0];
if( sum_count+1 < ksize )
{
for( i = 0; i <= width - 2; i += 2 )
{
double s0 = sum[i] + sp[i], s1 = sum[i+1] + sp[i+1];
sum[i] = s0; sum[i+1] = s1;
}
for( ; i < width; i++ )
sum[i] += sp[i];
sum_count++;
}
else
{
const double* sm = src[-ksize+1];
if( normalized )
for( i = 0; i <= width - 2; i += 2 )
{
double s0 = sum[i] + sp[i], s1 = sum[i+1] + sp[i+1];
double t0 = s0*scale, t1 = s1*scale;
s0 -= sm[i]; s1 -= sm[i+1];
dst[i] = (float)t0; dst[i+1] = (float)t1;
sum[i] = s0; sum[i+1] = s1;
}
else
for( i = 0; i <= width - 2; i += 2 )
{
double s0 = sum[i] + sp[i], s1 = sum[i+1] + sp[i+1];
dst[i] = (float)s0; dst[i+1] = (float)s1;
s0 -= sm[i]; s1 -= sm[i+1];
sum[i] = s0; sum[i+1] = s1;
}
for( ; i < width; i++ )
{
double s0 = sum[i] + sp[i], t0 = s0*scale;
sum[i] = s0 - sm[i]; dst[i] = (float)t0;
}
dst += dst_step;
}
}
*_sum_count = sum_count;
}
/****************************************************************************************\
Median Filter
\****************************************************************************************/
#define CV_MINMAX_8U(a,b) \
(t = CV_FAST_CAST_8U((a) - (b)), (b) += t, a -= t)
static CvStatus CV_STDCALL
icvMedianBlur_8u_CnR( uchar* src, int src_step, uchar* dst, int dst_step,
CvSize size, int m, int cn )
{
#define N 16
int zone0[4][N];
int zone1[4][N*N];
int x, y;
int n2 = m*m/2;
int nx = (m + 1)/2 - 1;
uchar* src_max = src + size.height*src_step;
uchar* src_right = src + size.width*cn;
#define UPDATE_ACC01( pix, cn, op ) \
{ \
int p = (pix); \
zone1[cn][p] op; \
zone0[cn][p >> 4] op; \
}
if( size.height < nx || size.width < nx )
return CV_BADSIZE_ERR;
if( m == 3 )
{
size.width *= cn;
for( y = 0; y < size.height; y++, dst += dst_step )
{
const uchar* src0 = src + src_step*(y-1);
const uchar* src1 = src0 + src_step;
const uchar* src2 = src1 + src_step;
if( y == 0 )
src0 = src1;
else if( y == size.height - 1 )
src2 = src1;
for( x = 0; x < 2*cn; x++ )
{
int x0 = x < cn ? x : size.width - 3*cn + x;
int x2 = x < cn ? x + cn : size.width - 2*cn + x;
int x1 = x < cn ? x0 : x2, t;
int p0 = src0[x0], p1 = src0[x1], p2 = src0[x2];
int p3 = src1[x0], p4 = src1[x1], p5 = src1[x2];
int p6 = src2[x0], p7 = src2[x1], p8 = src2[x2];
CV_MINMAX_8U(p1, p2); CV_MINMAX_8U(p4, p5);
CV_MINMAX_8U(p7, p8); CV_MINMAX_8U(p0, p1);
CV_MINMAX_8U(p3, p4); CV_MINMAX_8U(p6, p7);
CV_MINMAX_8U(p1, p2); CV_MINMAX_8U(p4, p5);
CV_MINMAX_8U(p7, p8); CV_MINMAX_8U(p0, p3);
CV_MINMAX_8U(p5, p8); CV_MINMAX_8U(p4, p7);
CV_MINMAX_8U(p3, p6); CV_MINMAX_8U(p1, p4);
CV_MINMAX_8U(p2, p5); CV_MINMAX_8U(p4, p7);
CV_MINMAX_8U(p4, p2); CV_MINMAX_8U(p6, p4);
CV_MINMAX_8U(p4, p2);
dst[x1] = (uchar)p4;
}
for( x = cn; x < size.width - cn; x++ )
{
int p0 = src0[x-cn], p1 = src0[x], p2 = src0[x+cn];
int p3 = src1[x-cn], p4 = src1[x], p5 = src1[x+cn];
int p6 = src2[x-cn], p7 = src2[x], p8 = src2[x+cn];
int t;
CV_MINMAX_8U(p1, p2); CV_MINMAX_8U(p4, p5);
CV_MINMAX_8U(p7, p8); CV_MINMAX_8U(p0, p1);
CV_MINMAX_8U(p3, p4); CV_MINMAX_8U(p6, p7);
CV_MINMAX_8U(p1, p2); CV_MINMAX_8U(p4, p5);
CV_MINMAX_8U(p7, p8); CV_MINMAX_8U(p0, p3);
CV_MINMAX_8U(p5, p8); CV_MINMAX_8U(p4, p7);
CV_MINMAX_8U(p3, p6); CV_MINMAX_8U(p1, p4);
CV_MINMAX_8U(p2, p5); CV_MINMAX_8U(p4, p7);
CV_MINMAX_8U(p4, p2); CV_MINMAX_8U(p6, p4);
CV_MINMAX_8U(p4, p2);
dst[x] = (uchar)p4;
}
}
return CV_OK;
}
for( x = 0; x < size.width; x++, dst += cn )
{
uchar* dst_cur = dst;
uchar* src_top = src;
uchar* src_bottom = src;
int k, c;
int x0 = -1;
if( x <= m/2 )
nx++;
if( nx < m )
x0 = x < m/2 ? 0 : (nx-1)*cn;
// init accumulator
memset( zone0, 0, sizeof(zone0[0])*cn );
memset( zone1, 0, sizeof(zone1[0])*cn );
for( y = -m/2; y < m/2; y++ )
{
for( c = 0; c < cn; c++ )
{
if( x0 >= 0 )
UPDATE_ACC01( src_bottom[x0+c], c, += (m - nx) );
for( k = 0; k < nx*cn; k += cn )
UPDATE_ACC01( src_bottom[k+c], c, ++ );
}
if( (unsigned)y < (unsigned)(size.height-1) )
src_bottom += src_step;
}
for( y = 0; y < size.height; y++, dst_cur += dst_step )
{
if( cn == 1 )
{
for( k = 0; k < nx; k++ )
UPDATE_ACC01( src_bottom[k], 0, ++ );
}
else if( cn == 3 )
{
for( k = 0; k < nx*3; k += 3 )
{
UPDATE_ACC01( src_bottom[k], 0, ++ );
UPDATE_ACC01( src_bottom[k+1], 1, ++ );
UPDATE_ACC01( src_bottom[k+2], 2, ++ );
}
}
else
{
assert( cn == 4 );
for( k = 0; k < nx*4; k += 4 )
{
UPDATE_ACC01( src_bottom[k], 0, ++ );
UPDATE_ACC01( src_bottom[k+1], 1, ++ );
UPDATE_ACC01( src_bottom[k+2], 2, ++ );
UPDATE_ACC01( src_bottom[k+3], 3, ++ );
}
}
if( x0 >= 0 )
{
for( c = 0; c < cn; c++ )
UPDATE_ACC01( src_bottom[x0+c], c, += (m - nx) );
}
if( src_bottom + src_step < src_max )
src_bottom += src_step;
// find median
for( c = 0; c < cn; c++ )
{
int s = 0;
for( k = 0; ; k++ )
{
int t = s + zone0[c][k];
if( t > n2 ) break;
s = t;
}
for( k *= N; ;k++ )
{
s += zone1[c][k];
if( s > n2 ) break;
}
dst_cur[c] = (uchar)k;
}
if( cn == 1 )
{
for( k = 0; k < nx; k++ )
UPDATE_ACC01( src_top[k], 0, -- );
}
else if( cn == 3 )
{
for( k = 0; k < nx*3; k += 3 )
{
UPDATE_ACC01( src_top[k], 0, -- );
UPDATE_ACC01( src_top[k+1], 1, -- );
UPDATE_ACC01( src_top[k+2], 2, -- );
}
}
else
{
assert( cn == 4 );
for( k = 0; k < nx*4; k += 4 )
{
UPDATE_ACC01( src_top[k], 0, -- );
UPDATE_ACC01( src_top[k+1], 1, -- );
UPDATE_ACC01( src_top[k+2], 2, -- );
UPDATE_ACC01( src_top[k+3], 3, -- );
}
}
if( x0 >= 0 )
{
for( c = 0; c < cn; c++ )
UPDATE_ACC01( src_top[x0+c], c, -= (m - nx) );
}
if( y >= m/2 )
src_top += src_step;
}
if( x >= m/2 )
src += cn;
if( src + nx*cn > src_right ) nx--;
}
#undef N
#undef UPDATE_ACC
return CV_OK;
}
/****************************************************************************************\
Bilateral Filtering
\****************************************************************************************/
static CvStatus CV_STDCALL
icvBilateralFiltering_8u_CnR( uchar* src, int srcStep,
uchar* dst, int dstStep,
CvSize size, double sigma_color,
double sigma_space, int channels )
{
double i2sigma_color = 1./(sigma_color*sigma_color);
double i2sigma_space = 1./(sigma_space*sigma_space);
double mean1[3];
double mean0;
double w;
int deltas[8];
double weight_tab[8];
int i, j;
#define INIT_C1\
color = src[0]; \
mean0 = 1; mean1[0] = color;
#define COLOR_DISTANCE_C1(c1, c2)\
(c1 - c2)*(c1 - c2)
#define KERNEL_ELEMENT_C1(k)\
temp_color = src[deltas[k]];\
w = weight_tab[k] + COLOR_DISTANCE_C1(color, temp_color)*i2sigma_color;\
w = 1./(w*w + 1); \
mean0 += w;\
mean1[0] += temp_color*w;
#define INIT_C3\
mean0 = 1; mean1[0] = src[0];mean1[1] = src[1];mean1[2] = src[2];
#define UPDATE_OUTPUT_C1 \
dst[i] = (uchar)cvRound(mean1[0]/mean0);
#define COLOR_DISTANCE_C3(c1, c2)\
((c1[0] - c2[0])*(c1[0] - c2[0]) + \
(c1[1] - c2[1])*(c1[1] - c2[1]) + \
(c1[2] - c2[2])*(c1[2] - c2[2]))
#define KERNEL_ELEMENT_C3(k)\
temp_color = src + deltas[k];\
w = weight_tab[k] + COLOR_DISTANCE_C3(src, temp_color)*i2sigma_color;\
w = 1./(w*w + 1); \
mean0 += w;\
mean1[0] += temp_color[0]*w; \
mean1[1] += temp_color[1]*w; \
mean1[2] += temp_color[2]*w;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -