安全中国首页 > 编程中心 > VB编程
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

VB图像处理之二次线性插值的应用(图)

更新时间:2008-5-29 17:43:20
责任编辑:hzz
热 点:
上次讲到了用DIB方法来获取图像的像素。从这次开始将如果运用已经得到的像素来处理图像。

   图像插值放大的方法有很多,最主要的有二次线性插值和三次线性插值这两种。这次我把自己的程序中所用的二次线性插值的算法公布给大家,希望对各位要使用VB写类似程序的朋友有所帮助。

   程序中用到的API、数据类型、全局变量的定义请参考上一篇:《 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 '插值运算使用的时间

   简单解释一下关于二次线性插值算法。

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

   假设我们有一个很简单的图片,图片只有4个像素(2*2)

A B
C D

   现在我们要把这个图片插值到9个像素:3*3

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

   推导:

ab= A + (B-A) / 2
cd=C +(D-C) / 2
...

   很简单,对吧,先从一个方向把只涉及两个原始像素的新像素算出来。我们这里假定先计算水平方向。而在算垂直方向的插值的时候,因为ab和cd已经在前面算好了,所以abcd的计算也和计算ac和bd没有任何区别了。

   有可能为有朋友已经想到把原来的图像插值到4*4或5*5的方法了。

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

   推导:

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;然后每一个新的点就是在前面那个点的值加上这个递增量就是了。

   这里我们假设A=100, B=255 放大倍率为3,水平方向插值;先计算出原始像素的差:(B-A) = 255-100 =155

 

1 2 下一页

 
学习软件编程开发技术,推荐加入以下软件编程培训班:
易语言软件编程培训班(简单易学)  Delphi软件编程培训班  VC++软件编程培训班
VB软件编程培训班  JAVA高端编程就业研发班

学习网站开发制作技术,推荐加入以下网站开发培训班:
ASP.net网站开发项目实战班  ASP语言网站建设培训班

学习网络安全入侵防护技术,推荐加入以下技术培训班:
大型网络安全入侵防护班  网站脚本程序全方位安全检测班

学习网络管理、网吧运营维护技术(网管),推荐加入以下培训班:
大型网吧技术管理人才特训班  Linux网络嵌入架构工程师培训班

学习专项特殊技术,推荐加入以下专项技术培训班:
软件与游戏外挂脱壳破解班(逆向工程)  赚钱王道-网赚技能培训班  Flash动画设计师就业特训班

 
相关编程
一日一文章
 
一日一软件
一日一动画