prrsw的个人博客分享 http://blog.sciencenet.cn/u/prrsw

博文

Visual Basic与图像处理11

已有 3084 次阅读 2012-10-11 11:30 |系统分类:教学心得|关键词:学者| Visual, Basic与图像处理

Visual Basic与图像处理()

8、灰度拉伸

灰度拉伸是将图像中不同灰度等级按照预定的方式进行拉伸,从实质上来说灰度拉伸是灰度线性变换的一种延伸,当然也不完全等同于灰度线性变换,而是对灰度等级进行分段,然后分别进行线性变换。灰度拉伸可以用下面的函数表达式表示:

式中(x1, y1)(x2, y2)是灰度拉伸中两个转折点的坐标,如下图中的AB两点。

相比于线性变换,灰度拉伸可以更灵活更改图像的灰度,可以根据需要选择性的变换某个灰度等级范围内的像素点。在本例中,采用图形化控制的方法设定上述两个转折点,这里涉及了一个平时称为“橡皮筋”的技术,在网络上有很多介绍橡皮筋技术的文章,在Visual Basic中利用DrawMode属性可以非常便捷的实现所谓的橡皮筋效果。在本例中专门放置了一个用于设定转折点的PictureBox控件,在PictureBox中鼠标左键按下时,选择第一个转折点,然后鼠标拖动到第二个转折点松开鼠标左键,当鼠标左键再次按下时,将PictureBox清空,重新设置转折点。整个系统的运行界面如下:

其中灰度拉伸按钮对应的代码如下:

Private Sub cmdGrayStrech_Click()

    Dim i As Integer, j As Integer

    Dim PixelValue As Long

    Dim r As Integer, g As Integer, b As Integer

    Dim GrayValue As Integer

    Dim Map(255) As Integer '采用映射模式计算拉伸后的灰度

    Dim k(2) As Single, t(2) As Integer '存放三条直线的斜率和截距

    Dim NGrayValue As Integer

   

    ThresholdValue = Val(txtThreshold)

    '设置目标图像的高度和宽度

    DestImHeight = SourceImHeight

    DestImWidth = SourceImWidth

   

    '设置目标PictureBox的大小

    PicDest.Height = DestImHeight

    PicDest.Width = DestImWidth

   

    '第一条直线斜率和截距

    k(0) = (255 - StartPY - 0) / (StartPX - 0)

    t(0) = 0

   

    For i = 0 To StartPX

        Map(i) = i * k(0) + t(0)

    Next i

   

    '第二条直线斜率和截距

    k(1) = ((255 - EndPY) - (255 - StartPY)) / (EndPX - StartPX)

    t(1) = (255 - EndPY) - k(1) * EndPX

   

    For i = StartPX + 1 To EndPX

        Map(i) = i * k(1) + t(1)

    Next i

   

   

     '第二条直线斜率和截距

    k(2) = (255 - (255 - EndPY)) / (255 - EndPX)

    t(2) = (255 - EndPY) - k(2) * EndPX

   

    For i = EndPX + 1 To 255

        Map(i) = i * k(2) + t(2)

    Next i

   

   

    '图像的灰度拉伸变换

    For i = 0 To SourceImHeight - 1

        For j = 0 To SourceImWidth - 1

               PixelValue = PicSource.Point(j, i)

               r = PixelValue Mod 256

               g = (PixelValue 256) Mod 256

               b = PixelValue 65536

              '插入图像处理的过程,对r, g, b进行处理

               GrayValue = 0.3 * r + 0.59 * g + 0.11 * b

              

               NGrayValue = Map(GrayValue)

              

               PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue)

        Next j

    Next i

End Sub

这里涉及的数组映射也是经常使用的一种技术,可以有效的提高软件的运行速度。

实现橡皮筋效应及转折点设置的代码分为三个部分,首先是鼠标左键按下,确定第一个转折点,然后是鼠标拖动时,实现的橡皮筋效果,最后鼠标左键抬起时,确定第二个转折点。第一个转折点和第二个转折点分别用窗口级变量来表示,分别是StartPX, StartPY, EndPX, EndPY,以便于后面计算直线的斜率和截距。

鼠标左键按下的代码如下:

Private Sub PicDraw_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

    If Button = vbLeftButton Then

        'PictureBox清空

        PicDraw.Cls

        '画个边框

        PicDraw.Line (0, 0)-(0, 255), RGB(255, 255, 255)

        PicDraw.Line (0, 0)-(255, 0), RGB(255, 255, 255)

        PicDraw.Line (0, 255)-(255, 255), RGB(255, 255, 255)

        PicDraw.Line (255, 0)-(255, 255), RGB(255, 255, 255)

       

        '鼠标左键已经按下

        Flag = True

        StartPX = X

        StartPY = Y

        txtFirst = "(" & Str(StartPX) & ", " & Str(255 - StartPY) & ")"

       

        Label8.Left = StartPX

        Label8.Top = StartPY

        Label8.Caption = txtFirst

       

        PicDraw.Line (0, PicDraw.Height - 1)-(StartPX, StartPY), RGB(255, 255, 0)

        PicDraw.Line (StartPX, PicDraw.Height - 1)-(StartPX, StartPY), RGB(255, 0, 0)

        PicDraw.Line (0, StartPY)-(StartPX, StartPY), RGB(255, 0, 0)

        EndPX = X

        EndPY = Y

    End If

End Sub

由于DrawMode模式是异或,因此设置颜色时需要根据互补色。

 

鼠标拖动的代码如下,注意观察如何实现橡皮筋效果:

Private Sub PicDraw_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

    If Flag = True Then

        '擦去前面的线条

        PicDraw.Line (StartPX, StartPY)-(EndPX, EndPY), RGB(255, 255, 0) '由于取的是异或,为了画蓝色的线,将前面两个量满置

       

        EndPX = X

        EndPY = Y

        '画上新的线条,实现橡皮筋效果

        PicDraw.Line (StartPX, StartPY)-(EndPX, EndPY), RGB(255, 255, 0)

    End If

End Sub

 

鼠标左键抬起的时候,确定第二个转折点,代码如下:

Private Sub PicDraw_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)

    EndPX = X

    EndPY = Y

    txtSecond = "(" & Str(EndPX) & ", " & Str(255 - EndPY) & ")"

   

    Label9.Left = EndPX

    Label9.Top = EndPY

    Label9.Caption = txtSecond

       

    PicDraw.Line (EndPX, EndPY)-(PicDraw.Width - 1, 0), RGB(255, 255, 0)

    PicDraw.Line (PicDraw.Width - 1, EndPY)-(EndPX, EndPY), RGB(255, 0, 0)

    PicDraw.Line (EndPX, 0)-(EndPX, EndPY), RGB(255, 0, 0)

   

    Flag = False

End Sub

 

需要注意的是DrawMode设置为Xor Pen表示在同一位置画同样的线时,将把原来的线擦除,从而可以实现橡皮筋效应,在窗体窗体时对DrawMode进行设置,代码如下:

Private Sub Form_Load()

    PicDraw.DrawMode = 7 ' vbXorPen  

End Sub



https://m.sciencenet.cn/blog-648901-621382.html

上一篇:Visual Basic与图像处理10
下一篇:Visual Basic与图像处理12

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-18 22:08

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部