///////////////////////////////////////////////////////////////////////////
这个简单的算法我是依书写的,但是和双线性插值比差别比较大,但是我找不到问题在那
所以来问问,希望给我的代码点建议,哪怕与算法无关也行啊三次卷积法计算精度高,但计算亮大,他考虑一个浮点坐标(i+u,j+v)周围的16个邻点,目的像素值f(i+u,j+v)可由如下插值公式得到:    f(i+u,j+v) = [A] * [B] * [C][A]=[ S(u + 1) S(u + 0) S(u - 1) S(u - 2) ]  ┏ f(i-1, j-1) f(i-1, j+0) f(i-1, j+1) f(i-1, j+2) ┓
[B]=┃ f(i+0, j-1) f(i+0, j+0) f(i+0, j+1) f(i+0, j+2) ┃
  ┃ f(i+1, j-1) f(i+1, j+0) f(i+1, j+1) f(i+1, j+2) ┃
  ┗ f(i+2, j-1) f(i+2, j+0) f(i+2, j+1) f(i+2, j+2) ┛  ┏ S(v + 1) ┓
[C]=┃ S(v + 0) ┃
  ┃ S(v - 1) ┃
  ┗ S(v - 2) ┛   ┏ 1-2*Abs(x)^2+Abs(x)^3      , 0<=Abs(x)<1
S(x)={ 4-8*Abs(x)+5*Abs(x)^2-Abs(x)^3 , 1<=Abs(x)<2
   ┗ 0                , Abs(x)>=2
S(x)是对 Sin(x*Pi)/x 的逼近(Pi是圆周率——π)
//逼近sin(x)/x
double S(double x)
{
double t = abs(x);
if (t>=0 && t<1)
return 1 -2*t*t + t*t*t;
else if(t>=1 && t<2)
return 4 -8*t + 5*t*t - t*t*t;
else
return 0;
}/// \brief 矩阵相乘 lpC = lpA*lpB,lpA m*s,lpB s*n,空间lpC外部分配
template<class T> 
T* matrix_multiplication(T* lpA,T* lpB,T* lpC,UINT m,UINT s,UINT n)
{
ASSERT(lpC!=NULL);
ASSERT(m!=0 && n!=0 && s!=0);
ASSERT(!::IsBadWritePtr(lpC,m*n*sizeof(T)));
ASSERT(!::IsBadReadPtr(lpA,m*s*sizeof(T)));
ASSERT(!::IsBadReadPtr(lpB,s*n*sizeof(T))); UINT i,j,k;
// for (i=0;i<m;i++)
// for (j=0;j<n;j++)
// *(lpC+i*n+j) = 0;
memset(lpC,0,m*n*sizeof(T)); for (i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
for (k=0;k<s;k++)
{
*(lpC+i*n+j) += *(lpA+i*s+k) * *(lpB+k*n+j);
// cerr<<*(lpA+i*s+k)<<'\t'<<*(lpB+k*n+j)<<endl;
}
}
} return lpC;
}/// \brief 三次卷积插值
//tx,ty 映射点座标,屏幕座标系(x横向右,y纵向下为正)
//p_0 数据矩阵起点
//nWidth, nHeight 数据矩阵大小
//rW,rH 映射矩阵比被映射矩阵
//返回tx,ty点的像素
template<class T>
T thrice_convolution
(int tx,int ty,T* p_0,UINT nWidth,UINT nHeight,double rW,double rH)
{
ASSERT(rW!=0 && rH!=0);
ASSERT(tx<nWidth && tx>=0);
ASSERT(ty<nHeight && ty>=0); //这就是所谓的反向变换
double u,v;
int x,y;
x = tx/rW;
y = ty/rH;
u = tx/rW - x;
v = ty/rH - y; int i,j; T A[4],B[4][4],C[4]; A[0] = S(u+1);
A[1] = S(u);
A[2] = S(u-1);
A[3] = S(u-2); C[0] = S(v+1);
C[1] = S(v);
C[2] = S(v-1);
C[3] = S(v-2); T* p = p_0 + y*nWidth +x;
ASSERT(!::IsBadReadPtr(p,sizeof(T)));
for (i=-1;i<3;i++)
{
for (j=-1;j<3;j++)
{
B[i+1][j+1] = *( p+i*nWidth+j );
}
} T* lp = new T[4];
matrix_multiplication(A, &B[0][0], lp,1,4,4);
T t ;
matrix_multiplication(lp, C, &t,1,4,1); delete []lp;
return t;
};

解决方案 »

  1.   

    我看了一下,好像没什么问题,和算法相符
    首先说,搂主用模板写我赞
    好多家伙嫌模版麻烦,我觉得算法如果是通用的,用模版多好 啊,大家还可以代码共享看看楼下同志们的测试结果怎么样个人感觉
    ASSERT(!::IsBadWritePtr(lpC,m*n*sizeof(T)));
    ASSERT(!::IsBadReadPtr(lpA,m*s*sizeof(T)));
    ASSERT(!::IsBadReadPtr(lpB,s*n*sizeof(T)));
    没什么用,反而会降低效率,好在你放在D板中了另外你用矩阵算的,我见过直接是矩阵展开算的,不过差不多了,都一样另外,UINT大小的矩阵,哈哈估计我的计算机是够呛,