///////////////////////////////////////////////////////////////////////////
这个简单的算法我是依书写的,但是和双线性插值比差别比较大,但是我找不到问题在那
所以来问问,希望给我的代码点建议,哪怕与算法无关也行啊三次卷积法计算精度高,但计算亮大,他考虑一个浮点坐标(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;
};
这个简单的算法我是依书写的,但是和双线性插值比差别比较大,但是我找不到问题在那
所以来问问,希望给我的代码点建议,哪怕与算法无关也行啊三次卷积法计算精度高,但计算亮大,他考虑一个浮点坐标(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;
};
解决方案 »
- toolbarctrl问题
- 在sock I/O中,有一种是"重叠I/O",我想知道"重叠I/O模型"名字的由来,哪里体现了重叠呢?为什么叫重叠呢?我看过这个模型,但不知道它为
- 刚开始学用DirectShow就碰到了问题..
- ●●●为什么在线程中线程参数会受到影响?●●●
- word 属性更改
- 编程高手看过来!!!!应聘请回复并请附详细介绍
- vc中如何得到IE中某一页面得内容
- 如何获取mib变量?
- mfc 创建的CMAINFRAME 类中dump 函数 和 precreatewindow 是做什么用的?
- 关于注册表的一点问题?求助高手!!!
- 请教:如何引用C编译的.OBJ文件,谢谢!
- 如何让放在CListBox控件范围上的CPicture控件上的图片能正常显示出来?
首先说,搂主用模板写我赞
好多家伙嫌模版麻烦,我觉得算法如果是通用的,用模版多好 啊,大家还可以代码共享看看楼下同志们的测试结果怎么样个人感觉
ASSERT(!::IsBadWritePtr(lpC,m*n*sizeof(T)));
ASSERT(!::IsBadReadPtr(lpA,m*s*sizeof(T)));
ASSERT(!::IsBadReadPtr(lpB,s*n*sizeof(T)));
没什么用,反而会降低效率,好在你放在D板中了另外你用矩阵算的,我见过直接是矩阵展开算的,不过差不多了,都一样另外,UINT大小的矩阵,哈哈估计我的计算机是够呛,