网站建设| 数据库类| 图形图象| 程序设计| 现代办公| 操作系统| 考试认证| 网络技术| 软件工程| 电脑相关| 文学作品
网站开发| 网页制作| 操作系统| 图象图形| 考试认证| 数据库类| 程序设计| 硬件技术| 现代办公| 网络技术| 笑话频道
 
您的位置: 电脑书库首页-> 电脑文摘-> 程序设计-> Basic/VB类-> VB图像处理之二次线性插值的应用

VB图像处理之二次线性插值的应用
作者:佚名 来源:InterNet 加入时间:2005-1-28
相关文章
  • VB图像处理之图像的亮度对比度调整
  • VB实现文件数据对SQL Server上传下载
  • 用VB6.0编写磁盘格式化程序
  • VB图像处理之图像的色彩纠正
  • VB图像处理之铅笔画算法和木雕算法
  • VB图像处理之几个常用滤镜的实现
  • VB图像处理之像素的获取和输出
  • VB实现图像在数据库的存储与显示
  • 利用VB6.0开发基于IIS的应用程序
  • VB6中用Oracle数据控件访问Oracle
  • 相关书籍:
  • VBScript语言参考
  • VBScript函数速查手册
  • VBScript5.5脚本语言参考
  • VB上机考试综合应用题选讲
  • vb另外两套教案
  • VB光盘资料库
  • VB、C快速进阶 2.0
  • Web 对象 VB参考
  • VB编程技巧集(中)--站长推荐
  • VB编程技巧集(上)--站长推荐
  • 上次讲到了用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

      再计算出水平方向每一步的递增量:(A-B) / 3=155 / 3 = 51.7

      这里我们用一个变量DRt来记录这个递增量(这里只用红色来做例子)

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

      好了,其实二次线性算法就是这么一个东西,并不复杂。或许有写朋友会对于我给出的代码产生疑问。很简单的一个算法为什么要写这么多代码。

      其实答案很简单:为了提高速度。

      在VB中“+”和“-”永远是最快的,“*”要比“/”和“\”快。不论是什么类型的变量都是这样的。

      下面再来分析一下我的程序。

      在我的程序中把两个方向的插值分解成了两个单独的部分。

      先把

    A B
    C D

      变成:

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

      再变成:

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

      这两个方向的插值算法完全相同

      而Xratio 和Yratio 这两个变量则用来记录水平方向和垂直方向的放大倍率。所以这个过程也能够让图像缩放不按照原始的纵横比进行。

      好了,将这个模块和全局变量添加到上次建立的工程模块中。

      把按钮中的代码改成:

    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

      图像是否已经放大到原来的两倍了呢?速度不算很慢吧?

      什么?很慢?先编译成EXE再运行吧。下面是效果图:

      原图:


      二次线性插值放大5倍:


      关于二次线性插值就说到这里了,下一次将说一些基本的滤镜效果:锐化、柔化、扩散、雕刻。请大家继续关注

    [文章录入员:nancy]

    相关文章
  • VB图像处理之图像的亮度对比度调整
  • VB实现文件数据对SQL Server上传下载
  • 用VB6.0编写磁盘格式化程序
  • VB图像处理之图像的色彩纠正
  • VB图像处理之铅笔画算法和木雕算法
  • VB图像处理之几个常用滤镜的实现
  • VB图像处理之像素的获取和输出
  • VB实现图像在数据库的存储与显示
  • 利用VB6.0开发基于IIS的应用程序
  • VB6中用Oracle数据控件访问Oracle
  • 相关书籍:
  • VBScript语言参考
  • VBScript函数速查手册
  • VBScript5.5脚本语言参考
  • VB上机考试综合应用题选讲
  • vb另外两套教案
  • VB光盘资料库
  • VB、C快速进阶 2.0
  • Web 对象 VB参考
  • VB编程技巧集(中)--站长推荐
  • VB编程技巧集(上)--站长推荐
  • 本站推荐内容

    近期主机类热搜关键词:
    美国服务器 美国服务器租用 海外服务器租用 国外服务器租用

    Basic/VB类
    C/C++/VC
    C++Builder
    Basic/VB类
    Delphi/Pascal
    Java编程
    FORTRAN
    其它
    电脑教程阅读排行
    ·VB学习一点通
    ·VB设计动画时钟
    ·在Visual Basic 6....
    · 用VB6.0编写手机短信发送 ...
    ·VB实现文件数据对SQL Ser...
    ·利用Visual Basic操作...
    ·VB实现图像在数据库的存储与显示
    ·用Visual Basic6.0...
    ·Visual Basic代码优化...
    · VB中实现“无标题”窗体的移动...