大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
用point 方法太慢了,还是用api的getDIBits和setDIBits吧,彩图转灰度图的代码如下:
西区网站建设公司成都创新互联,西区网站设计制作,有大型网站制作公司丰富经验。已为西区1000+提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的西区做网站的公司定做!
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BitMapInfo, ByVal wUsage As Long) As Long
Private Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BitMapInfo, ByVal wUsage As Long) As Long
Private Type BitMapInfoHeader ''文件信息头——BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type RGBQuad
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
''rgbReserved As Byte
End Type
Private Type BitMapInfo
bmiHeader As BitMapInfoHeader
bmiColors As RGBQuad
End Type
Private Sub Command1_Click()
Dim ix As Integer
Dim iy As Integer
Dim iWidth As Integer '以像素为单位的图形宽度
Dim iHeight As Integer '以像素为单位的图形高度
Dim bytGray As Byte
Dim bytThreshold As Byte
Dim bits() As Byte '三维数组,用于获取原彩色图像中各像素的RGB数值以及存放转化后的灰度值
Dim bitsBW() As Byte '三维数组,用于存放转化为黑白图后各像素的值
'获取图形的宽度和高度
iWidth = Picture1.ScaleWidth / Screen.TwipsPerPixelX
iHeight = Picture1.ScaleHeight / Screen.TwipsPerPixelY
Picture1.Picture = Picture1.Image
'创建并初始化一个bitMapInfo自定义类型
Dim bi24BitInfo As BitMapInfo
With bi24BitInfo.bmiHeader
.biBitCount = 32
.biCompression = 0
.biPlanes = 1
.biSize = Len(bi24BitInfo.bmiHeader)
.biWidth = iWidth
.biHeight = Picture1.ScaleHeight / Screen.TwipsPerPixelY
End With
'重新定义数组大小
ReDim bits(3, 0 To iWidth, 0 To iHeight) As Byte
ReDim bitsBW(3, 0 To iWidth, 0 To iHeight) As Byte
'使用GetDIBits方法一次性获取picture1中各点的rgb值,比point方法或getPixel函数逐像素获取像素rgb要快出一个数量级
lrtn = GetDIBits(Picture1.hdc, Picture1.Picture.Handle, 0, iHeight, bits(0, 0, 0), bi24BitInfo, 0)
'数组的三个维度分别代表像素的RGB分量、以图形左下角为原点的X和Y坐标。
'具体说来,这时bits(0,2,3)代表从图形左下角数起横向第2个纵向第3个像素的Blue值,而bits(1,2,3)和bits(2,2,3)分别的Green值和Red值.
bytThreshold = 128 '这里定义转换为黑白图像时的阈值为128,即灰色亮度大于128的像素转为白色,小于128的像素转为黑的,此值可根据需要修改为0-255之前任意数值
For ix = 0 To iWidth
For iy = 0 To iHeight
'***********RGB转为灰度的算法有多种,这里给出常见的两种*******
'bytGray = bits(0, ix, iy) * 0.11 + bits(1, ix, iy) * 0.59 + bits(2, ix, iy) * 0.3 '这是传统的根据三原色亮度加权得到灰阶的算法
bytGray = (bits(0, ix, iy) ^ 2.2 * 0.0722 + bits(1, ix, iy) ^ 2.2 * 0.7152 + bits(2, ix, iy) ^ 2.2 * 0.2126) ^ (1 / 2.2) '这是简化 sRGB IEC61966-2.1 [gamma=2.20],有点类似于photoshop中所用的算法
bits(0, ix, iy) = bytGray
bits(1, ix, iy) = bytGray
bits(2, ix, iy) = bytGray
'*********转为黑白图像********
If bits(0, ix, iy) bytThreshold Then
bitsBW(0, ix, iy) = 0
bitsBW(1, ix, iy) = 0
bitsBW(2, ix, iy) = 0
Else
bitsBW(0, ix, iy) = 255
bitsBW(1, ix, iy) = 255
bitsBW(2, ix, iy) = 255
End If
Next
Next
'将灰度图显示到picture2中
Picture2.Picture = Picture2.Image '如果picture2的picture属性为空,需要在setDIBits之前将其picture属性设置一下,否则无法显示出图形
SetDIBits Picture2.hdc, Picture2.Picture.Handle, 0, iHeight, bits(0, 0, 0), bi24BitInfo, 0
Picture2.Picture = Picture2.Image
'将黑白图显示到picture3中
Picture3.Picture = Picture3.Image
SetDIBits Picture3.hdc, Picture3.Picture.Handle, 0, iHeight, bitsBW(0, 0, 0), bi24BitInfo, 0
Picture3.Picture = Picture3.Image
End Sub
代码运行很快,如图所示图片基本可瞬间完成
图像的灰度变换一般是指根据某种规律改变图像中的灰度值,使得图像的亮度或者对比度发生变化,最终让图像变得更容易分辨以及达到我们想要的效果,一般来说,灰度转换有以下几种方式:
① 线性变换: 当图像出现曝光不足或者曝光过度的时候,灰度图会被局限在很小的范围内,这时我们会通过线性变换将每一个像素线性拉伸。一般线性变换效果会增强图像的对比度,举个例子就是,图像会变得黑色更黑,白色更白。
② 分段线性变换: 主要是用作突出感兴趣的目标或者灰度区间,抑制那些不感兴趣的区域,一般来说,我们会把图像分成三段去进行线性变换,对任意区间的灰度区间进行压缩或拓展,一般用在有类似于折痕这样的噪声的图片中,减少折痕的影响。
③ 非线性变换: 该变换一般不针对某个不同的灰度区间进行变换,而是在整个灰度值范围内采取相同的非线性函数实现灰度值区间的压缩和拓展。如对数变换,用于扩展图像的低灰度值部分,压缩高灰度值部分,使得低灰度的图像细节清晰化。相对应的指数变换则是拉伸高灰度区域,提高灰度区域高的像素点。
这个说的直方图一般指的是灰度直方图,是按照灰度值大小,统计图像中像素出现的频率,横坐标为灰度值,纵坐标是该灰度值出现的频率或者像素个数。但直方图只能反映整幅图像的亮暗程度和对比度,不能看出灰度空间分布情况。直方图一般有以下两种修正形式:
① 直方图均衡化: 通过对原图像进行某种变换,使得原图像的灰度直方图修正为均匀分布直方图,从而达到调整图像对比度的目的,主要适用于背景和前景太暗或太亮的图像(啊,依旧是万能的ppt画的直方图,ppt赛高)。
② 直方图规定化 :即是将原图像直方图变成规定形状的直方图。最理想的情况是直方图均衡化实现了图像灰度的均衡分布,对提高图像对比度有明显的作用。但是在实际使用中,我们不一定需要直方图具有整体的均匀分布特性,而是希望与规定的一致。
意思是将图像的像素点全部设置成0或255,变成黑白图像,大幅度减少图像的数据量,凸显目标轮廓,同样的,一般有三种做法:
①取0-255之间的平均数作为阈值过滤,灰度值小于平均数127的归于像素0,反之归于255。
②计算图像所有像素的灰度平均值作为阈值过滤,灰度值小于阈值的归于像素0,反之归于255。
③取灰度直方图上,前景和背景两个高峰之间的最低谷为阈值,灰度值小于阈值的归于像素0,反之归于255。
符号说明:erode(腐蚀)dilate(膨胀)src(原图)element(移动窗口大小)dist(最终图像)
先腐蚀后膨胀,可以用来消除小物体,可以在分离物体,平滑边界的同时改变面积不明显,效果通常为放大了裂痕或局部亮度低的区域,公式为:
dist= dilate(erode(src, element))
先膨胀后腐蚀,能排除小型黑色区域,效果通常为突出了比原图轮廓周围更暗的区域。公式为:
dist = erode(dilate(src , element))
求膨胀图与腐蚀图之差,对二值图像进行这一操作可以突出图块边缘,从而保留物体的边缘轮廓,公式为:
dist = dilate(src, element) - erode(src , element)
求原图和开运算图之差,开运算减去原图后可以得到比原图轮廓周围区域更亮的效果图,公式为:
dist = src - dilate(erode(src, element))
求闭运算图和原图之差,用作分离比临近点暗一点的斑块,得出比较平滑的轮廓,公式为:
dist = erode(dilate(src, element)) - src
主要是用作对图像进行平滑处理,目的是去除图像中的噪声,但会使得图像中物体边缘模糊,具体操作为:对窗口范围内像素的灰度值进行平均值计算,然后将当前像素的灰度值用它所在邻域内像素的平均值代替。
内容掺杂个人理解,记录准确性不担保,随时改(●ˇ∀ˇ●)
图像二值化的目的是最大限度的将图象中感兴趣的部分保留下来,在很多情况下,也是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。这个看似简单的问题,在过去的四十年里受到国内外学者的广泛关注,产生了数以百计的阈值选取方法,但如同其他图像分割算法一样,没有一个现有方法对各种各样的图像都能得到令人满意的结果。
本文针对几种经典而常用的二值发放进行了简单的讨论并给出了其vb.net 实现。
1、P-Tile法
Doyle于1962年提出的P-Tile (即P分位数法)可以说是最古老的一种阈值选取方法。该方法根据先验概率来设定阈值,使得二值化后的目标或背景像素比例等于先验概率,该方法简单高效,但是对于先验概率难于估计的图像却无能为力。
2、OTSU 算法(大津法)
OSTU算法可以说是自适应计算单阈值(用来转换灰度图像为二值图像)的简单高效方法。1978 OTSU年提出的最大类间方差法以其计算简单、稳定有效,一直广为使用。
3、迭代法(最佳阀值法)
(1). 求出图象的最大灰度值和最小灰度值,分别记为Zl和Zk,令初始阈值为:
(2). 根据阈值TK将图象分割为前景和背景,分别求出两者的平均灰度值Z0和ZB:
式中,Z(i,j)是图像上(i,j)点的象素值,N(i,j)是(i,j)点的权值,一般取1。
(3). 若TK=TK+1,则所得即为阈值,否则转2,迭代计算。
4、一维最大熵阈值法
它的思想是统计图像中每一个灰度级出现的概率 ,计算该灰度级的熵 ,假设以灰度级T分割图像,图像中低于T灰度级的像素点构成目标物体(O),高于灰度级T的像素点构成背景(B),那么各个灰度级在本区的分布概率为:
O区: i=1,2……,t
B区: i=t+1,t+2……L-1
上式中的 ,这样对于数字图像中的目标和背景区域的熵分别为:
对图像中的每一个灰度级分别求取W=H0 +HB,选取使W最大的灰度级作为分割图像的阈值,这就是一维最大熵阈值图像分割法。