## CSDN博客

### VB图像处理，（二）二次线性插值的应用

《VB图像处理，（一）像素的获取和输出 》

Public Sub ZoomImage(ByVal OutPutWidth As Long, ByVal OutputHeight As Long)
Dim I As Long
Dim L As Long
Dim X As Long
Dim Y As Long
Dim Xb As Long
Dim Yb As Long
Dim Xe As Long
Dim Ye As Long
Dim M As Integer
Dim N As Integer
Dim CurR As Long
Dim CurG As Long
Dim CurB As Long
Dim NxtR As Integer
Dim NxtG As Integer
Dim NxtB As Integer
Dim DR As Single
Dim DG As Single
Dim DB As Single
Dim DRt As Single
Dim DGt As Single
Dim DBt As Single
Dim Xratio As Single
Dim Yratio As Single
Dim CurStep As Single
Dim NxtStep As Single
Dim NegN As Single

On Error GoTo ErrLine
If Not CanZoom Then Exit Sub
Done = False

OutPutWid = OutPutWidth - 1
OutPutHei = OutputHeight - 1
I = (Bits / 8) - 1
ReDim ColTmp(I, InPutWid, OutPutHei) '先从Y方向进行缩放处理，结果保存在此中间数组内
ReDim ColOut(I, OutPutWid, OutPutHei)
Xratio = OutPutWid / InPutWid
Yratio = OutPutHei / InPutHei

TimeZoom = timeGetTime

NegN = 1 / Int(Yratio + 1)
For X = 0 To InPutWid
CurR = ColVal(0, X, 0)
CurG = ColVal(1, X, 0)
CurB = ColVal(2, X, 0)
CurStep = 0
NxtStep = 0
For Y = 0 To InPutHei - 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)
If N > 1 Then
DRt = (NxtR - CurR) * NegN
DGt = (NxtG - CurG) * NegN
DBt = (NxtB - CurB) * NegN
DR = 0
DG = 0
DB = 0
For L = Yb + 1 To Ye - 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
End If
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)
For Y = 0 To OutPutHei
CurR = ColTmp(0, 0, Y)
CurG = ColTmp(1, 0, Y)
CurB = ColTmp(2, 0, Y)
CurStep = 0
NxtStep = 0
For X = 0 To InPutWid - 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)
If N > 1 Then
DRt = (NxtR - CurR) * NegN
DGt = (NxtG - CurG) * NegN
DBt = (NxtB - CurB) * NegN
DR = 0
DG = 0
DB = 0
For L = Xb + 1 To Xe - 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
End If
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
Exit Sub
ErrLine:
MsgBox Err.Description
End Sub

Dim ColTmp() As Byte      '用于保存插值中间变量
Dim OutPutHei As Long    '要插值的目标高度
Dim OutPutWid As Long   '要插值的目标宽度
Public TimeZoom As Long '插值运算使用的时间

（为了说明算法本身，我们只计算这个图片的红色分量，因为红绿蓝三种颜色的计算方法完全相同）

A  B
C  D

A    ab      B
ac   abcd   bd
C    cd      D

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

cd=C +(D-C) / 2
...

A      ab1           ab2              B
ac1   ab1cd11   ab2cd21       bd1
ac2   ab1cd12   ab2cd22       bd2
C      cd1           cd2               D

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
...

ab1 = A + DRt = 100+51.7 =151
ab2 = ab1 + DRt = 151+51.7 = 202

A B
C D

A ab1...abN B
C cd1...cdN D

A      ab1...abN    B
ac1    .............     db1
...       ............      ...
acN  ..............      bdN
C      cd1...cdN    D

sub command1_click()
With picture1
.ScaleMode=3
.BorderStyle=0
DibGet .hdc ,0 , 0 , .scalewidth , .scaleheight
ZoomImage , .scalewidth * 2 , .scaleheight * 2
End With
picture2.AutoRedraw=True
DibPut picture2.hdc
picture2.refresh
end sub

（这里只是说了我自己在写程序的时候用到的方法，存在很多的不足。并且因为在贴上来的时候作了部分修改，可能会存在部分错误，请各位高手不吝赐教，将您用到的更好的方法提供一下，我将不胜感激。）

VB图像处理，（七）一种邻近均值滤波器的算法介绍（去尘，去噪音）

0 0