📄 cvfilter.cpp
字号:
break;
j -= 1 + shift;
dj = -dj;
}
}
for( i = 0, j = row_count-1-shift; i < bottom_rows; i++, j-- )
rows[i + row_count] = rows[j];
}
}
int CvBaseImageFilter::fill_cyclic_buffer( const uchar* src, int src_step,
int y0, int y1, int y2 )
{
int i, y = y0, bsz1 = border_tab_sz1, bsz = border_tab_sz;
int pix_size = CV_ELEM_SIZE(src_type);
int width = prev_x_range.end_index - prev_x_range.start_index, width_n = width*pix_size;
bool can_use_src_as_trow = is_separable && width >= ksize.width;
// fill the cyclic buffer
for( ; buf_count < buf_max_count && y < y2; buf_count++, y++, src += src_step )
{
uchar* trow = is_separable ? buf_end : buf_tail;
uchar* bptr = can_use_src_as_trow && y1 < y && y+1 < y2 ? (uchar*)(src - bsz1) : trow;
if( bptr != trow )
{
for( i = 0; i < bsz1; i++ )
trow[i] = bptr[i];
for( ; i < bsz; i++ )
trow[i] = bptr[i + width_n];
}
else if( !(((size_t)(bptr + bsz1)|(size_t)src|width_n) & (sizeof(int)-1)) )
for( i = 0; i < width_n; i += sizeof(int) )
*(int*)(bptr + i + bsz1) = *(int*)(src + i);
else
for( i = 0; i < width_n; i++ )
bptr[i + bsz1] = src[i];
if( border_mode != IPL_BORDER_CONSTANT )
{
for( i = 0; i < bsz1; i++ )
{
int j = border_tab[i];
bptr[i] = bptr[j];
}
for( ; i < bsz; i++ )
{
int j = border_tab[i];
bptr[i + width_n] = bptr[j];
}
}
else
{
const uchar *bt = (uchar*)border_tab;
for( i = 0; i < bsz1; i++ )
bptr[i] = bt[i];
for( ; i < bsz; i++ )
bptr[i + width_n] = bt[i];
}
if( is_separable )
{
x_func( bptr, buf_tail, this );
if( bptr != trow )
{
for( i = 0; i < bsz1; i++ )
bptr[i] = trow[i];
for( ; i < bsz; i++ )
bptr[i + width_n] = trow[i];
}
}
buf_tail += buf_step;
if( buf_tail >= buf_end )
buf_tail = buf_start;
}
return y - y0;
}
int CvBaseImageFilter::process( const CvMat* src, CvMat* dst,
CvRect src_roi, CvPoint dst_origin, int flags )
{
int rows_processed = 0;
/*
check_parameters
initialize_horizontal_border_reloc_tab_if_not_initialized_yet
for_each_source_row: src starts from src_roi.y, buf starts with the first available row
1) if separable,
1a.1) copy source row to temporary buffer, form a border using border reloc tab.
1a.2) apply row-wise filter (symmetric, asymmetric or generic)
else
1b.1) copy source row to the buffer, form a border
2) if the buffer is full, or it is the last source row:
2.1) if stage != middle, form the pointers to other "virtual" rows.
if separable
2a.2) apply column-wise filter, store the results.
else
2b.2) form a sparse (offset,weight) tab
2b.3) apply generic non-separable filter, store the results
3) update row pointers etc.
*/
CV_FUNCNAME( "CvBaseImageFilter::process" );
__BEGIN__;
int i, width, _src_y1, _src_y2;
int src_x, src_y, src_y1, src_y2, dst_y;
int pix_size = CV_ELEM_SIZE(src_type);
uchar *sptr = 0, *dptr;
int phase = flags & (CV_START|CV_END|CV_MIDDLE);
bool isolated_roi = (flags & CV_ISOLATED_ROI) != 0;
if( !CV_IS_MAT(src) )
CV_ERROR( CV_StsBadArg, "" );
if( CV_MAT_TYPE(src->type) != src_type )
CV_ERROR( CV_StsUnmatchedFormats, "" );
width = src->cols;
if( src_roi.width == -1 && src_roi.x == 0 )
src_roi.width = width;
if( src_roi.height == -1 && src_roi.y == 0 )
{
src_roi.y = 0;
src_roi.height = src->rows;
}
if( src_roi.width > max_width ||
src_roi.x < 0 || src_roi.width < 0 ||
src_roi.y < 0 || src_roi.height < 0 ||
src_roi.x + src_roi.width > width ||
src_roi.y + src_roi.height > src->rows )
CV_ERROR( CV_StsOutOfRange, "Too large source image or its ROI" );
src_x = src_roi.x;
_src_y1 = 0;
_src_y2 = src->rows;
if( isolated_roi )
{
src_roi.x = 0;
width = src_roi.width;
_src_y1 = src_roi.y;
_src_y2 = src_roi.y + src_roi.height;
}
if( !CV_IS_MAT(dst) )
CV_ERROR( CV_StsBadArg, "" );
if( CV_MAT_TYPE(dst->type) != dst_type )
CV_ERROR( CV_StsUnmatchedFormats, "" );
if( dst_origin.x < 0 || dst_origin.y < 0 )
CV_ERROR( CV_StsOutOfRange, "Incorrect destination ROI origin" );
if( phase == CV_WHOLE )
phase = CV_START | CV_END;
phase &= CV_START | CV_END | CV_MIDDLE;
// initialize horizontal border relocation tab if it is not initialized yet
if( phase & CV_START )
start_process( cvSlice(src_roi.x, src_roi.x + src_roi.width), width );
else if( prev_width != width || prev_x_range.start_index != src_roi.x ||
prev_x_range.end_index != src_roi.x + src_roi.width )
CV_ERROR( CV_StsBadArg,
"In a middle or at the end the horizontal placement of the stripe can not be changed" );
dst_y = dst_origin.y;
src_y1 = src_roi.y;
src_y2 = src_roi.y + src_roi.height;
if( phase & CV_START )
{
for( i = 0; i <= max_ky*2; i++ )
rows[i] = 0;
src_y1 -= max_ky;
top_rows = bottom_rows = 0;
if( src_y1 < _src_y1 )
{
top_rows = _src_y1 - src_y1;
src_y1 = _src_y1;
}
buf_head = buf_tail = buf_start;
buf_count = 0;
}
if( phase & CV_END )
{
src_y2 += max_ky;
if( src_y2 > _src_y2 )
{
bottom_rows = src_y2 - _src_y2;
src_y2 = _src_y2;
}
}
dptr = dst->data.ptr + dst_origin.y*dst->step + dst_origin.x*CV_ELEM_SIZE(dst_type);
sptr = src->data.ptr + src_y1*src->step + src_x*pix_size;
for( src_y = src_y1; src_y < src_y2; )
{
uchar* bptr;
int row_count, delta;
delta = fill_cyclic_buffer( sptr, src->step, src_y, src_y1, src_y2 );
src_y += delta;
sptr += src->step*delta;
// initialize the cyclic buffer row pointers
bptr = buf_head;
for( i = 0; i < buf_count; i++ )
{
rows[i+top_rows] = bptr;
bptr += buf_step;
if( bptr >= buf_end )
bptr = buf_start;
}
row_count = top_rows + buf_count;
if( !rows[0] || (phase & CV_END) && src_y == src_y2 )
{
int br = (phase & CV_END) && src_y == src_y2 ? bottom_rows : 0;
make_y_border( row_count, top_rows, br );
row_count += br;
}
if( rows[0] && row_count > max_ky*2 )
{
int count = row_count - max_ky*2;
if( dst_y + count > dst->rows )
CV_ERROR( CV_StsOutOfRange, "The destination image can not fit the result" );
assert( count >= 0 );
y_func( rows + max_ky - anchor.y, dptr, dst->step, count, this );
row_count -= count;
dst_y += count;
dptr += dst->step*count;
for( bptr = row_count > 0 ?rows[count] : 0; buf_head != bptr && buf_count > 0; buf_count-- )
{
buf_head += buf_step;
if( buf_head >= buf_end )
buf_head = buf_start;
}
rows_processed += count;
top_rows = MAX(top_rows - count, 0);
}
}
__END__;
return rows_processed;
}
/****************************************************************************************\
Separable Linear Filter
\****************************************************************************************/
static void icvFilterRowSymm_8u32s( const uchar* src, int* dst, void* params );
static void icvFilterColSymm_32s8u( const int** src, uchar* dst, int dst_step,
int count, void* params );
static void icvFilterColSymm_32s16s( const int** src, short* dst, int dst_step,
int count, void* params );
static void icvFilterRowSymm_8u32f( const uchar* src, float* dst, void* params );
static void icvFilterRow_8u32f( const uchar* src, float* dst, void* params );
static void icvFilterRowSymm_16s32f( const short* src, float* dst, void* params );
static void icvFilterRow_16s32f( const short* src, float* dst, void* params );
static void icvFilterRowSymm_16u32f( const ushort* src, float* dst, void* params );
static void icvFilterRow_16u32f( const ushort* src, float* dst, void* params );
static void icvFilterRowSymm_32f( const float* src, float* dst, void* params );
static void icvFilterRow_32f( const float* src, float* dst, void* params );
static void icvFilterColSymm_32f8u( const float** src, uchar* dst, int dst_step,
int count, void* params );
static void icvFilterCol_32f8u( const float** src, uchar* dst, int dst_step,
int count, void* params );
static void icvFilterColSymm_32f16s( const float** src, short* dst, int dst_step,
int count, void* params );
static void icvFilterCol_32f16s( const float** src, short* dst, int dst_step,
int count, void* params );
static void icvFilterColSymm_32f16u( const float** src, ushort* dst, int dst_step,
int count, void* params );
static void icvFilterCol_32f16u( const float** src, ushort* dst, int dst_step,
int count, void* params );
static void icvFilterColSymm_32f( const float** src, float* dst, int dst_step,
int count, void* params );
static void icvFilterCol_32f( const float** src, float* dst, int dst_step,
int count, void* params );
CvSepFilter::CvSepFilter()
{
min_depth = CV_32F;
kx = ky = 0;
kx_flags = ky_flags = 0;
}
CvSepFilter::CvSepFilter( int _max_width, int _src_type, int _dst_type,
const CvMat* _kx, const CvMat* _ky,
CvPoint _anchor, int _border_mode,
CvScalar _border_value )
{
min_depth = CV_32F;
kx = ky = 0;
init( _max_width, _src_type, _dst_type, _kx, _ky, _anchor, _border_mode, _border_value );
}
void CvSepFilter::clear()
{
cvReleaseMat( &kx );
cvReleaseMat( &ky );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -