📄 cvimgwarp.cpp
字号:
p0 = descale_macro( mul_one_macro(p0) + b*(p1 - p0) ); \
dst[x*cn+k] = (arrtype)cast_macro(p0); \
} \
} \
else if( fillval ) \
for( k = 0; k < cn; k++ ) \
dst[x*cn+k] = fillval[k]; \
} \
} \
\
return CV_OK; \
}
#define ICV_WARP_SCALE_ALPHA(x) ((x)*(1./(ICV_WARP_MASK+1)))
ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 8u, uchar, int, CV_NOP, ICV_WARP_MUL_ONE_8U,
ICV_WARP_DESCALE_8U, CV_NOP )
//ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 8u, uchar, double, ICV_WARP_SCALE_ALPHA, CV_NOP,
// CV_NOP, ICV_WARP_CAST_8U )
ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 16u, ushort, double, ICV_WARP_SCALE_ALPHA, CV_NOP,
CV_NOP, cvRound )
ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 32f, float, double, ICV_WARP_SCALE_ALPHA, CV_NOP,
CV_NOP, CV_NOP )
typedef CvStatus (CV_STDCALL * CvWarpAffineFunc)(
const void* src, int srcstep, CvSize ssize,
void* dst, int dststep, CvSize dsize,
const double* matrix, int cn,
const void* fillval, const int* ofs );
static void icvInitWarpAffineTab( CvFuncTable* bilin_tab )
{
bilin_tab->fn_2d[CV_8U] = (void*)icvWarpAffine_Bilinear_8u_CnR;
bilin_tab->fn_2d[CV_16U] = (void*)icvWarpAffine_Bilinear_16u_CnR;
bilin_tab->fn_2d[CV_32F] = (void*)icvWarpAffine_Bilinear_32f_CnR;
}
/////////////////////////////// IPP warpaffine functions /////////////////////////////////
icvWarpAffineBack_8u_C1R_t icvWarpAffineBack_8u_C1R_p = 0;
icvWarpAffineBack_8u_C3R_t icvWarpAffineBack_8u_C3R_p = 0;
icvWarpAffineBack_8u_C4R_t icvWarpAffineBack_8u_C4R_p = 0;
icvWarpAffineBack_32f_C1R_t icvWarpAffineBack_32f_C1R_p = 0;
icvWarpAffineBack_32f_C3R_t icvWarpAffineBack_32f_C3R_p = 0;
icvWarpAffineBack_32f_C4R_t icvWarpAffineBack_32f_C4R_p = 0;
typedef CvStatus (CV_STDCALL * CvWarpAffineBackIPPFunc)
( const void* src, CvSize srcsize, int srcstep, CvRect srcroi,
void* dst, int dststep, CvRect dstroi,
const double* coeffs, int interpolation );
//////////////////////////////////////////////////////////////////////////////////////////
CV_IMPL void
cvWarpAffine( const CvArr* srcarr, CvArr* dstarr, const CvMat* matrix,
int flags, CvScalar fillval )
{
static CvFuncTable bilin_tab;
static int inittab = 0;
CV_FUNCNAME( "cvWarpAffine" );
__BEGIN__;
CvMat srcstub, *src = (CvMat*)srcarr;
CvMat dststub, *dst = (CvMat*)dstarr;
int k, type, depth, cn, *ofs = 0;
double src_matrix[6], dst_matrix[6];
double fillbuf[4];
int method = flags & 3;
CvMat srcAb = cvMat( 2, 3, CV_64F, src_matrix ),
dstAb = cvMat( 2, 3, CV_64F, dst_matrix ),
A, b, invA, invAb;
CvWarpAffineFunc func;
CvSize ssize, dsize;
if( !inittab )
{
icvInitWarpAffineTab( &bilin_tab );
inittab = 1;
}
CV_CALL( src = cvGetMat( srcarr, &srcstub ));
CV_CALL( dst = cvGetMat( dstarr, &dststub ));
if( !CV_ARE_TYPES_EQ( src, dst ))
CV_ERROR( CV_StsUnmatchedFormats, "" );
if( !CV_IS_MAT(matrix) || CV_MAT_CN(matrix->type) != 1 ||
CV_MAT_DEPTH(matrix->type) < CV_32F || matrix->rows != 2 || matrix->cols != 3 )
CV_ERROR( CV_StsBadArg,
"Transformation matrix should be 2x3 floating-point single-channel matrix" );
if( flags & CV_WARP_INVERSE_MAP )
cvConvertScale( matrix, &dstAb );
else
{
// [R|t] -> [R^-1 | -(R^-1)*t]
cvConvertScale( matrix, &srcAb );
cvGetCols( &srcAb, &A, 0, 2 );
cvGetCol( &srcAb, &b, 2 );
cvGetCols( &dstAb, &invA, 0, 2 );
cvGetCol( &dstAb, &invAb, 2 );
cvInvert( &A, &invA, CV_SVD );
cvGEMM( &invA, &b, -1, 0, 0, &invAb );
}
type = CV_MAT_TYPE(src->type);
depth = CV_MAT_DEPTH(type);
cn = CV_MAT_CN(type);
if( cn > 4 )
CV_ERROR( CV_BadNumChannels, "" );
ssize = cvGetMatSize(src);
dsize = cvGetMatSize(dst);
if( icvWarpAffineBack_8u_C1R_p && MIN( ssize.width, dsize.width ) >= 4 &&
MIN( ssize.height, dsize.height ) >= 4 )
{
CvWarpAffineBackIPPFunc ipp_func =
type == CV_8UC1 ? icvWarpAffineBack_8u_C1R_p :
type == CV_8UC3 ? icvWarpAffineBack_8u_C3R_p :
type == CV_8UC4 ? icvWarpAffineBack_8u_C4R_p :
type == CV_32FC1 ? icvWarpAffineBack_32f_C1R_p :
type == CV_32FC3 ? icvWarpAffineBack_32f_C3R_p :
type == CV_32FC4 ? icvWarpAffineBack_32f_C4R_p : 0;
if( ipp_func && CV_INTER_NN <= method && method <= CV_INTER_AREA )
{
int srcstep = src->step ? src->step : CV_STUB_STEP;
int dststep = dst->step ? dst->step : CV_STUB_STEP;
CvRect srcroi = {0, 0, ssize.width, ssize.height};
CvRect dstroi = {0, 0, dsize.width, dsize.height};
// this is not the most efficient way to fill outliers
if( flags & CV_WARP_FILL_OUTLIERS )
cvSet( dst, fillval );
if( ipp_func( src->data.ptr, ssize, srcstep, srcroi,
dst->data.ptr, dststep, dstroi,
dstAb.data.db, 1 << method ) >= 0 )
EXIT;
}
}
cvScalarToRawData( &fillval, fillbuf, CV_MAT_TYPE(src->type), 0 );
ofs = (int*)cvStackAlloc( dst->cols*2*sizeof(ofs[0]) );
for( k = 0; k < dst->cols; k++ )
{
ofs[2*k] = CV_FLT_TO_FIX( dst_matrix[0]*k, ICV_WARP_SHIFT );
ofs[2*k+1] = CV_FLT_TO_FIX( dst_matrix[3]*k, ICV_WARP_SHIFT );
}
/*if( method == CV_INTER_LINEAR )*/
{
func = (CvWarpAffineFunc)bilin_tab.fn_2d[depth];
if( !func )
CV_ERROR( CV_StsUnsupportedFormat, "" );
IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
dst->step, dsize, dst_matrix, cn,
flags & CV_WARP_FILL_OUTLIERS ? fillbuf : 0, ofs ));
}
__END__;
}
CV_IMPL CvMat*
cv2DRotationMatrix( CvPoint2D32f center, double angle,
double scale, CvMat* matrix )
{
CV_FUNCNAME( "cvGetRotationMatrix" );
__BEGIN__;
double m[2][3];
CvMat M = cvMat( 2, 3, CV_64FC1, m );
double alpha, beta;
if( !matrix )
CV_ERROR( CV_StsNullPtr, "" );
angle *= CV_PI/180;
alpha = cos(angle)*scale;
beta = sin(angle)*scale;
m[0][0] = alpha;
m[0][1] = beta;
m[0][2] = (1-alpha)*center.x - beta*center.y;
m[1][0] = -beta;
m[1][1] = alpha;
m[1][2] = beta*center.x + (1-alpha)*center.y;
cvConvert( &M, matrix );
__END__;
return matrix;
}
/****************************************************************************************\
* WarpPerspective *
\****************************************************************************************/
#define ICV_DEF_WARP_PERSPECTIVE_BILINEAR_FUNC( flavor, arrtype, load_macro, cast_macro )\
static CvStatus CV_STDCALL \
icvWarpPerspective_Bilinear_##flavor##_CnR( \
const arrtype* src, int step, CvSize ssize, \
arrtype* dst, int dststep, CvSize dsize, \
const double* matrix, int cn, \
const arrtype* fillval ) \
{ \
int x, y, k; \
float A11 = (float)matrix[0], A12 = (float)matrix[1], A13 = (float)matrix[2];\
float A21 = (float)matrix[3], A22 = (float)matrix[4], A23 = (float)matrix[5];\
float A31 = (float)matrix[6], A32 = (float)matrix[7], A33 = (float)matrix[8];\
\
step /= sizeof(src[0]); \
dststep /= sizeof(dst[0]); \
\
for( y = 0; y < dsize.height; y++, dst += dststep ) \
{ \
float xs0 = A12*y + A13; \
float ys0 = A22*y + A23; \
float ws = A32*y + A33; \
\
for( x = 0; x < dsize.width; x++, xs0 += A11, ys0 += A21, ws += A31 )\
{ \
float inv_ws = 1.f/ws; \
float xs = xs0*inv_ws; \
float ys = ys0*inv_ws; \
int ixs = cvFloor(xs); \
int iys = cvFloor(ys); \
float a = xs - ixs; \
float b = ys - iys; \
float p0, p1; \
\
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++ ) \
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -