📄 cvimgwarp.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*/
/* ////////////////////////////////////////////////////////////////////
//
// Geometrical transforms on images and matrices: rotation, zoom etc.
//
// */
#include "_cv.h"
/************** interpolation constants and tables ***************/
#define ICV_WARP_MUL_ONE_8U(x) ((x) << ICV_WARP_SHIFT)
#define ICV_WARP_DESCALE_8U(x) CV_DESCALE((x), ICV_WARP_SHIFT*2)
#define ICV_WARP_CLIP_X(x) ((unsigned)(x) < (unsigned)ssize.width ? \
(x) : (x) < 0 ? 0 : ssize.width - 1)
#define ICV_WARP_CLIP_Y(y) ((unsigned)(y) < (unsigned)ssize.height ? \
(y) : (y) < 0 ? 0 : ssize.height - 1)
float icvLinearCoeffs[(ICV_LINEAR_TAB_SIZE+1)*2];
void icvInitLinearCoeffTab()
{
static int inittab = 0;
if( !inittab )
{
for( int i = 0; i <= ICV_LINEAR_TAB_SIZE; i++ )
{
float x = (float)i/ICV_LINEAR_TAB_SIZE;
icvLinearCoeffs[i*2] = x;
icvLinearCoeffs[i*2+1] = 1.f - x;
}
inittab = 1;
}
}
float icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE+1)*2];
void icvInitCubicCoeffTab()
{
static int inittab = 0;
if( !inittab )
{
#if 0
// classical Mitchell-Netravali filter
const double B = 1./3;
const double C = 1./3;
const double p0 = (6 - 2*B)/6.;
const double p2 = (-18 + 12*B + 6*C)/6.;
const double p3 = (12 - 9*B - 6*C)/6.;
const double q0 = (8*B + 24*C)/6.;
const double q1 = (-12*B - 48*C)/6.;
const double q2 = (6*B + 30*C)/6.;
const double q3 = (-B - 6*C)/6.;
#define ICV_CUBIC_1(x) (((x)*p3 + p2)*(x)*(x) + p0)
#define ICV_CUBIC_2(x) ((((x)*q3 + q2)*(x) + q1)*(x) + q0)
#else
// alternative "sharp" filter
const double A = -0.75;
#define ICV_CUBIC_1(x) (((A + 2)*(x) - (A + 3))*(x)*(x) + 1)
#define ICV_CUBIC_2(x) (((A*(x) - 5*A)*(x) + 8*A)*(x) - 4*A)
#endif
for( int i = 0; i <= ICV_CUBIC_TAB_SIZE; i++ )
{
float x = (float)i/ICV_CUBIC_TAB_SIZE;
icvCubicCoeffs[i*2] = (float)ICV_CUBIC_1(x);
x += 1.f;
icvCubicCoeffs[i*2+1] = (float)ICV_CUBIC_2(x);
}
inittab = 1;
}
}
/****************************************************************************************\
* Resize *
\****************************************************************************************/
static CvStatus CV_STDCALL
icvResize_NN_8u_C1R( const uchar* src, int srcstep, CvSize ssize,
uchar* dst, int dststep, CvSize dsize, int pix_size )
{
int* x_ofs = (int*)cvStackAlloc( dsize.width * sizeof(x_ofs[0]) );
int pix_size4 = pix_size / sizeof(int);
int x, y, t;
for( x = 0; x < dsize.width; x++ )
{
t = (ssize.width*x*2 + MIN(ssize.width, dsize.width) - 1)/(dsize.width*2);
t -= t >= ssize.width;
x_ofs[x] = t*pix_size;
}
for( y = 0; y < dsize.height; y++, dst += dststep )
{
const uchar* tsrc;
t = (ssize.height*y*2 + MIN(ssize.height, dsize.height) - 1)/(dsize.height*2);
t -= t >= ssize.height;
tsrc = src + srcstep*t;
switch( pix_size )
{
case 1:
for( x = 0; x <= dsize.width - 2; x += 2 )
{
uchar t0 = tsrc[x_ofs[x]];
uchar t1 = tsrc[x_ofs[x+1]];
dst[x] = t0;
dst[x+1] = t1;
}
for( ; x < dsize.width; x++ )
dst[x] = tsrc[x_ofs[x]];
break;
case 2:
for( x = 0; x < dsize.width; x++ )
*(ushort*)(dst + x*2) = *(ushort*)(tsrc + x_ofs[x]);
break;
case 3:
for( x = 0; x < dsize.width; x++ )
{
const uchar* _tsrc = tsrc + x_ofs[x];
dst[x*3] = _tsrc[0]; dst[x*3+1] = _tsrc[1]; dst[x*3+2] = _tsrc[2];
}
break;
case 4:
for( x = 0; x < dsize.width; x++ )
*(int*)(dst + x*4) = *(int*)(tsrc + x_ofs[x]);
break;
case 6:
for( x = 0; x < dsize.width; x++ )
{
const ushort* _tsrc = (const ushort*)(tsrc + x_ofs[x]);
ushort* _tdst = (ushort*)(dst + x*6);
_tdst[0] = _tsrc[0]; _tdst[1] = _tsrc[1]; _tdst[2] = _tsrc[2];
}
break;
default:
for( x = 0; x < dsize.width; x++ )
CV_MEMCPY_INT( dst + x*pix_size, tsrc + x_ofs[x], pix_size4 );
}
}
return CV_OK;
}
typedef struct CvResizeAlpha
{
int idx;
union
{
float alpha;
int ialpha;
};
}
CvResizeAlpha;
#define ICV_DEF_RESIZE_BILINEAR_FUNC( flavor, arrtype, worktype, alpha_field, \
mul_one_macro, descale_macro ) \
static CvStatus CV_STDCALL \
icvResize_Bilinear_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize,\
arrtype* dst, int dststep, CvSize dsize, \
int cn, int xmax, \
const CvResizeAlpha* xofs, \
const CvResizeAlpha* yofs, \
worktype* buf0, worktype* buf1 ) \
{ \
int prev_sy0 = -1, prev_sy1 = -1; \
int k, dx, dy; \
\
srcstep /= sizeof(src[0]); \
dststep /= sizeof(dst[0]); \
dsize.width *= cn; \
xmax *= cn; \
\
for( dy = 0; dy < dsize.height; dy++, dst += dststep ) \
{ \
worktype fy = yofs[dy].alpha_field, *swap_t; \
int sy0 = yofs[dy].idx, sy1 = sy0 + (fy > 0 && sy0 < ssize.height-1); \
\
if( sy0 == prev_sy0 && sy1 == prev_sy1 ) \
k = 2; \
else if( sy0 == prev_sy1 ) \
{ \
CV_SWAP( buf0, buf1, swap_t ); \
k = 1; \
} \
else \
k = 0; \
\
for( ; k < 2; k++ ) \
{ \
worktype* _buf = k == 0 ? buf0 : buf1; \
const arrtype* _src; \
int sy = k == 0 ? sy0 : sy1; \
if( k == 1 && sy1 == sy0 ) \
{ \
memcpy( buf1, buf0, dsize.width*sizeof(buf0[0]) ); \
continue; \
} \
\
_src = src + sy*srcstep; \
for( dx = 0; dx < xmax; dx++ ) \
{ \
int sx = xofs[dx].idx; \
worktype fx = xofs[dx].alpha_field; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -