VB6之图像灰度与二值化

老代码备忘,我对图像处理不是太懂。

注:部分代码引援自网上,话说我到底自己写过什么代码。。。

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 Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, _
    ByVal hObject As Long) As Long
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, _
    ByVal lpDeviceName As String, _
    ByVal lpOutput As String, _
    lpInitData As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long

Private Type 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 pic As StdPicture
    Set pic = LoadPicture("D:\My Documents\Downloads\119562132_21n.jpg")

    Dim w As Long
    Dim h As Long
    With pic
        w = ScaleX(.Width, vbHimetric, vbPixels)
        h = ScaleY(.Height, vbHimetric, vbPixels)
    End With

    Dim hdc As Long
    hdc = CreateDC("DISPLAY", vbNullString, vbNullString, 0&)
    Call SelectObject(hdc, pic.Handle)

    Dim bits() As Byte
    ReDim bits(3, w, h) As Byte
    Dim bi As BitMapInfo
    With bi.bmiHeader
        .biBitCount = 32&
        .biCompression = 0&
        .biPlanes = 1&
        .biSize = Len(bi.bmiHeader)
        .biWidth = w
        .biHeight = h
    End With
    Call GetDIBits(hdc, pic.Handle, 0, h, bits(0, 0, 0), bi, 0&)

    ‘灰度化
    Dim x As Long
    Dim y As Long
    Dim g As Byte
    For x = 0 To w
        For y = 0 To h
            ‘灰度公式:Gray=R×0.299+G×0.587+B×0.114
            ‘貌似有更好的方案:g=(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)
            ‘不过,肉眼看不出差别来 (>_<)
            g = bits(0, x, y) * 0.114 + bits(1, x, y) * 0.587 + bits(2, x, y) * 0.299
            bits(0, x, y) = g
            bits(1, x, y) = g
            bits(2, x, y) = g
        Next
    Next

    Picture1.Picture = Picture1.Image
    Call SetDIBits(Picture1.hdc, Picture1.Picture.Handle, 0&, h, bits(0, 0, 0), bi, 0&)
    Picture1.Picture = Picture1.Image

    Dim threshold As Byte
    threshold = GetThreshold(bits, w, h)

    ‘二值化,阈值通过[最大类间方差法(Otsu)]取得
    For x = 0 To w
        For y = 0 To h
            If bits(0, x, y) > threshold Then
                bits(0, x, y) = 255
                bits(1, x, y) = 255
                bits(2, x, y) = 255
            Else
                bits(0, x, y) = 0
                bits(1, x, y) = 0
                bits(2, x, y) = 0
            End If
        Next
    Next

    Picture2.Picture = Picture2.Image
    Call SetDIBits(Picture2.hdc, Picture2.Picture.Handle, 0&, h, bits(0, 0, 0), bi, 0&)
    Picture2.Picture = Picture2.Image

    Erase bits
    Call DeleteDC(hdc)
    Set pic = Nothing
End Sub

