📄 cvimgwarp.c
字号:
float fsx1 = dx*scale_x, fsx2 = fsx1 + scale_x;
int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2);
assert( (unsigned)sx1 < (unsigned)ssize.width );
if( sx1 > fsx1 )
{
assert( k < ssize.width*2 );
xofs[k].di = dx*cn;
xofs[k].si = (sx1-1)*cn;
xofs[k++].alpha = (sx1 - fsx1)*scale;
}
for( sx = sx1; sx < sx2; sx++ )
{
assert( k < ssize.width*2 );
xofs[k].di = dx*cn;
xofs[k].si = sx*cn;
xofs[k++].alpha = scale;
}
if( fsx2 - sx2 > 1e-3 )
{
assert( k < ssize.width*2 );
assert((unsigned)sx2 < (unsigned)ssize.width );
xofs[k].di = dx*cn;
xofs[k].si = sx2*cn;
xofs[k++].alpha = (fsx2 - sx2)*scale;
}
}
xofs_count = k;
memset( sum, 0, buf_len*sizeof(float) );
memset( buf, 0, buf_len*sizeof(float) );
IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
dst->step, dsize, cn, xofs, xofs_count, buf, sum ));
}
}
else // true "area" method for the cases (scale_x > 1 & scale_y < 1) and
// (scale_x < 1 & scale_y > 1) is not implemented.
// instead, it is emulated via some variant of bilinear interpolation.
{
float inv_scale_x = (float)dsize.width/ssize.width;
float inv_scale_y = (float)dsize.height/ssize.height;
int xmax = dsize.width, width = dsize.width*cn, buf_size;
float *buf0, *buf1;
CvResizeAlpha *xofs, *yofs;
int area_mode = method == CV_INTER_AREA;
float fx, fy;
CvResizeBilinearFunc func = (CvResizeBilinearFunc)bilin_tab.fn_2d[depth];
if( !func )
CV_ERROR( CV_StsUnsupportedFormat, "" );
buf_size = width*2*sizeof(float) + (width + dsize.height)*sizeof(CvResizeAlpha);
if( buf_size < CV_MAX_LOCAL_SIZE )
buf0 = (float*)cvStackAlloc(buf_size);
else
CV_CALL( temp_buf = buf0 = (float*)cvAlloc(buf_size));
buf1 = buf0 + width;
xofs = (CvResizeAlpha*)(buf1 + width);
yofs = xofs + width;
for( dx = 0; dx < dsize.width; dx++ )
{
if( !area_mode )
{
fx = (float)((dx+0.5)*scale_x - 0.5);
sx = cvFloor(fx);
fx -= sx;
}
else
{
sx = cvFloor(dx*scale_x);
fx = (dx+1) - (sx+1)*inv_scale_x;
fx = fx <= 0 ? 0.f : fx - cvFloor(fx);
}
if( sx < 0 )
fx = 0, sx = 0;
if( sx >= ssize.width-1 )
{
fx = 0, sx = ssize.width-1;
if( xmax >= dsize.width )
xmax = dx;
}
if( depth != CV_8U )
for( k = 0, sx *= cn; k < cn; k++ )
xofs[dx*cn + k].idx = sx + k, xofs[dx*cn + k].alpha = fx;
else
for( k = 0, sx *= cn; k < cn; k++ )
xofs[dx*cn + k].idx = sx + k,
xofs[dx*cn + k].ialpha = CV_FLT_TO_FIX(fx, ICV_WARP_SHIFT);
}
for( dy = 0; dy < dsize.height; dy++ )
{
if( !area_mode )
{
fy = (float)((dy+0.5)*scale_y - 0.5);
sy = cvFloor(fy);
fy -= sy;
if( sy < 0 )
sy = 0, fy = 0;
}
else
{
sy = cvFloor(dy*scale_y);
fy = (dy+1) - (sy+1)*inv_scale_y;
fy = fy <= 0 ? 0.f : fy - cvFloor(fy);
}
yofs[dy].idx = sy;
if( depth != CV_8U )
yofs[dy].alpha = fy;
else
yofs[dy].ialpha = CV_FLT_TO_FIX(fy, ICV_WARP_SHIFT);
}
IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
dst->step, dsize, cn, xmax, xofs, yofs, buf0, buf1 ));
}
}
else if( method == CV_INTER_CUBIC )
{
int width = dsize.width*cn, buf_size;
int xmin = dsize.width, xmax = -1;
CvResizeAlpha* xofs;
float* buf[4];
CvResizeBicubicFunc func = (CvResizeBicubicFunc)bicube_tab.fn_2d[depth];
if( !func )
CV_ERROR( CV_StsUnsupportedFormat, "" );
buf_size = width*(4*sizeof(float) + sizeof(xofs[0]));
if( buf_size < CV_MAX_LOCAL_SIZE )
buf[0] = (float*)cvStackAlloc(buf_size);
else
CV_CALL( temp_buf = buf[0] = (float*)cvAlloc(buf_size));
for( k = 1; k < 4; k++ )
buf[k] = buf[k-1] + width;
xofs = (CvResizeAlpha*)(buf[3] + width);
icvInitCubicCoeffTab();
for( dx = 0; dx < dsize.width; dx++ )
{
float fx = dx*scale_x;
int ifx;
sx = cvFloor(fx);
fx -= sx;
ifx = cvRound(fx*ICV_CUBIC_TAB_SIZE);
if( sx-1 >= 0 && xmin > dx )
xmin = dx;
if( sx+2 < ssize.width )
xmax = dx + 1;
// at least one of 4 points should be within the image - to
// be able to set other points to the same value. see the loops
// for( dx = 0; dx < xmin; dx++ ) ... and for( ; dx < width; dx++ ) ...
if( sx < -2 )
sx = -2;
else if( sx > ssize.width )
sx = ssize.width;
for( k = 0; k < cn; k++ )
{
xofs[dx*cn + k].idx = sx*cn + k;
xofs[dx*cn + k].ialpha = ifx;
}
}
IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
dst->step, dsize, cn, xmin, xmax, xofs, buf ));
}
else
CV_ERROR( CV_StsBadFlag, "Unknown/unsupported interpolation method" );
__END__;
cvFree( &temp_buf );
}
#if 0
/****************************************************************************************\
* WarpAffine *
\****************************************************************************************/
#define ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( flavor, arrtype, worktype, \
scale_alpha_macro, mul_one_macro, descale_macro, cast_macro ) \
static CvStatus CV_STDCALL \
icvWarpAffine_Bilinear_##flavor##_CnR( \
const arrtype* src, int step, CvSize ssize, \
arrtype* dst, int dststep, CvSize dsize, \
const double* matrix, int cn, \
const arrtype* fillval, const int* ofs ) \
{ \
int x, y, k; \
double A12 = matrix[1], b1 = matrix[2]; \
double A22 = matrix[4], b2 = matrix[5]; \
\
step /= sizeof(src[0]); \
dststep /= sizeof(dst[0]); \
\
for( y = 0; y < dsize.height; y++, dst += dststep ) \
{ \
int xs = CV_FLT_TO_FIX( A12*y + b1, ICV_WARP_SHIFT ); \
int ys = CV_FLT_TO_FIX( A22*y + b2, ICV_WARP_SHIFT ); \
\
for( x = 0; x < dsize.width; x++ ) \
{ \
int ixs = xs + ofs[x*2]; \
int iys = ys + ofs[x*2+1]; \
worktype a = scale_alpha_macro( ixs & ICV_WARP_MASK ); \
worktype b = scale_alpha_macro( iys & ICV_WARP_MASK ); \
worktype p0, p1; \
ixs >>= ICV_WARP_SHIFT; \
iys >>= ICV_WARP_SHIFT; \
\
if( (unsigned)ixs < (unsigned)(ssize.width - 1) && \
(unsigned)iys < (unsigned)(ssize.height - 1) ) \
{ \
const arrtype* ptr = src + step*iys + ixs*cn; \
\
for( k = 0; k < cn; k++ ) \
{ \
p0 = mul_one_macro(ptr[k]) + \
a * (ptr[k+cn] - ptr[k]); \
p1 = mul_one_macro(ptr[k+step]) + \
a * (ptr[k+cn+step] - ptr[k+step]); \
p0 = descale_macro(mul_one_macro(p0) + b*(p1 - p0)); \
dst[x*cn+k] = (arrtype)cast_macro(p0); \
} \
} \
else if( (unsigned)(ixs+1) < (unsigned)(ssize.width+1) && \
(unsigned)(iys+1) < (unsigned)(ssize.height+1)) \
{ \
int x0 = ICV_WARP_CLIP_X( ixs ); \
int y0 = ICV_WARP_CLIP_Y( iys ); \
int x1 = ICV_WARP_CLIP_X( ixs + 1 ); \
int y1 = ICV_WARP_CLIP_Y( iys + 1 ); \
const arrtype* ptr0, *ptr1, *ptr2, *ptr3; \
\
ptr0 = src + y0*step + x0*cn; \
ptr1 = src + y0*step + x1*cn; \
ptr2 = src + y1*step + x0*cn; \
ptr3 = src + y1*step + x1*cn; \
\
for( k = 0; k < cn; k++ ) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -