高质量地快速图像缩放二次线性插值和三次卷积插值.docx
- 文档编号:3124375
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:34
- 大小:121.45KB
高质量地快速图像缩放二次线性插值和三次卷积插值.docx
《高质量地快速图像缩放二次线性插值和三次卷积插值.docx》由会员分享,可在线阅读,更多相关《高质量地快速图像缩放二次线性插值和三次卷积插值.docx(34页珍藏版)》请在冰豆网上搜索。
高质量地快速图像缩放二次线性插值和三次卷积插值
高质量的快速的图像缩放——二次线性插值和三次卷积插值
限制条件:
为了便于讨论,这里只处理32bit的ARGB颜色;
代码使用C++;涉及到汇编优化的时候假定为x86平台;使用的编译器为vc2005;
为了代码的可读性,没有加入异常处理代码;
测试使用的CPU为AMD64x24200+(2.37G)和IntelCore24400(2.00G);
速度测试说明:
只测试内存数据到内存数据的缩放
测试图片都是800*600缩放到1024*768;fps表示每秒钟的帧数,值越大表示函数越快
A:
近邻取样插值、二次线性插值、三次卷积插值缩放效果对比
原图近邻取样缩放到0.6倍近邻取样缩放到1.6倍
二次线性插值缩放到0.6倍二次线性插值缩放到1.6倍
三次卷积插值缩放到0.6倍三次卷积插值缩放到1.6倍
原图近邻取样缩放到8倍二次线性插值缩放到8倍三次卷积插值缩放到8倍二次线性插值(近似公式)
近邻取样插值缩放简单、速度快,但很多时候缩放出的图片质量比较差(特别是对于人物、景色等),图片的缩放有比较明显的锯齿;使用二次或更高次插值有利于改善缩放效果;
B:
首先定义图像数据结构:
#defineasm__asm
typedefunsignedcharTUInt8;//[0..255]
structTARGB32//32bitcolor
{
TUInt8b,g,r,a;//aisalpha
};
structTPicRegion//一块颜色数据区的描述,便于参数传递
{
TARGB32*pdata;//颜色数据首地址
longbyte_width;//一行数据的物理宽度(字节宽度);
//abs(byte_width)有可能大于等于width*sizeof(TARGB32);
longwidth;//像素宽度
longheight;//像素高度
};
//那么访问一个点的函数可以写为:
inlineTARGB32&Pixels(constTPicRegion&pic,constlongx,constlongy)
{
return((TARGB32*)((TUInt8*)pic.pdata+pic.byte_width*y))[x];
}
二次线性差值
C:
二次线性插值缩放原理和公式图示:
缩放后图片原图片
(宽DW,高DH)(宽SW,高SH)
缩放映射原理:
(Sx-0)/(SW-0)=(Dx-0)/(DW-0)(Sy-0)/(SH-0)=(Dy-0)/(DH-0)
=>Sx=Dx*SW/DWSy=Dy*SH/DH
聚焦看看(Sx,Sy)坐标点(Sx,Sy为浮点数)附近的情况;
对于近邻取样插值的缩放算法,直接取Color0颜色作为缩放后点的颜色;
二次线性插值需要考虑(Sx,Sy)坐标点周围的4个颜色值Color0\Color1\Color2\Color3,
把(Sx,Sy)到A\B\C\D坐标点的距离作为系数来把4个颜色混合出缩放后点的颜色;
(u=Sx-floor(Sx);v=Sy-floor(Sy);说明:
floor函数的返回值为小于等于参数的最大整数)
二次线性插值公式为:
tmpColor0=Color0*(1-u)+Color2*u;
tmpColor1=Color1*(1-u)+Color3*u;
DstColor=tmpColor0*(1-v)+tmpColor2*v;
展开公式为:
pm0=(1-u)*(1-v);
pm1=v*(1-u);
pm2=u*(1-v);
pm3=u*v;
则颜色混合公式为:
DstColor=Color0*pm0+Color1*pm1+Color2*pm2+Color3*pm3;
参数函数图示:
二次线性插值函数图示
对于上面的公式,它将图片向右下各移动了半个像素,需要对此做一个修正;
=>Sx=(Dx+0.5)*SW/DW-0.5;Sy=(Dy+0.5)*SH/DH-0.5;
而实际的程序,还需要考虑到边界(访问源图片可能超界)对于算法的影响,边界的处理可能有各种方案(不处理边界或边界回绕或边界饱和或边界映射或用背景颜色混合等;文章中默认使用边界饱和来处理超界);
比如:
边界饱和函数:
//访问一个点的函数,(x,y)坐标可能超出图片边界;//边界处理模式:
边界饱和
inlineTARGB32Pixels_Bound(constTPicRegion&pic,longx,longy)
{
//assert((pic.width>0)&&(pic.height>0));
boolIsInPic=true;
if(x<0){x=0;IsInPic=false;}
elseif(x>=pic.width){x=pic.width-1;IsInPic=false;}
if(y<0){y=0;IsInPic=false;}
elseif(y>=pic.height){y=pic.height-1;IsInPic=false;}
TARGB32result=Pixels(pic,x,y);
if(!
IsInPic)result.a=0;
returnresult;
}
D:
二次线性插值缩放算法的一个参考实现:
PicZoom_BilInear0
该函数并没有做什么优化,只是一个简单的浮点实现版本;
inlinevoidBilinear0(constTPicRegion&pic,floatfx,floatfy,
TARGB32*result)
{
longx=(long)fx;if(x>fx)--x;//x=floor(fx);
longy=(long)fy;if(y>fy)--y;//y=floor(fy);
TARGB32Color0=Pixels_Bound(pic,x,y);
TARGB32Color2=Pixels_Bound(pic,x+1,y);
TARGB32Color1=Pixels_Bound(pic,x,y+1);
TARGB32Color3=Pixels_Bound(pic,x+1,y+1);
floatu=fx-x;
floatv=fy-y;
floatpm3=u*v;
floatpm2=u*(1-v);
floatpm1=v*(1-u);
floatpm0=(1-u)*(1-v);
result->a=(pm0*Color0.a+pm1*Color1.a+pm2*Color2.a+pm3*Color3.a);
result->r=(pm0*Color0.r+pm1*Color1.r+pm2*Color2.r+pm3*Color3.r);
result->g=(pm0*Color0.g+pm1*Color1.g+pm2*Color2.g+pm3*Color3.g);
result->b=(pm0*Color0.b+pm1*Color1.b+pm2*Color2.b+pm3*Color3.b);
}
voidPicZoom_Bilinear0(constTPicRegion&Dst,constTPicRegion&Src)
{
if((0==Dst.width)||(0==Dst.height)
||(0==Src.width)||(0==Src.height))return;
unsignedlongdst_width=Dst.width;
TARGB32*pDstLine=Dst.pdata;
for(unsignedlongy=0;y { floatsrcy=(y+0.4999999)*Src.height/Dst.height-0.5; for(unsignedlongx=0;x { floatsrcx=(x+0.4999999)*Src.width/Dst.width-0.5; Bilinear0(Src,srcx,srcy,&pDstLine[x]); } ((TUInt8*&)pDstLine)+=Dst.byte_width; } } //////////////////////////////////////////////////////////////////////////////// //速度测试: //============================================================================== //PicZoom_BilInear08.3fps //////////////////////////////////////////////////////////////////////////////// E: 浮点计算改为定点数实现: PicZoom_BilInear1 inlinevoidBilinear1(constTPicRegion&pic,constlongx_16, constlongy_16,TARGB32*result) { longx=x_16>>16; longy=y_16>>16; TARGB32Color0=Pixels_Bound(pic,x,y); TARGB32Color2=Pixels_Bound(pic,x+1,y); TARGB32Color1=Pixels_Bound(pic,x,y+1); TARGB32Color3=Pixels_Bound(pic,x+1,y+1); unsignedlongu_8=(x_16&0xFFFF)>>8; unsignedlongv_8=(y_16&0xFFFF)>>8; unsignedlongpm3_16=(u_8*v_8); unsignedlongpm2_16=(u_8*(unsignedlong)(255-v_8)); unsignedlongpm1_16=(v_8*(unsignedlong)(255-u_8)); unsignedlongpm0_16=((255-u_8)*(255-v_8)); result->a= ((pm0_16*Color0.a+pm1_16*Color1.a+pm2_16*Color2.a+pm3_16*Color3.a)>>16); result->r= ((pm0_16*Color0.r+pm1_16*Color1.r+pm2_16*Color2.r+pm3_16*Color3.r)>>16); result->g= ((pm0_16*Color0.g+pm1_16*Color1.g+pm2_16*Color2.g+pm3_16*Color3.g)>>16); result->b= ((pm0_16*Color0.b+pm1_16*C
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 质量 快速 图像 缩放 二次 线性插值 三次 卷积
![提示](https://static.bdocx.com/images/bang_tan.gif)