转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
VB图像处理,(二)二次线性插值的应用         ★★★★

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

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1354 更新时间:2009/4/23 15:41:41

上次讲到了用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,水平方向插值
先计算出原始像素的差

[1] [2]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台