效果并不理想,在图像梯度大的地方很容易出现噪声干扰。
运行时间很长,时效性差
void Cimage2View::ThreeLinearInterpolation(unsigned char** SourceData, int Width , int Height , int Band ,
unsigned char** NewData, int NewWidth , int NewHeight , float Scale)
{
/*
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是圆周率——π)
*/
//(x0,y0)为目标文件按比例缩放之后的点
float x0;
float y0;
//左上角的点(x1,y1)
int x1;
int y1;
//与左上角点的浮点差值
float u ;
float v;
//保存计算的中间变量
float temp[4];
for(int b = 0;b < Band;++b)
{
for(int x = 0;x < NewHeight;++x)
{
for(int y = 0;y < NewWidth;++y)
{
x0 = x / Scale;
y0 = y / Scale;
x1 = int(x0);
y1 = int(y0);
u = x0 - x1;
v = y0 - y1;
if((x1 - 1) < 0 || (y1 - 1) < 0 || (x1 + 3) > Height || (y1 + 3) > Width)
continue;
temp[0] = SourceData[b][(x1 - 1) * Width + (y1 - 1)] * S(u + 1)
+ SourceData[b][x1 * Width + (y1 - 1)] * S(u)
+ SourceData[b][(x1 + 1) * Width + (y1 - 1)] * S(u - 1)
+ SourceData[b][(x1 + 2) * Width + (y1 - 1)] * S(u - 2);
temp[1] = SourceData[b][(x1 - 1) * Width + y1] * S(u + 1)
+ SourceData[b][x1 * Width + y1] * S(u)
+ SourceData[b][(x1 + 1) * Width + y1] * S(u - 1)
+ SourceData[b][(x1 + 2) * Width + y1] * S(u - 2);
temp[2] = SourceData[b][(x1 - 1) * Width + (y1 + 1)] * S(u + 1)
+ SourceData[b][x1 * Width + (y1 + 1)] * S(u)
+ SourceData[b][(x1 + 1) * Width + (y1 + 1)] * S(u - 1)
+ SourceData[b][(x1 + 2) * Width + (y1 + 1)] * S(u - 2);
temp[3] = SourceData[b][(x1 - 1) * Width + (y1 + 2)] * S(u + 1)
+ SourceData[b][x1 * Width + (y1 + 2)] * S(u)
+ SourceData[b][(x1 + 1) * Width + (y1 + 2)] * S(u - 1)
+ SourceData[b][(x1 + 2) * Width + (y1 + 2)] * S(u - 2);
NewData[b][x * NewWidth + y] = temp[0] * S(v + 1) + temp[1] * S(v)
+ temp[2] * S(v - 1) + temp[3] * S(v - 2);
}
}
}
}
//S(x)是对 Sin(x*Pi)/x 的逼近(Pi是圆周率——π)
float Cimage2View::S(float x)
{
float returnValue;
if(abs(x) >= 0 && abs(x) < 1)
returnValue = 1 - 2 * abs(x) * abs(x) + abs(x) * abs(x) * abs(x);
else if(abs(x) >= 1 && abs(x) < 2)
returnValue = 4 - 8 * abs(x) + 5 * abs(x) * abs(x) - abs(x) * abs(x) * abs(x);
else if(abs(x) >= 2)
returnValue = 0;
else
{
MessageBox("S(x)输入有误");
}
return returnValue;
}