Private Function GetThreshold(ByRef Pixels() As Byte, _
    ByVal Width As Long, _
    ByVal Height As Long) As Byte
    ‘最大类间方差法(Otsu)
    ‘这个函数是我根据百度文库一个文档里提供的C代码翻译过来的
    ‘@http://wenku.baidu.com/link?url=wVl9A7eZiRddxpaCPPLcAIb-VDlyrV__-Zfw6j6o50FEUochgV9G_zRVsMHVDxN2ilOUXiRbSSM-as_ELJpjxnWEvERlABlvVoVK6-FDQpW
    Dim hist(255) As Long
    Dim x As Long
    Dim y As Long
    Dim i As Long

    For i = 0 To 255: hist(i) = 0: Next
    For y = 0 To Height
        For x = 0 To Width
            hist(Pixels(0, x, y)) = hist(Pixels(0, x, y)) + 1
        Next
    Next

    Dim p(255) As Double
    Dim ut As Double
    Dim uk As Double
    Dim sigma As Double
    Dim mk As Double
    Dim maxk As Byte
    Dim maxs As Double
    Dim total As Long
    Dim EPSTLON As Double
    EPSILON = 0.000001 ‘10 ^ -6

    total = Width * Height
    ut = 0
    For i = 0 To 255
        p(i) = hist(i) / total
        ut = ut + i * hist(i)
    Next
    ut = ut / total
    wk = 0
    uk = 0
    maxs = 0
    For i = 0 To 255
        uk = uk + i * p(i)
        wk = wk + p(i)
        If wk <= EPSTLON Or wk >= (1# - EPSTLON) Then
        Else
            sigma = (ut * wk - uk)
            sigma = (sigma * sigma) / (wk * (1# - wk))
            If sigma > maxs Then
                maxs = sigma
                maxk = i
            End If
        End If
    Next
    GetThreshold = maxk
End Function

上张图,看看效果:

再来一张小妹妹的原图(抱歉啊,给你做了张黑白照),不要怪叔叔:

VB6之图像灰度与二值化,布布扣,bubuko.com

时间: 2024-10-18 22:53:04

VB6之图像灰度与二值化的相关文章

图像灰度变换、二值化、直方图

1.灰度变换 1)灰度图的线性变换 Gnew = Fa * Gold + Fb. Fa为斜线的斜率,Fb为y轴上的截距. Fa>1 输出图像的对比度变大,否则变小. Fa=1 Fb≠0时,图像的灰度上移或下移,效果为图像变亮或变暗. Fa=-1,Fb=255时,发生图像反转. 注意:线性变换会出现亮度饱和而丢失细节. 2)对数变换 t=c * log(1+s) c为变换尺度,s为源灰度,t为变换后的灰度. 对数变换自变量低时曲线斜率高,自变量大时斜率小.所以会放大图像较暗的部分,压缩较亮的部分.

图像的自适应二值化

机器视觉分为三个阶段 : 图像转化.图像分析.图像理解.若要将一幅图像转化为方便分析理解的格式,有一个很关键的过程就是"图像二值化".一幅图像能否分析理解的准确很大程度上来说取决于二值化效果的好坏.然而目前国际上还没有任何二值化标准的算法,也没相关的确定性数学模型建立.这里我大致介绍我这几天研究的鄙见. 在二值化前有一个很重要的步骤是"图像灰度化",原理就是将原RGB图像的三维矩阵进行f(x) = R*0.3+G*0.51+B*0.11运算得到一个二维矩阵(个人认为

[iOS OpenCV的使用,灰度和二值化]

看网上方法很多,但版本都不够新,我看了网上一些知识,总结了下,来个最新版Xcode6.1的. 最近主要想做iOS端的车牌识别,所以开始了解OpenCV.有兴趣的可以跟我交流下哈. 一.Opencv的使用: 步骤: 1.从官网下载iOS版本的Opencv2.framework. 2.拖进工程,选择copy items if needed 3.进入building settings,设置Framework SearchPath: 设置成$(PROJECT_DIR)/Newtest,这个Newtest

【华为云技术分享】灰度图二值化算法

[摘要] 目前最常用的快速二值化阈值确定方法为根据每一张目标图像来动态的计算平均灰度值.然后将灰度图像中的每个像素灰度值和此平均阈值作对比,高于平均阈值的记为“1”(白色),低于的则设置为“0”(黑色).这种方法虽然会让造成部分背景像素点丢失,但却是最简单高效的处理方法. 灰度图片中都可以用一个具体的灰度值Grav来量化每一个像素点.考虑到实际识别的二值特征,为了让被处理目标答题卡更加简单,计算量更少,速度更快,我们可以直接对灰度图片进行二值化处理. 图像二值化简单来说就是讲整个灰度图片的目标像

基于RGB颜色模型的图像提取与二值化

现实中我们要处理的往往是RGB彩色图像.对其主要通过HSI转换.分量色差等技术来提出目标. RGB分量灰度化: RGB可以分为R.G.B三分量.当R=G=B即为灰度图像,很多时候为了方便,会直接利用某个分量来进行灰度化,如下图所示: 上图中R分量下红色部分明显比其他两幅更偏白:同样地G分量草地较淡,B分量天空较淡.其他部分如灰黑色马路则相差不多.实际中,我们可以根据 需求有选择地选择分量. RGB分量差灰度化: 有时候我们的要求是从图像中提取某种颜色区域,那么最简单的方法就是采用RGB色差. 例

[转载+原创]Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化

局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自<OpenCV_基于局部自适应阈值的图像二值化>) 局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值.这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的.亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适

c#图像灰度化、灰度反转、二值化

图像灰度化:将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些.灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征.图像的灰度

图像 - 灰度化、灰度反转、二值化

原文地址:http://www.cnblogs.com/gdjlc/archive/2013/03/05/2943801.html 图像灰度化: 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图

【OPENCV】图像的预处理(灰度图、二值化、字符矫正(旋转))

1.首先加载原始图片: 2.cvCvtColor(img, source, CV_BGR2GRAY);转化成灰度图像: 3.cvThreshold(source,source_gray,100,255,CV_THRESH_BINARY );进行二值化处理. 由于原始的图片会有一定的角度,需要进行旋转,而旋转的话可以使用OPENCV提供的函数实现,本文中采用的是自己编写的,即通过旋转360,并记录旋转某个角度的时候使得在x轴方向的投影最大化. 如图,经过处理的图片效果如下所示: 完整的工程已经上传