科学网

 找回密码
  注册

tag 标签: Basic与图像处理

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

Visual Basic与图像处理21
prrsw 2012-10-14 15:59
Visual Basic与图像处理21
Visual Basic 与图像处理 ( 三 ) 6 、 Roberts 微分算子 前面介绍的两种微分算子,实际上是分别求出了水平和垂直方向上的细节信息。但在实际的图像处理之中,除了特殊用途之下才会使用到方向滤波,大部分二维图像处理时,需要同时获得两个方向上的细节信息,因此需要设计各向同性的微分算子用于图像的锐化处理。 Roberts 算子一种常用的微分算子,可以满足上述要求,其计算方法可以用下面的公式进行表示: 同样上面的公式可以用下面的两个模板进行表示: 本例的运行界面如下图所示: Roberts 滤波按钮对应的代码如下: Private Sub cmdRobertsFilter_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 Temp(1, 1) As Integer Dim x As Integer, y As Integer Dim Dx As Integer, Dy As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 1 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 1 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的 Roberts 滤波 For i = 0 To SourceImHeight - 2 ' 边界像素不处理 For j = 0 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 1 For y = 0 To 1 r = sbits(i + x, j + y, 0) g = sbits(i + x, j + y, 1) b = sbits(i + x, j + y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x Dx = -Temp(0, 0) + Temp(1, 1) Dy = -Temp(0, 1) + Temp(1, 0) NGrayValue = Abs(Dx) + Abs(Dy) If NGrayValue 255 Then NGrayValue = 255 dbits(i, j, 0) = NGrayValue dbits(i, j, 1) = NGrayValue dbits(i, j, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2779 次阅读|0 个评论
Visual Basic与图像处理20
prrsw 2012-10-14 15:35
Visual Basic与图像处理20
Visual Basic 与图像处理(三) 图像的锐化处理也是图像增强的一种方法,主要是为了突出图像中的部分细节或者增强被模糊了细节。从取样规律来说,在图像分辨率不足时,所获得的像素点可以认为是周围景物亮度的平均值,这种均值效率使得图像变得模糊,可以认为这种均值处理的方法与积分效应类似,与此相对,为了强化图像细节,可以对图像进行微分处理,后面介绍的锐化处理就可以看成为各种不同的微分算法。 从数学定义来看,微分的含义就是数据的变化率,由于图像是由离散的像素点表示的,因此图像的微分就是像素点的差值,称为差分。为了便于叙述,后文在不再区分微分和差分的概念。 5 、具有方向性的一阶微分算子 为了便于理解,首先从一些最简单的微分算子将其,这类一阶微分算法的最大特点就是可以获得图像中特定方向上的灰度变化情况,在特定的纹理分析、检测方法非常有效,有时会称为方向性锐化。 (1) 水平方向的微分算子 水平方向的微分算子就是为了获得图像在水平方向上的灰度变化率,对于像素点 f(x,y) ,水平算子的定义如下: 用前面讲述过的模板的概念,水平方向微分算法可以用下面的模板进行表示: 在实际运算中,可以对上述的计算结果取绝对值处理,以避免出现负值,本例的运行界面如下: 水平微分算子按钮对应代码如下: Private Sub cmdHonSharpFilter_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 Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的均值滤波直方图统计 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Abs(Temp(0, 0) + 2 * Temp(0, 1) + Temp(0, 2) - Temp(2, 0) - 2 * Temp(2, 1) - Temp(2, 2)) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 垂直方向滤波的方法与水平方向锐化滤波的方法基本一致,只是将模板修改如下: 垂直方向滤波的界面如下: 垂直锐化滤波按钮对应的代码如下: Private Sub cmdVSharpFilter_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 Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight - 2 ' 边界像素直接不要了 DestImWidth = SourceImWidth - 2 ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的垂直锐化滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Abs(Temp(0, 0) + 2 * Temp(1, 0) + Temp(2, 0) - Temp(0, 2) - 2 * Temp(1, 2) - Temp(2, 2)) If NGrayValue 255 Then NGrayValue = 255 dbits(i - 1, j - 1, 0) = NGrayValue dbits(i - 1, j - 1, 1) = NGrayValue dbits(i - 1, j - 1, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
3216 次阅读|0 个评论
Visual Basic与图像处理19
prrsw 2012-10-12 14:47
Visual Basic与图像处理19
Visual Basic 与图像处理 ( 三 ) 4 、中值滤波 前面讲的均值滤波器等都是属于线性滤波器,容易带来图像细节的模糊,本节要讲的是一种非线性滤波器:中值滤波。中值滤波最早是有 J. W. Jukey 在 1971 年提出的一种一维信号处理技术,后来被拓展应用到二维图像处理技术之中。 所谓中值滤波,就是采用一个含有奇数个点的滑动窗口,将当前点灰度值(一般指窗口的中心点)用窗口中各点灰度值的中值来替代。由于一般采用的是奇数窗口,因此只要将各个像素点的灰度等级进行大小排序,中间的竖直就是中值;如果窗口是偶数(特殊情况)。就用排序后中间两个元素的均值来表示中值。 用前面均值滤波直接用线性方程来计算新的灰度值不一样的是,中值滤波首先要对当前窗口内的所有像素点的灰度值进行排序,一般有选择排序和冒泡排序两种方法,具体可参照相关的 Visual Basic 基础教程中的讲解,这里就不详细解释了。 中值滤波器窗口的形状有多种,有一维也有二维的,对于二维情况,中值滤波器的窗口形状和尺度对滤波结果影响也很大,因此需要根据实际的要求来选择滤波器的形状和尺寸。本例中示范一种最简单的 3 × 3 中值滤波,其余的情况读者可根据本例提供的相关代码适当修改得到,本例的运行界面如下: 3 × 3 中值滤波按钮对应的代码如下: Private Sub cmd33MedianFilter_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 x As Integer, y As Integer Dim Temp(8) As Integer, TV As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的中值滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x * 3 + y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x ' 选择排序 For x = 0 To 7 For y = x + 1 To 8 If Temp(x) Temp(y) Then TV = Temp(x) Temp(x) = Temp(y) Temp(y) = TV End If Next y Next x dbits(i, j, 0) = Temp(4) dbits(i, j, 1) = Temp(4) dbits(i, j, 2) = Temp(4) Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
3607 次阅读|0 个评论
Visual Basic与图像处理18
prrsw 2012-10-12 09:33
Visual Basic与图像处理18
Visual Basic 与图像处理(三) 3 、特殊模板 有时候利用一些特殊的模板可以达到意外的效果,利用均值滤波类似的方法,只是改变模板就可能达到特殊的效果,这里以下面一个模板为例,可以达到边缘检测的效果: 下面是系统的 运行界面: 特殊模板按钮对应的代码如下: Private Sub cmdSpecialFilter_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 Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的特殊模板滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Temp(0, 1) + Temp(1, 0) + Temp(2, 1) + Temp(1, 2) - 4 * Temp(1, 1) If NGrayValue 0 Then NGrayValue = 0 If NGrayValue 255 Then NGrayValue = 255 dbits(i, j, 0) = NGrayValue dbits(i, j, 1) = NGrayValue dbits(i, j, 2) = NGrayValue Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2670 次阅读|0 个评论
Visual Basic与图像处理17
prrsw 2012-10-12 08:17
Visual Basic与图像处理17
Visual Basic 与图像处理 ( 三 ) 2 、高斯滤波 高斯滤波与均值滤波方法接近,只是采用的模板不一样,均值滤波的模板中每个像素点权重是相等,而高斯滤波认为当前像素点的权重最大,距离越远的像素点在滤波结果中所占的权重越小,最常见的 3 × 3 高斯滤波器模板如下: 之所以称为高斯滤波,是因为上述模板是采样二维高斯函数得到的,下图就是 3 × 3 高斯滤波的运行界面: 3 × 3 高斯滤波按钮对应的代码如下: Private Sub cmd33GaussianFilter_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 Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的高斯滤波 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Temp(0, 0) + Temp(0, 1) * 2 + Temp(0, 2) + Temp(1, 0) * 2 + Temp(1, 1) * 4 + Temp(1, 2) * 2 + Temp(2, 0) + Temp(2, 1) * 2 + Temp(2, 2) dbits(i, j, 0) = NGrayValue / 16 dbits(i, j, 1) = NGrayValue / 16 dbits(i, j, 2) = NGrayValue / 16 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 5 × 5 高斯滤波器模板如下: 其滤波方法与前面介绍的方法一致,该部分运行界面如下: 5 × 5 高斯滤波按钮对应的代码如下: Private Sub cmd55GaussianFilter_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 Temp(4, 4) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的高斯滤波 For i = 2 To SourceImHeight - 3 ' 边界像素不处理 For j = 2 To SourceImWidth - 3 NGrayValue = 0 For x = 0 To 4 For y = 0 To 4 r = sbits(i + 2 - x, j + 2 - y, 0) g = sbits(i + 2 - x, j + 2 - y, 1) b = sbits(i + 2 - x, j + 2 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b Next y Next x NGrayValue = Temp(0, 0) + Temp(0, 1) * 2 + Temp(0, 2) * 4 + Temp(0, 3) * 2 + Temp(0, 4) ' 第一行 NGrayValue = NGrayValue + Temp(1, 0) * 2 + Temp(1, 1) * 4 + Temp(1, 2) * 8 + Temp(1, 3) * 4 + Temp(1, 4) * 2 ' 第二行 NGrayValue = NGrayValue + Temp(2, 0) * 4 + Temp(2, 1) * 8 + Temp(2, 2) * 16 + Temp(2, 3) * 8 + Temp(2, 4) * 4 ' 第三行 NGrayValue = NGrayValue + Temp(3, 0) * 2 + Temp(3, 1) * 4 + Temp(3, 2) * 8 + Temp(3, 3) * 4 + Temp(3, 4) * 2 ' 第四行 NGrayValue = NGrayValue + Temp(4, 0) + Temp(4, 1) * 2 + Temp(4, 2) * 4 + Temp(4, 3) * 2 + Temp(4, 4) ' 第五行 dbits(i, j, 0) = NGrayValue / 100 dbits(i, j, 1) = NGrayValue / 100 dbits(i, j, 2) = NGrayValue / 100 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub
2912 次阅读|0 个评论
Visual Basic与图像处理16
热度 1 prrsw 2012-10-11 18:54
Visual Basic与图像处理16
Visual Basic 与图像处理 ( 三 ) 从本节开始介绍图像增强的知识,在图像的传送和转换,比如复制、扫描等过程中总要造成图像品质的下降,因此需要提供一定的方法对这些降质的图像进行改善处理。常用的一种方法就是将图像中感兴趣的特征进行选择性的突出,减弱次要信息,当然这种方法虽然能提高图像的可读性,但是改善后的图像不一定逼近原始图像,比如突出目标的轮廓、衰减图像的各种噪声,通常把这类方法称为图像增强技术。当然还有一类方法也能改善图像的质量,称为图像复原,这里先不进行阐述。 图像增强的方法通常可分为两大类,第一类就是在空间域内对图像的像素点灰度值直接进行处理,比如区域内进行均值、中值滤波;第二类方法是在频域内进行滤波,即将图像变换到频域,在频域内对图像进行某种运算增强,再变换回空间域,这部分内容在以后也会讲述到。本章讲述的是第一类方法。 1、 均值滤波 均值滤波是图像增强中最简单的一类,主要是为了减少图像中的噪声信号,常见的有 3 × 3 , 5 × 5 均值滤波,高斯模板滤波等,首先从最简单的 3 × 3 均值滤波开始讲起。 所谓 3 × 3 均值滤波就是将原图像中每个人像素点的灰度值与其八邻域的八个像素点的灰度值累加,将求得的平均值作为新图像中该像素点的均值,可以用下面的简单模板表示这种滤波方法: 均值滤波中要考虑的是边界像素的处理,最简单的一种处理方法是边界像素不作相应的处理,当然也有其他的处理方法,比如在图像周围补充一些像素,本例中采用边界像素直接复制的方法,系统的运行界面如下: 3 × 3 均值滤波按钮对应的代码如下: Private Sub cmdGrayEqua_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 Temp(2, 2) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的均值滤波直方图统计 For i = 1 To SourceImHeight - 2 ' 边界像素不处理 For j = 1 To SourceImWidth - 2 NGrayValue = 0 For x = 0 To 2 For y = 0 To 2 r = sbits(i + 1 - x, j + 1 - y, 0) g = sbits(i + 1 - x, j + 1 - y, 1) b = sbits(i + 1 - x, j + 1 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = NGrayValue + Temp(x, y) Next y Next x dbits(i, j, 0) = NGrayValue / 9 dbits(i, j, 1) = NGrayValue / 9 dbits(i, j, 2) = NGrayValue / 9 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 5 × 5 均值滤波方法与此类似,只是将模板扩大,改变其中的几句话即可,代码如下: Private Sub cmd55MeanFilter_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 Temp(4, 4) As Integer Dim x As Integer, y As Integer Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 dbits = sbits ' 数组的直接复制,只有数组维数完全一样才可以 ' 图像的均值滤波直方图统计 For i = 2 To SourceImHeight - 3 ' 边界像素不处理 For j = 2 To SourceImWidth - 3 NGrayValue = 0 For x = 0 To 4 For y = 0 To 4 r = sbits(i + 2 - x, j + 2 - y, 0) g = sbits(i + 2 - x, j + 2 - y, 1) b = sbits(i + 2 - x, j + 2 - y, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 Temp(x, y) = 0.3 * r + 0.59 * g + 0.11 * b NGrayValue = NGrayValue + Temp(x, y) Next y Next x dbits(i, j, 0) = NGrayValue / 25 dbits(i, j, 1) = NGrayValue / 25 dbits(i, j, 2) = NGrayValue / 25 Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 对应的软件运行界面如下: 从上述两个图可以看出,无论是 3 × 3 均值滤波,还是 5 × 5 均值滤波,都在一定程度上使得图像变得模糊,也就是说在滤除噪声信号的同时,也损失了图像的部分细节信号。
2910 次阅读|1 个评论
Visual Basic与图像处理15
prrsw 2012-10-11 16:12
Visual Basic 与图像处理(三) 通过动态数组减少 Point 方法的使用次数,可以有效的提高图像处理的速度, C 系列语言之所以在处理图像的时候速度较快,其实很大原因就是因为是从内存中直接读取图像数据。如果能完全放弃使用 Point 和 PSet 方法,直接获得图像数据,那么 Visual Basic 与 C 系列语言处理图像的速度并无明显差异,一种方法是直接读取文件的方法,对于初学者,还是不建议使用,因此没有必要,如果需要可以直接参考文件读取和写入的方法即可。这里推荐一种通过 API 函数直接完成图像读写的方法,主要涉及这样几个 API 函数: (1) 从 PictureBox 读入图像数据到数组中,用于取代 Point 方法。 Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long (2) 将数组数据直接映射到 PictureBox 中,用于取代 PSet 方法。 Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long (3) 获得控件句柄 Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long 为了便于对图像进行操作,自定义了一个数据类型 BIPMAP ,定义如下: Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type 上述 API 函数定义和自定义变量都放置于标准模块之中。 在获取图像数据时,首先定义一个整型变量用于存放 PictureBox 中的图像句柄,然后调用 GetBitmapBits 函数获取图像数据,存放于数组中,需要注意的时, Visual Basic 获得的数据都默认为彩色图像,因此定义数组大小时,需要按照真彩色图像进行处理。将读取图像按钮代码做调整,使得读入图像的同时就获得图像数据,代码调整如下: Private Sub cmdReadImage_Click() Dim strFileName As String CDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CDialog1.ShowOpen If CDialog1.FileName "" Then strFileName = CDialog1.FileName PicSource.Picture = LoadPicture(strFileName) End If SourceImHeight = PicSource.Height SourceImWidth = PicSource.Width Dim tSBmpInfo As BITMAP Dim hSrcBmp As Long Dim x As Integer, y As Integer hSrcBmp = PicSource.Image.Handle ' 注意,这里只能使用 image ,而不能使用 picture ' 获得位图信息 Call GetObject(hSrcBmp, Len(tSBmpInfo), tSBmpInfo) ReDim ImageArray(1 To tSBmpInfo.bmWidthBytes, 1 To SourceImHeight) As Byte ' 获得源图与目标图二进制位 Call GetBitmapBits(hSrcBmp, tSBmpInfo.bmWidthBytes * tSBmpInfo.bmHeight, ImageArray(1, 1)) ' 注意起点是 (1,1) ReDim sbits(SourceImHeight - 1, SourceImWidth - 1, 2) As Byte ' 通过下面的转换,将数组转置为习惯的格式,当然也可以不转置,只是后面使用起来比较麻烦 For y = 1 To SourceImHeight For x = 1 To SourceImWidth sbits(y - 1, x - 1, 2) = ImageArray((x - 1) * 4 + 1, y) sbits(y - 1, x - 1, 1) = ImageArray((x - 1) * 4 + 2, y) sbits(y - 1, x - 1, 0) = ImageArray((x - 1) * 4 + 3, y) Next x Next y End Sub 在处理程序时,同样定义动态数组用于存储目标图像数据,处理完成后再利用 SetBitmapBits 一次性将数组显示于目标的 PictureBox 控件之中,同样以直方图均衡化为例,对应的“直方图均衡化按钮代码调整如下: Private Sub cmdGrayEqua_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 Hist(255) As Long ' 存放原直方图统计结果 Dim P(255) As Single ' 存放原直方图概率 Dim PA(255) As Single ' 存放原直方图累计分布概率 Dim Map(255) As Single ' 存放灰度等级映射结果 Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim dbits(DestImHeight - 1, DestImWidth - 1, 2) As Byte ' 重新定义目标数组的维数 ' 图像的直方图统计 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 r = sbits(i, j, 0) g = sbits(i, j, 1) b = sbits(i, j, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i P(0) = Hist(0) / SourceImHeight / SourceImWidth Map(0) = 255 * P(0) For i = 1 To 255 P(i) = P(i - 1) + Hist(i) / SourceImHeight / SourceImWidth Map(i) = 255 * P(i) Next i ' 图像的直方图均衡化 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 r = sbits(i, j, 0) g = sbits(i, j, 1) b = sbits(i, j, 2) ' 插入图像处理的过程,对 r, g, b 进行处理 GrayValue = 0.3 * r + 0.59 * g + 0.11 * b dbits(i, j, 0) = Map(GrayValue) dbits(i, j, 1) = Map(GrayValue) dbits(i, j, 2) = Map(GrayValue) Next j Next i Dim tDBmpInfo As BITMAP Dim hDestBmp As Long hDestBmp = PicDest.Image.Handle ' 获得位图信息 Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo) ReDim ImageArray(1 To DestImWidth * 4, 1 To DestImHeight) As Byte For i = 1 To DestImHeight For j = 1 To DestImWidth ImageArray((j - 1) * 4 + 1, i) = dbits(i - 1, j - 1, 2) ImageArray((j - 1) * 4 + 2, i) = dbits(i - 1, j - 1, 1) ImageArray((j - 1) * 4 + 3, i) = dbits(i - 1, j - 1, 0) Next j Next i ' 获得源图与目标图二进制位 Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, ImageArray(1, 1)) End Sub 初学者可能觉得本例比较复杂,一下子跳跃的跨度较大,但只要熟悉下来,流程还是基本一致的,后面在做一些实例时,可能感觉更为明显。前面在做点运算时,每次计算只需要使用到一个点,本章开始讲述图像的增强,一般需要同时涉及到多个像素点,这里提出的数组存储数据的方法也便于这样的操作。 通过比对可以发现,采用本例的方法以后, Visual Basic 处理图像的速度就跟平时见到的 C 系列语言处理的图像的速度基本一致,如果想要进一步提高处理速度,就需要研究算法方面的内容,这个就不在这里进行讨论了。
2778 次阅读|0 个评论
Visual Basic与图像处理14
prrsw 2012-10-11 15:15
Visual Basic与图像处理14
Visual Basic 与图像处理(三) Visual Basic 做图像处理其实一直未专业人员所不屑,很大原因在于其速度不快,甚至很多初步接触图像处理的学生也是提到就皱眉,其实 Visual Basic 做图像处理理论研究并不是那么一无是处,尤其对于初学者,毕竟容易上手,能够快速的进行研究,还是有很多优点的,这里就不再辩论这个问题。 前文已经讲述了点运算的知识,也结合了一些实例来阐述 Visual Basic 进行图像处理的方法,从本节开始逐步进入稍微复杂的问题,但首先要解决的就是常说的处理速度的问题。本节还是从直方图均衡化那个实例下手,从实例分析来逐步提高运行速度。 引起 Visual Basic 图像处理速度慢的很大原因是前面说的非常多的两个函数 Point 和 PSet 方法,一个是从控件中取颜色点,一个是往控件界面上设置颜色点,无论取点还是设置点,都是要调用显存的,这显然会降低速度。在前面的直方图均衡化程序中,在灰度统计的时候遍历了一次图像,挨个取颜色点的值,而在后面设置颜色点,得到目标图像的时候,又得遍历一次图像,我们能想到的第一个办法就是尽量减少使用 Point 和 PSet 的次数。前面提到过,图像的本质就是一个矩阵,而矩阵在程序设计中往往是用数组进行表示的,如果在第一次取点以后就把得到的数据放置于数组中,那么后文再次调用这些数据时,就可以直接调用这个数组,可以有效的提高程序运行速度。 本例基于上述思路,采用数组来存储图像数据,由于在程序运行前,图像数据大小还不知道,因此需要采用动态数组来实现数据的存储,运行界面与前面的一样,如下图所示: 首先在窗口模块中定位了两个窗口级别的动态数组 SourceImData() 和 DestImData() ,在得到图像的高度和宽度以后就可以定义数组的大小,通过数组可以减少使用 Point 方法的次数,直方图均衡化按钮对应的代码调整如下: Private Sub cmdGrayEqua_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 Hist(255) As Long ' 存放原直方图统计结果 Dim P(255) As Single ' 存放原直方图概率 Dim PA(255) As Single ' 存放原直方图累计分布概率 Dim Map(255) As Single ' 存放灰度等级映射结果 Dim NGrayValue As Integer ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ReDim SourceImData(SourceImHeight - 1, SourceImWidth - 1) As Integer ReDim DestImData(DestImHeight - 1, DestImWidth - 1) As Integer ' 图像的直方图统计 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 SourceImData(i, j) = GrayValue Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i P(0) = Hist(0) / SourceImHeight / SourceImWidth Map(0) = 255 * P(0) For i = 1 To 255 P(i) = P(i - 1) + Hist(i) / SourceImHeight / SourceImWidth Map(i) = 255 * P(i) Next i ' 图像的直方图均衡化 For i = 0 To SourceImHeight - 1 For j = 0 To SourceImWidth - 1 NGrayValue = Map(SourceImData(i, j)) PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 如果细心对比,会发现通过这样一个改变,已经能稍微提高该程序的运行速度了,当然还是没有达到理想的要求,后面会继续讨论。
2555 次阅读|0 个评论
Visual Basic与图像处理13
热度 1 prrsw 2012-10-11 13:52
Visual Basic 与图像处理 ( 二 ) 到直方图均衡化结束,常见的点运算处理已经结束,适当总结两句,点运算是图像处理的入门,所谓入门也就是只有你跨过这个门槛才能算这个行业的人,但并不是你掌握了点运算就掌握了多少知识,而是希望学生通过学习这一章的知识知道图像处理的流程以及基本的实现方法。 本章所使用的方法以及涉及的理论并不复杂,也很容易掌握,但并不表示用处不大,比如本章涉及的阈值分割往往是检测类的图像分析所必须要涉及的一个步骤,只是在本章中阈值是自行设定的,而在具体实际问题时,需要采用一定的数学方法完成阈值的自动计算。我在上课时一直跟学生说,图像处理说到底也只是一个工具,分析具体问题时还是得到数学、信息等方面的知识,但是如果工具都掌握不好,也就无法解决实际的问题了。 即使是点处理可能也需要适当变通,前一段有个博士生在研究中发现直方图均衡化与 Photoshop 中的“自动对比度”菜单效果不一致,而在研究中发现利用“自动对比度”可以完成其论文研究中的其中一个步骤,就想找出这种操作的原理,我们找了好多本书都没有找到,而最后意外的在某个网页中发现了其中的原理介绍,顺利解决了这个问题。我想说的是,学无止境,并不是说你学会了一个东西就能解决所有问题,只有在不断研究之中,发现新的问题,解决新的问题,才能逐步提高自己的能力。 我在这里更新这个博客的目的,也是希望给初步进入这个研究领域的学生或者研究者提供一点点细微的帮助,希望大家一切都能够顺利。第一章终于结束了,我是一边编程,一边写这个文档,多多少少会出现一些问题,希望看到的同仁们不要笑话。
2340 次阅读|1 个评论
Visual Basic与图像处理12
prrsw 2012-10-11 13:40
Visual Basic与图像处理12
Visual Basic 与图像处理 ( 二 ) 9 、直方图均衡化 直方图均衡化也成为灰度均衡,是点运算较为复杂的一种,其基本原理是对图像中像素个数较多的灰度区域进行范围拓宽,而对像素较少的灰度区域,即在图像画面中不起主要作用的灰度值进行归并。一般在图像比较或者分割之前进行直方图均衡,可以使图像具有较为一致格式。比如由于光照条件使得同一背景图像有较大的亮度反差就可以利用直方图均衡化进行亮度调整。 设 f(i, j), g(i, j) 分别为原图像和处理后的图像,图像的灰度等级变换范围为 ,直方图均衡化可以按照以下的步骤进行: (1) 原图像直方图统计结果为 Hist ; (2) 求原图像直方图的灰度分布概率,记作 p ; (3) 计算元图像各个灰度等级的累计分布概率,记作 PA ,显然 PA =0, PA =1 ; (4) 进行直方图均衡化新的灰度值计算,将新的灰度值存放于映射 Map 中,其中: Map =255 × PA 。 从上述步骤来看,要做直方图均衡化,首先要计算直方图统计结果,然后再得到每个灰度等级对应的新的灰度等级,最后才能完成直方图均衡化操作。程序的实现与前面的类似,这里不在详细讲述,该例的运行界面如下图所示: 直方图均衡化按钮对应的代码如下: Private Sub cmdGrayEqua_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 Hist(255) As Long ' 存放原直方图统计结果 Dim P(255) As Single ' 存放原直方图概率 Dim PA(255) As Single ' 存放原直方图累计分布概率 Dim Map(255) As Single ' 存放灰度等级映射结果 Dim NGrayValue As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 图像的直方图统计 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 Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i P(0) = Hist(0) / SourceImHeight / SourceImWidth Map(0) = 255 * P(0) For i = 1 To 255 P(i) = P(i - 1) + Hist(i) / SourceImHeight / SourceImWidth Map(i) = 255 * P(i) 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
2487 次阅读|0 个评论
Visual Basic与图像处理11
prrsw 2012-10-11 11:30
Visual Basic与图像处理11
Visual Basic 与图像处理 ( 二 ) 8 、灰度拉伸 灰度拉伸是将图像中不同灰度等级按照预定的方式进行拉伸,从实质上来说灰度拉伸是灰度线性变换的一种延伸,当然也不完全等同于灰度线性变换,而是对灰度等级进行分段,然后分别进行线性变换。灰度拉伸可以用下面的函数表达式表示: 式中 (x1, y1) 和 (x2, y2) 是灰度拉伸中两个转折点的坐标,如下图中的 A , B 两点。 相比于线性变换,灰度拉伸可以更灵活更改图像的灰度,可以根据需要选择性的变换某个灰度等级范围内的像素点。在本例中,采用图形化控制的方法设定上述两个转折点,这里涉及了一个平时称为“橡皮筋”的技术,在网络上有很多介绍橡皮筋技术的文章,在 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
3091 次阅读|0 个评论
Visual Basic与图像处理10
prrsw 2012-10-11 07:56
Visual Basic与图像处理10
Visual Basic 与图像处理(二) 7 、灰度窗口变换 灰度窗口变换是选择窗口中部分灰度等级的一种点运算方式,其实现方法与阈值变换类似。选择一定的灰度等级范围,在该范围内的灰度值保持不变,小于该范围下限的灰度值设置为 0 (黑色),而大于该范围上限的灰度值设置为 255 (白色)。灰度窗口变换可以用下面的函数形式进行表达: 这里的 L 表示窗口范围的下限, H 表示窗口范围的上限。 灰度窗口变换的在平时用途较为广泛,比如利用灰度窗口变换可以消除较暗或者较亮的背景,在软件设计时,该例与阈值变换非常相似,同样由两个 PictureBox 组成,另外在窗口中放置了两个文本框,分别用于存放窗口范围的下限和上限。本例的运行界面如下图所示 : 窗口变换按钮对应的代码如下: Private Sub cmdWindowTrans_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 NGrayValue As Integer Dim L As Integer, H As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth L = Val(txtL) H = Val(txtH) ' 图像的窗口变换 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 If GrayValue L Then NGrayValue = 0 ElseIf GrayValue H Then NGrayValue = 255 Else NGrayValue = GrayValue End If PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub
2891 次阅读|0 个评论
Visual Basic与图像处理9
热度 1 prrsw 2012-10-10 15:15
Visual Basic与图像处理9
Visual Basic 与图像处理 ( 二 ) 6 、阈值变换 图像的阈值变换可以将一幅图像变为黑白二值图像,即按照设定的阈值,如果图像中像素点的灰度值小于该阈值,则将该像素点的灰度值设定为 0 ,在图像中显示为黑色,否则将改点的灰度值设定为 255 ,在图像中显示为白色。有时候为强化阈值后的效果,也会将阈值结果进行反相。 阈值变换的原理可以表达为如下的函数形式: 这里的 T 就是设定的阈值。 阈值变换的实现方法也比较简单,在本例示范时,增加了一个水平滚动条用于设定阈值,其余界面与灰度线性变换的类似,软件的界面如下图所示: 这里用一个 ThresholdValued 窗体级别变量作为阈值,其中阈值变换按钮对于的代码如下: Private Sub cmdThresholdTrans_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 NGrayValue As Integer ThresholdValue = Val(txtThreshold) ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 彩色图像的阈值变换 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 If GrayValue ThresholdValue Then NGrayValue = 0 Else NGrayValue = 255 PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 滚动条对应的代码如下: Private Sub HScroll1_Change() txtThreshold = Str(HScroll1.Value) End Sub 当文本框失去焦点时,也自动更改阈值,对应的代码如下: Private Sub txtThreshold_LostFocus() HScroll1.Value = Val(txtThreshold) End Sub
2573 次阅读|2 个评论
Visual Basic与图像处理8
prrsw 2012-10-10 11:24
Visual Basic与图像处理8
Visual Basic 与图像处理 ( 二 ) 5 、灰度线性变换 灰度线性变换也是一种典型的点运算,原理也比较简单,就是将图像中所有像素点的灰度按照线性函数进行变换,以 D image 表示目标图像, S image 表示源图像,灰度线性变换可以理解为: D image =k*S image +b 其中 k 为线性函数的斜率, b 为线性函数在 y 轴上的截距。当 k1 时,整个图像灰度的分布区域将变大,目标图像的整体对比度增大;反之,当 k1 时,整个图像灰度的分布区域将变小,目标图像的整体对比度减小;而 k=1 时,目标图像所有像素点的灰度增大或者减小,使得图像整体变亮或者变暗,而图像的整体对比度并不发生改变。 有两种特殊情况,当 k=1 , b=0 时,目标图像与原图像;而当 k=-1 , b=255 时,目标图像的灰度正好与原图像反转,就是平时所说的反相。 对于给定的 k 值和 b 值,对图像进行灰度线性变换比较简单,软件界面与灰度化处理的程序类似,直接更改其中的几句代码即可,软件的运行界面如下: 灰度线性变换按钮对应的代码如下: Private Sub cmdLinearTrans_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 NGrayValue As Integer Dim k As Integer, t As Integer ' 改用字母 t ,避免与颜色值变量重复 ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth k = Val(txtK) t = Val(txtB) ' 彩色图像的灰度线性变换 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 = k * GrayValue + t If NGrayValue 255 Then NGrayValue = 255 ' 如果超过 255 ,统一设定为 255 If NGrayValue 0 Then NGrayValue = 0 ' 如果小于 0 ,统一设定为 0 PicDest.PSet (j, i), RGB(NGrayValue, NGrayValue, NGrayValue) Next j Next i End Sub 特殊情况下,当 k=-1 , b=255 时,实现的是图像的反相,效果如下图所示:
2949 次阅读|0 个评论
Visual Basic与图像处理7
prrsw 2012-10-10 10:44
Visual Basic与图像处理7
Visual Basic 与图像处理 ( 二 ) 4 、基于灰度直方图的灰度特征值计算 前文介绍过直接基于图像的每个像素点计算图像的均值和方差,在得到图像的灰度直方图统计以后,还可以根据直方图统计结果进行图像均值和方差的计算,这种算法效率更高,程序运行更快,尤其对于尺寸较大的图像,这种优势更为明显。算法的本质是将灰度等级相同的像素点进行归类,一次性计算出其和值,然后来计算均值和方差。本例将这种算法与前文直接根据像素点计算的方法进行比对,软件的界面如下: 从图中可以看出,两者的结果是一致的,其中基于直方图的特征计算按钮对应的代码如下: Private Sub cmdCalFeatureBaseHist_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 Hist(0 To 255) As Long Dim SumValue As Long Dim MeanValue As Single Dim StdValue As Single ' 直方图统计 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 Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i ' 图像均值计算 For i = 1 To 255 ' 计算和值是,灰度等级为 0 的直接省略 SumValue = SumValue + Hist(i) * i Next i MeanValue = SumValue / SourceImHeight / SourceImWidth MeanValue = Format(MeanValue, "0.00") ' 保留两位小数 txtNewMean = Str(MeanValue) ' 图像标准差计算 SumValue = 0 For i = 0 To 255 SumValue = SumValue + (i - MeanValue) ^ 2 * Hist(i) Next i StdValue = Sqr(SumValue / SourceImHeight / SourceImWidth) StdValue = Format(StdValue, "0.00") ' 保留两位小数 txtNewStd = Str(StdValue) End Sub
2676 次阅读|0 个评论
Visual Basic与图像处理6
热度 2 prrsw 2012-10-10 10:24
Visual Basic与图像处理6
Visual Basic 与图像处理 ( 二 ) 3 、灰度直方图 灰度直方图是描述图像中像素灰度分布的一个统计图,简而言之就是描述图像中每个灰度值像素的个数或者概率,横坐标对应就是图像的灰度级别,纵坐标是该灰度级别对应的像素个数(或概率)。要得到图像的灰度直方图,首先要完成各灰度级别对应像素个数的统计,将统计结果存放于 Hist 数组中,然后再根据这个数组进行直方图的绘制。 基于前面的编程基础,相信要完成直方图统计应该都没有问题,这里要简要介绍一下直方图绘制的方法。前文提及过, PictureBox 不仅支持图像的读写,还支持图形的绘制,在这里为简便起见,只用一系列直线进行直方图的绘制, PictureBox 的 Line 方法可用于直线的绘制,其原型如下: object.Line (x1, y1) - (x2, y2), , 这里 (x1,y1) 为直线的起点, (x2,y2) 为直线的终点,如果没有 Step 表示直接从起点画到终点,如果有关键字 Step ,表示分别沿着 x1 , y1 在横向和纵向绘制 x2, y2 的长度, color 用于设置直线的颜色,可用 RGB 函数进行设定。如果使用了 B 选项,则 F 选项规定矩形以矩形边框的颜色填充。不能不用 B 而用 F 。如果不用 F 光用 B ,则矩形用当前的 FillColor 和 FillStyle 填充, FillStyle 的缺省值是 Transparent ,由于本例中只画直线,因此 B 选项和 F 选项都不选用。 在直方图绘制时,首先要确定每个灰度等级对应的线段长度,这里采用常见的一种方法,即首先找出统计概率最高的灰度等级,设定其绘制长度,其余灰度等级绘制的线段长度与该灰度等级成对比,假设概率最高的灰度等级对应的绘制长度为 L ,其他灰度等级的线段绘制长度可按照下面的方式进行计算: L gray = L * Hist / Hist max 首先对程序界面进行设计,本例主要由两个 PictureBox 组成,其中一个 PictureBox 用于存放图像,另一个用于直方图的绘制。用于直方图绘制的 PictureBox 宽度直接设置为 256 个像素,即每个灰度等级绘制的直线占的宽度都是 1 个像素。该程序的软件运行界面如下: 直方图绘制按钮对应的代码如下: Private Sub cmdHist_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 Hist(0 To 255) As Long Dim maxHist As Long, L As Integer, L0 As Integer ' 直方图统计 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 Hist(GrayValue) = Hist(GrayValue) + 1 Next j Next i ' 直方图绘制 ' 第一步,寻找 Hist 数组中的最大值,即灰度等级统计概率最高者 maxHist = Hist(0) For i = 1 To 255 If maxHist Hist(i) Then maxHist = Hist(i) Next i ' 绘制直方图,其中最高概率的灰度等级绘制长度与 PictureBox 的高度一致 L = PicHist.Height For i = 0 To 255 L0 = L * Hist(i) / maxHist PicHist.Line (i, L - 1)-Step(0, -L0), RGB(0, 0, 255) ' 绘制蓝色线条 Next i End Sub
3887 次阅读|3 个评论
Visual Basic与图像处理5
prrsw 2012-10-10 09:28
Visual Basic与图像处理5
Visual Basic 与图像处理 ( 二 ) 2 、图像的特征值计算 这里所说图像的特征值是指可以直接从图像中提取出来的特征参数,常用于对图像的整体性评价,如图像的灰度均值可以用于判断图像整体亮度的高低。在图像灰度化的基础上可以很便捷的完成图像特征值的计算,本例中以两个基本的特征参数计算作为示范:均值和标准差。从本质上来说,图像灰度化以后就相当于一个二维矩阵,因此均值的计算只要求得图像中所有像素点的灰度值之和,再除以图像的高度与宽度的乘积即可,图像的标准差计算方法与此类似。以 MeanValue 和 StdValue 分别表示图像的均值和标准差,其计算公式如下: 首先设计程序的软件界面,本例中运行界面如下图: 同样“读入图像”按钮的代码与前文类似,这里给出特征值计算按钮对于的程序代码: Private Sub cmdCalFeature_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 SumValue As Long Dim MeanValue As Single Dim StdValue As Single ' 图像均值计算 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 SumValue = SumValue + GrayValue Next j Next i MeanValue = SumValue / SourceImHeight / SourceImWidth MeanValue = Format(MeanValue, "0.00") ' 保留两位小数 txtMeanValue = Str(MeanValue) ' 图像标准差计算 SumValue = 0 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 SumValue = SumValue + (GrayValue - MeanValue) ^ 2 Next j Next i StdValue = Sqr(SumValue / SourceImHeight / SourceImWidth) StdValue = Format(StdValue, "0.00") ' 保留两位小数 txtStdValue = Str(StdValue) End Sub
2642 次阅读|0 个评论
Visual Basic与图像处理4
prrsw 2012-10-10 08:39
Visual Basic与图像处理4
Visual Basic 与图像处理 ( 二 ) 有了上面介绍的 Point 和 PSet 方法以后就可以进入真正的图像处理阶段了,与平时学习一样,这里同样从最简单的图像处理技术——点运算开始讲起。点运算简而言之就是对图像进行逐点运算,得到所需要的特征参数或者新的图像。点运算之所以简单是因为点运算每次只需要考虑当前一个像素点的颜色值,当然点运算不可能改变图像内的空间关系。 点运算中最简单是获得图像的特征参数包括均值、方差等,另一种就是按照特定的方式对图像的直方图进行改变,这里的特定方式可以看成是从像素到像素的操作,常见的有对比度增强、对比度拉伸或灰度变换。后面将从图像灰度化、特征参数计算、直方图统计、灰度线性变换、灰度拉伸、直方图均衡化等几种常用的实例进行讲解,同时以 Visual Basic 软件进行算法实现。 1、 图像的灰度化 图像的灰度化是指将原始的彩色图像转换为灰度图像,这也是后续其他点运算操作的先前操作,也就是说点运算是基于灰度图像进行的。彩色图像中 Red 、 Green 、 Blue 三个分量值相等时,呈现出的就是一种灰度化的效果,因此要讲彩色图像转换为灰度图像只要将上述三个分量值设置为同样的值即可。这里需要讨论的只是设置灰度值的方法,有一种最简单的方法是取三个分量中的一个或者是平均值,但在实践中发现这种简单的转换方法与人的视觉习惯不太符合,因此有许多公司在研究这种灰度转换模型,在本节中,我们采用加权平均的方法实现图像的灰度化,方法如下: Gray = 0.3*Red+0.59*Green+0.11*Blue 下面通过一个实例实现彩色图像的灰度化,本例是后续点运算的基础,同样第一次涉及图像处理的完整流程,因此讲述的稍微详细一点。 为了强调原始图像与目标图像的概念,这也是在一般图像处理软件里面都会涉及的,本例中在窗体中放置两个 PictureBox 控件,分别用于存放原始图像与目标图像。 读取图像的方法与前文介绍的一致,即用 LoadPicture 函数进行图像读取,在获得原始图像的高度和宽度以后,按照预定方式进行目标图像的高度和宽度设置,然后利用循环语句遍历原始图像,逐个改变原始图像中每个像素点的值,并将其赋值到目标图像中,就可以完成图像的点运算。这里的循环语句是后面其他图像处理中也经常需要使用的一个标准过程,其基本格式如下 For i = 0 To h - 1 For j = 0 To w - 1 PixelValue = Picture1.Point(j, i) r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 ’ 插入图像处理的过程,对 r, g, b 进行处理 …….………………………………. Picture2.PSet (j, i), RGB(RValue, GValue, BValue) Next j Next i 这里需要注意观察的是 Point 和 PSet 方法中坐标的位置,第一个坐标是横坐标,第二个坐标是纵坐标。 有了这个标准过程就可以理解图像灰度化处理的基本代码了,首先设计该程序的软件界面,效果如下图所示: 这里读入图像按钮的代码与前文类似,这里不在阐述,下面是灰度化按钮对于代码: Private Sub cmdGray_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 ' 设置目标图像的高度和宽度 DestImHeight = SourceImHeight DestImWidth = SourceImWidth ' 设置目标 PictureBox 的大小 PicDest.Height = DestImHeight PicDest.Width = DestImWidth ' 彩色图像的灰度化处理 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 PicDest.PSet (j, i), RGB(GrayValue, GrayValue, GrayValue) Next j Next i End Sub
3036 次阅读|0 个评论
Visual Basic与图像处理3
热度 1 prrsw 2012-10-9 19:19
Visual Basic与图像处理3
Visual Basic 与图像处理(二) 从本节开始,正式开始进入 Visual Basic 图像处理的内容,在正文中会结合一些实例来讲解 Visual Basic 处理图像的方法,当然在初始阶段,一切从简单的开始,在处理图像时也仅用 Point 与 PSet 相结合完成图像的读和写的两个过程。 1. 读入和保存图像 VB 中读入图像可以采用 LoadPicture 函数直接进行,当然也可以采用读取文件的方法直接读取图像数据,然后将图像数据在 PictureBox 中进行绘制。为了便于教学,一般都直接采用 LoadPicture 函数进行图像的读取, LoadPicture 函数的原型如下: LoadPicture ( , , , , ) as TPictureDisp 在我们读入图像时,一般直接使用下面的格式: Picture1.Picture=LoadPicture (FileName) 当 FileName 为空时,清空 PictureBox 中图像。 如果直接使用固定的 FileName 字符常量时,可读入存储器中固定位置的图像,如果希望以对话框的形式进行图像的选择性读取,可以使用 CommonDialog 控件实现。 图像保存对打开类似,可以使用写文件的形式进行图像数据的存储,在 Visual Basic 中提供了配合 PictureBox 控件专门的文件保存函数 SavePicture ,其函数原型如下: SavePicture ( Picture as TPictureDisp, FileName as String) 下面以一个实例示范如何进行图像读取和保存: 窗体中放有 1 个 PictureBox 控件用于显示图像, 2 个 CommandButton 分别用读取和保存图像, 1 个 CommodDialog 控件用于调用对话框。窗体外观如下: 注意设置 PictureBox 控件的相关属性。本例对应的相关代码如下: Option Explicit Private Sub cmdOpenImage_Click() Dim strFileName As String CommonDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CommonDialog1.ShowOpen If CommonDialog1.FileName "" Then strFileName = CommonDialog1.FileName PicShowImage.Picture = LoadPicture(strFileName) End If End Sub Private Sub cmdSaveImage_Click() Dim strFileName As String CommonDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CommonDialog1.ShowSave If CommonDialog1.FileName "" Then strFileName = CommonDialog1.FileName SavePicture PicShowImage.Picture, strFileName End If End Sub 2 、 PictureBox 控件中像素点颜色值存储格式 在 PictureBox 读入图像以后,像素点以长整型的格式存储在控件之中,利用 Point 方法可以实现像素点颜色值的读取,具体方法如下: Picture1.Point (x, y), 其中 x 为横坐标, y 为纵坐标。 在使用中常采用以下格式得到对应的值: Dim PixelValue as Long PixelValue=Picture1.Point (x, y) 为了便于后续运算,一般要完成颜色数据的分离,即将这个长整型的数转化为对应的 Red 、 Green 、 Blue 三个分量的值。在转化之前,首先看一下颜色值的存储方法,在 Visual Basic 中颜色点以下面的格式进行存储 : 其中第一个字节一般不使用,所以这里只讨论后面三个字节的分离,在数据合成时,上述三个分量分别占 1 个字节,如果将其理解为 256 进制就比如容易理解了,相当于十进制中的个位、十位和百位,只是在显示的时候还是以十进制的形式进行显示而已,如果要分离上述数据就比较简单了,只要将十进制转化为对应的 256 进制就可以了。十进制转化为二进制是除 2 取余法,转化为 256 进制也是采用同样的方法,除 256 取余即可。 下面就是作者在授课是经常采用的一种颜色数据分离方法 Dim r as Integer, g as Integer, b as Integer r = PixelValue Mod 256 g = (PixelValue \ 256) Mod 256 b = PixelValue \ 65536 3 . PictureBox 颜色点的写入 有了 Point 方法可以从 PictureBox 控件中读取颜色点值,对用还需要将某个颜色点值写入到对应的 PixtureBox 控件之中,这里采用与 Point 对用的 PSet 方法, PSet 的使用格式如下: Picture1.PSset (x, y), Color 这里的 Color 同样对应一个长整型的颜色数值,对上述数据分离对应的时,在数据处理时往往知道的是 Red, Green, Blue 三个分量的值,需要将这三个分量进行合成,得到长整型的颜色数值,合成方法与前面讲的非常类似,具体方法如下: PixelValue= r+256*g+256*b 当然在实际使用中还可以直接利用 RGB 函数进行颜色值的合成,使用方法如下: PixelValue=RGB(r, g, b) 下面结合一个实例结束这一部分内容,在完成图像读和写以后,本例中完成图像高度和宽度的自动读取,同时利用 Point 方法读取某个指定位置像素点的值,最后利用 PSet 方法将图像的左上角一块区域设置为红色。本例的运行结果如下: 对应的代码分别如下: Option Explicit Dim ImageHeight As Integer, ImageWidth As Integer Private Sub cmdOpenImage_Click() Dim strFileName As String CommonDialog1.Filter = "bmp|*.bmp|jpg|*.jpg|gif|*.gif" ' 文件过滤,可以打开上述三类图像 CommonDialog1.ShowOpen If CommonDialog1.FileName "" Then strFileName = CommonDialog1.FileName PicShowImage.Picture = LoadPicture(strFileName) End If ImageHeight = PicShowImage.Height ImageWidth = PicShowImage.Width Text1 = Str(ImageHeight) Text2 = Str(ImageWidth) End Sub Private Sub cmdPoint_Click() Dim r As Integer, g As Integer, b As Integer Dim x As Integer, y As Integer Dim pixelvalue As Long x = Val(Text3): y = Val(Text4) pixelvalue = PicShowImage.Point(x, y) r = pixelvalue Mod 256 g = (pixelvalue \ 256) Mod 256 b = pixelvalue \ 65536 Text5 = Str(r) Text6 = Str(g) Text7 = Str(b) End Sub Private Sub cmdPSet_Click() Dim i As Integer, j As Integer For i = 0 To 20 For j = 0 To 20 PicShowImage.PSet (i, j), RGB(255, 0, 0) Next j Next i End Sub
3474 次阅读|1 个评论
Visual Basic与图像处理2
prrsw 2012-10-9 15:47
Visual Basic与图像处理2
Visual Basic 与图像处理 ( 一 ) 4. PictureBox 控件 对于 Visual Basic 众多控件中,重点介绍一下这个 PictureBox 控件。 PictureBox 支持图像的读取,同时也支持图像的绘制,因此经常在 VB 中被用于图像处理使用。 PictureBox 支持常用的 bmp 、 jpg 和 gif 等格式的读取,自带简单的 Point 和 PSet 方法,便于构建简单的图像处理程序。 PictureBox 的 AutoSize 属性设定为 True 以后,读入图像中会自动调整 PictureBox 控件的大小,使其与图像的大小一致,从而可以自动获得图像的高度和宽度。为了使 PictureBox 的宽度和高度与图像的宽度与高度完全一致,可以将 PictureBox 的 BorderStyle 属性设置为 0-None 。 平时我们所说的图像的高度和宽度一般是以像素形式进行表示的,所以在控制绘制完成后,要将窗体以及 PictureBox 的 ScaleMode 属性设置为 3-Pixel ,这样得到的竖直才符合我们平时的认知。 下图即为一种的简单的程序实例,可以完成图像的读取和保存。 本例中 PictureBox 控件的相关属性已经进过设置,可以看出读取图像以后, PictureBox 控件的大小已经与图像一致,为了获得图像的高度和宽度可以使用下述语句: ImageHeight=Picture1.Height ImageWidth=Picture1.Width 5. 处理图像的三要素 这也是我经常跟学生讲的一句话,要理解图像处理的本质,首先要知道图像处理要从何下手,不管是什么语言,处理图像的语句可能不一样,但是基本过程是一致的。要处理图像首先要知道以下三个信息: (1) 第一个就是图像的高度和宽度,这也是平时遍历图像所需要的,在前面介绍 PictureBox 控件的时候已经做了简要介绍; (2) 图像的起点,也就是要理解图像的坐标格式,比如平时读取 bmp 图像是从左下角开始,在 VB 中, PicureBox 读入图像以后,图像的起点都是在左上角; (3) 每个像素的值,也就是要知道具体的图像内部数据,就好像矩阵处理要知道每个元素的值一样,前两个要素已经作了相关介绍,关于这个要素后文会专门介绍。 6. VB 图像处理的基本流程 这个流程也是初学者在编程时需要牢记的,这样才便于理清自己的思路。 l 读入图像并显示。 l 获得图像高度和宽度。 l 获得图像每一像素的数据。 l 对每一像素的数据进行相应变换。
3524 次阅读|0 个评论

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

GMT+8, 2024-5-25 02:20

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部