VB图像处理之二次线性插值的应用
来源:Linuxdby.com
作者:Webmaster
时间:2007-06-05
点击:
[ 收藏] [ 投稿]
上次讲到了用DIB方法来获取图像的像素。从这次开始将如果运用已经得到的像素来处理图像。
图像插值放大的方法有很多,最主要的有二次线性插值和三次线性插值这两种。这次我把自己的程序中所用的二次线性插值的算法公布给大家,希望对各位要使用VB写类似程序的朋友有所帮助。
程序中用到的API、数据类型、全局变量的定义请参考上一篇:《VB实现图像在数据库的存储与显示》
->PublicSubZoomImage(ByValOutPutWidthAsLong,ByValOutputHeightAsLong) DimIAsLong DimLAsLong DimXAsLong DimYAsLong DimXbAsLong DimYbAsLong DimXeAsLong DimYeAsLong DimMAsInteger DimNAsInteger DimCurRAsLong DimCurGAsLong DimCurBAsLong DimNxtRAsInteger DimNxtGAsInteger DimNxtBAsInteger DimDRAsSingle DimDGAsSingle DimDBAsSingle DimDRtAsSingle DimDGtAsSingle DimDBtAsSingle DimXratioAsSingle DimYratioAsSingle DimCurStepAsSingle DimNxtStepAsSingle DimNegNAsSingle
OnErrorGoToErrLine IfNotCanZoomThenExitSub Done=False
OutPutWid=OutPutWidth-1 OutPutHei=OutputHeight-1 I=(Bits\8)-1 ReDimColTmp(I,InPutWid,OutPutHei)'先从Y方向进行缩放处理,结果保存在此中间数组内 ReDimColOut(I,OutPutWid,OutPutHei) Xratio=OutPutWid/InPutWid Yratio=OutPutHei/InPutHei
TimeZoom=timeGetTime
NegN=1/Int(Yratio 1) ForX=0ToInPutWid CurR=ColVal(0,X,0) CurG=ColVal(1,X,0) CurB=ColVal(2,X,0) CurStep=0 NxtStep=0 ForY=0ToInPutHei-1 NxtStep=CurStep Yratio Yb=CurStep Ye=NxtStep N=Ye-Yb ColTmp(0,X,Yb)=CurR ColTmp(1,X,Yb)=CurG ColTmp(2,X,Yb)=CurB M=Y 1 NxtR=ColVal(0,X,M) NxtG=ColVal(1,X,M) NxtB=ColVal(2,X,M) IfN>1Then DRt=(NxtR-CurR)*NegN DGt=(NxtG-CurG)*NegN DBt=(NxtB-CurB)*NegN DR=0 DG=0 DB=0 ForL=Yb 1ToYe-1 DR=DR DRt DG=DG DGt DB=DB DBt ColTmp(0,X,L)=CurR DR ColTmp(1,X,L)=CurG DG ColTmp(2,X,L)=CurB DB Next EndIf CurStep=NxtStep CurR=NxtR CurG=NxtG CurB=NxtB Next ColTmp(0,X,OutPutHei)=NxtR ColTmp(1,X,OutPutHei)=NxtG ColTmp(2,X,OutPutHei)=NxtB Next
NegN=1/Int(Xratio 1) ForY=0ToOutPutHei CurR=ColTmp(0,0,Y) CurG=ColTmp(1,0,Y) CurB=ColTmp(2,0,Y) CurStep=0 NxtStep=0 ForX=0ToInPutWid-1 NxtStep=CurStep Xratio Xb=CurStep Xe=NxtStep N=Xe-Xb ColOut(0,Xb,Y)=CurR ColOut(1,Xb,Y)=CurG ColOut(2,Xb,Y)=CurB M=X 1 NxtR=ColTmp(0,M,Y) NxtG=ColTmp(1,M,Y) NxtB=ColTmp(2,M,Y) IfN>1Then DRt=(NxtR-CurR)*NegN DGt=(NxtG-CurG)*NegN DBt=(NxtB-CurB)*NegN DR=0 DG=0 DB=0 ForL=Xb 1ToXe-1 DR=DR DRt DG=DG DGt DB=DB DBt ColOut(0,L,Y)=CurR DR ColOut(1,L,Y)=CurG DG ColOut(2,L,Y)=CurB DB Next EndIf CurStep=NxtStep CurR=NxtR CurG=NxtG CurB=NxtB Next ColOut(0,OutPutWid,Y)=NxtR ColOut(1,OutPutWid,Y)=NxtG ColOut(2,OutPutWid,Y)=NxtB Next
Done=True TimeZoom=timeGetTime-TimeZoom CanPut=True ExitSub ErrLine: MsgBoxErr.Description EndSub-> 全局变量定义:
->DimColTmp()AsByte'用于保存插值中间变量 DimOutPutHeiAsLong'要插值的目标高度 DimOutPutWidAsLong'要插值的目标宽度 PublicTimeZoomAsLong'插值运算使用的时间-> 简单解释一下关于二次线性插值算法。
(为了说明算法本身,我们只计算这个图片的红色分量,因为红绿蓝三种颜色的计算方法完全相同)
假设我们有一个很简单的图片,图片只有4个像素(2*2)
现在我们要把这个图片插值到9个像素:3*3
其中大写的字母代表原来的像素,小写字母代表插值得到的新像素。
想必看到这个图,大家心里已经有了这个算法了。
->ab=(A B)/2 cd=(C D)/2 ac=(A C)/2 bd=(B D)/2 abcd=(ab cd)/2=(A B C D)/4-> 推导:
->ab=A (B-A)/2 cd=C (D-C)/2 ...-> 很简单,对吧,先从一个方向把只涉及两个原始像素的新像素算出来。我们这里假定先计算水平方向。而在算垂直方向的插值的时候,因为ab和cd已经在前面算好了,所以abcd的计算也和计算ac和bd没有任何区别了。
有可能为有朋友已经想到把原来的图像插值到4*4或5*5的方法了。
->Aab1ab2B ac1ab1cd11ab2cd21bd1 ac2ab1cd12ab2cd22bd2 Ccd1cd2D-> 推导:
->ab1=A (B-A)*1/3 ab2=A (B-A)*2/3=ab1 (B-A)/3 cd1=C (D-C)*1/3 cd1=C (D-C)*2/3=cd1 (D-C)/3 ...-> 以A和B为例,先求出原始像素的差(A-B)再算出每一步的递增量(A-B)/3;然后每一个新的点就是在前面那个点的值加上这个递增量就是了。
如果您对本文有任何疑问或者建议,请到讨论区发表您的意见:
>>
论坛入口 <<
上一篇:VB图像处理之几个常用滤镜的实现 下一篇:VB实现图像在数据库的存储与显示
【文章评论】
【收藏本文】
【推荐好友】
【打印本文】
【我要投稿】 【论坛讨论】
更多相关文章
|
|