📄 cvsmooth.cpp
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
/****************************************************************************************\
Box Filter
\****************************************************************************************/
static void icvSumRow_8u32s( const uchar* src0, int* dst, void* params );
static void icvSumRow_32f64f( const float* src0, double* dst, void* params );
static void icvSumCol_32s8u( const int** src, uchar* dst, int dst_step,
int count, void* params );
static void icvSumCol_32s16s( const int** src, short* dst, int dst_step,
int count, void* params );
static void icvSumCol_32s32s( const int** src, int* dst, int dst_step,
int count, void* params );
static void icvSumCol_64f32f( const double** src, float* dst, int dst_step,
int count, void* params );
CvBoxFilter::CvBoxFilter()
{
min_depth = CV_32S;
sum = 0;
sum_count = 0;
normalized = false;
}
CvBoxFilter::CvBoxFilter( int _max_width, int _src_type, int _dst_type,
bool _normalized, CvSize _ksize,
CvPoint _anchor, int _border_mode,
CvScalar _border_value )
{
min_depth = CV_32S;
sum = 0;
sum_count = 0;
normalized = false;
init( _max_width, _src_type, _dst_type, _normalized,
_ksize, _anchor, _border_mode, _border_value );
}
CvBoxFilter::~CvBoxFilter()
{
clear();
}
void CvBoxFilter::init( int _max_width, int _src_type, int _dst_type,
bool _normalized, CvSize _ksize,
CvPoint _anchor, int _border_mode,
CvScalar _border_value )
{
CV_FUNCNAME( "CvBoxFilter::init" );
__BEGIN__;
sum = 0;
normalized = _normalized;
if( normalized && CV_MAT_TYPE(_src_type) != CV_MAT_TYPE(_dst_type) ||
!normalized && CV_MAT_CN(_src_type) != CV_MAT_CN(_dst_type))
CV_ERROR( CV_StsUnmatchedFormats,
"In case of normalized box filter input and output must have the same type.\n"
"In case of unnormalized box filter the number of input and output channels must be the same" );
min_depth = CV_MAT_DEPTH(_src_type) == CV_8U ? CV_32S : CV_64F;
CvBaseImageFilter::init( _max_width, _src_type, _dst_type, 1, _ksize,
_anchor, _border_mode, _border_value );
scale = normalized ? 1./(ksize.width*ksize.height) : 1;
if( CV_MAT_DEPTH(src_type) == CV_8U )
x_func = (CvRowFilterFunc)icvSumRow_8u32s;
else if( CV_MAT_DEPTH(src_type) == CV_32F )
x_func = (CvRowFilterFunc)icvSumRow_32f64f;
else
CV_ERROR( CV_StsUnsupportedFormat, "Unknown/unsupported input image format" );
if( CV_MAT_DEPTH(dst_type) == CV_8U )
{
if( !normalized )
CV_ERROR( CV_StsBadArg, "Only normalized box filter can be used for 8u->8u transformation" );
y_func = (CvColumnFilterFunc)icvSumCol_32s8u;
}
else if( CV_MAT_DEPTH(dst_type) == CV_16S )
{
if( normalized || CV_MAT_DEPTH(src_type) != CV_8U )
CV_ERROR( CV_StsBadArg, "Only 8u->16s unnormalized box filter is supported in case of 16s output" );
y_func = (CvColumnFilterFunc)icvSumCol_32s16s;
}
else if( CV_MAT_DEPTH(dst_type) == CV_32S )
{
if( normalized || CV_MAT_DEPTH(src_type) != CV_8U )
CV_ERROR( CV_StsBadArg, "Only 8u->32s unnormalized box filter is supported in case of 32s output");
y_func = (CvColumnFilterFunc)icvSumCol_32s32s;
}
else if( CV_MAT_DEPTH(dst_type) == CV_32F )
{
if( CV_MAT_DEPTH(src_type) != CV_32F )
CV_ERROR( CV_StsBadArg, "Only 32f->32f box filter (normalized or not) is supported in case of 32f output" );
y_func = (CvColumnFilterFunc)icvSumCol_64f32f;
}
else{
CV_ERROR( CV_StsBadArg, "Unknown/unsupported destination image format" );
}
__END__;
}
void CvBoxFilter::start_process( CvSlice x_range, int width )
{
CvBaseImageFilter::start_process( x_range, width );
int i, psz = CV_ELEM_SIZE(work_type);
uchar* s;
buf_end -= buf_step;
buf_max_count--;
assert( buf_max_count >= max_ky*2 + 1 );
s = sum = buf_end + cvAlign((width + ksize.width - 1)*CV_ELEM_SIZE(src_type), ALIGN);
sum_count = 0;
width *= psz;
for( i = 0; i < width; i++ )
s[i] = (uchar)0;
}
static void
icvSumRow_8u32s( const uchar* src, int* dst, void* params )
{
const CvBoxFilter* state = (const CvBoxFilter*)params;
int ksize = state->get_kernel_size().width;
int width = state->get_width();
int cn = CV_MAT_CN(state->get_src_type());
int i, k;
width = (width - 1)*cn; ksize *= cn;
for( k = 0; k < cn; k++, src++, dst++ )
{
int s = 0;
for( i = 0; i < ksize; i += cn )
s += src[i];
dst[0] = s;
for( i = 0; i < width; i += cn )
{
s += src[i+ksize] - src[i];
dst[i+cn] = s;
}
}
}
static void
icvSumRow_32f64f( const float* src, double* dst, void* params )
{
const CvBoxFilter* state = (const CvBoxFilter*)params;
int ksize = state->get_kernel_size().width;
int width = state->get_width();
int cn = CV_MAT_CN(state->get_src_type());
int i, k;
width = (width - 1)*cn; ksize *= cn;
for( k = 0; k < cn; k++, src++, dst++ )
{
double s = 0;
for( i = 0; i < ksize; i += cn )
s += src[i];
dst[0] = s;
for( i = 0; i < width; i += cn )
{
s += (double)src[i+ksize] - src[i];
dst[i+cn] = s;
}
}
}
static void
icvSumCol_32s8u( const int** src, uchar* dst,
int dst_step, int count, void* params )
{
#define BLUR_SHIFT 24
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();
int iscale = cvFloor(scale*(1 << BLUR_SHIFT));
int* sum = (int*)state->get_sum_buf();
int* _sum_count = state->get_sum_count_ptr();
int sum_count = *_sum_count;
width *= cn;
src += sum_count;
count += ksize - 1 - sum_count;
for( ; count--; src++ )
{
const int* sp = src[0];
if( sum_count+1 < ksize )
{
for( i = 0; i <= width - 2; i += 2 )
{
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];
int t0 = CV_DESCALE(s0*iscale, BLUR_SHIFT), t1 = CV_DESCALE(s1*iscale, BLUR_SHIFT);
s0 -= sm[i]; s1 -= sm[i+1];
sum[i] = s0; sum[i+1] = s1;
dst[i] = (uchar)t0; dst[i+1] = (uchar)t1;
}
for( ; i < width; i++ )
{
int s0 = sum[i] + sp[i], t0 = CV_DESCALE(s0*iscale, BLUR_SHIFT);
sum[i] = s0 - sm[i]; dst[i] = (uchar)t0;
}
dst += dst_step;
}
}
*_sum_count = sum_count;
#undef BLUR_SHIFT
}
static void
icvSumCol_32s16s( const int** src, short* dst,
int dst_step, int count, void* params )
{
CvBoxFilter* state = (CvBoxFilter*)params;
int ksize = state->get_kernel_size().height;
int ktotal = ksize*state->get_kernel_size().width;
int i, width = state->get_width();
int cn = CV_MAT_CN(state->get_src_type());
int* sum = (int*)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 int* sp = src[0];
if( sum_count+1 < ksize )
{
for( i = 0; i <= width - 2; i += 2 )
{
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 if( ktotal < 128 )
{
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] = (short)s0; dst[i+1] = (short)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] = (short)s0;
sum[i] = s0 - sm[i];
}
dst += dst_step;
}
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] = CV_CAST_16S(s0); dst[i+1] = CV_CAST_16S(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] = CV_CAST_16S(s0);
sum[i] = s0 - sm[i];
}
dst += dst_step;
}
}
*_sum_count = sum_count;
}
static void
icvSumCol_32s32s( const int** src, int * 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());
int* sum = (int*)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 int* sp = src[0];
if( sum_count+1 < ksize )
{
for( i = 0; i <= width - 2; i += 2 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -