Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
vb.net中的图像二值化_Vb.net_Image_Gdi+ - Fatal编程技术网

vb.net中的图像二值化

vb.net中的图像二值化,vb.net,image,gdi+,Vb.net,Image,Gdi+,请查看测试2的结果。为什么当我在photoshop中稍微调整图像大小时,输出(二进制图像)会倾斜?但是,如果我将同一图像的像素格式转换为Format32bppArgb,那么输出很好 我已经将其缩小到GetPixel()pixel方法(请参见BitmapParser类)。我不明白为什么这个方法返回了错误的像素颜色的大小图像 包括源代码 测试:1(有效输出) 源图像:Test_200x200.jpg 宽度:200 高度:200 像素格式:格式化24bpprgb 输出: 测试:2(无效输出) 源

请查看测试2的结果。为什么当我在photoshop中稍微调整图像大小时,输出(二进制图像)会倾斜?但是,如果我将同一图像的像素格式转换为Format32bppArgb,那么输出很好

我已经将其缩小到GetPixel()pixel方法(请参见BitmapParser类)。我不明白为什么这个方法返回了错误的像素颜色的大小图像

包括源代码

测试:1(有效输出)
源图像:Test_200x200.jpg
宽度:200
高度:200
像素格式:格式化24bpprgb

输出:


测试:2(无效输出)
源图像:Test_203x203.jpg(相同的图像,只是在Photoshop中稍微调整了大小)
宽度:203
高度:203
像素格式:格式化24bpprgb

输出:


测试:3(有效输出)
源图像:test203x203.jpg(与Test#2相同)
宽度:203
高度:203
像素格式:在内存中转换为格式32bppargb


输出:



测试#1和2

Private Sub ConvertJpegToBiIMage(p_fullFileName As String)
    Dim _BinaryImage As BinaryImage = Nothing
    Dim _outPutFolder As String = "C:\BinaryImages\"
    Dim _fileName As String = Path.GetFileNameWithoutExtension(p_fullFileName)
    Dim _outBoundFileName As String = _outPutFolder + "BI__" + _fileName + ".jpeg"

    _BinaryImage = New BinaryImage(Image.FromFile(p_fullFileName))
    _BinaryImage.GetImage.Save(_outBoundFileName, System.Drawing.Imaging.ImageFormat.Jpeg)
End Sub

测试#3

Private Sub ConvertJpegToBiIMage(p_fullFileName As String)
    Dim _BinaryImage As BinaryImage = Nothing
    Dim _outPutFolder As String = "C:\BinaryImages\"
    Dim _fileName As String = Path.GetFileNameWithoutExtension(p_fullFileName)
    Dim _outBoundFileName As String = _outPutFolder + "BI__" + _fileName + ".jpeg"

    Dim _bmp As Bitmap = Nothing

    Using _obmp = New Bitmap(p_fullFileName)
        _bmp = New Bitmap(_obmp.Width, _obmp.Height, Imaging.PixelFormat.Format32bppArgb)
        Using g As Graphics = Graphics.FromImage(_bmp)
            g.DrawImage(_obmp, New Rectangle(0, 0, _bmp.Width, _bmp.Height))
        End Using
    End Using

    _BinaryImage = New BinaryImage(_bmp)
    _BinaryImage.GetImage.Save(_outBoundFileName, System.Drawing.Imaging.ImageFormat.Jpeg)
End Sub

问题是图像中的填充字节。图像中每行的总字节数必须是4的倍数。因此,203像素(24bpp)的线具有
203*3=609
,这不是4的倍数。行中添加了3个字节,因此总字节数为612,是4的倍数。32bpp的图像没有这个问题,因为它总是4的倍数。谢谢。这是一个可以接受的答案。请随时发布。请注意,您不必自己进行此计算-它已在BitmapData.Stride中为您计算。问题在于图像中的填充字节。图像中每行的总字节数必须是4的倍数。因此,203像素(24bpp)的线具有
203*3=609
,这不是4的倍数。行中添加了3个字节,因此总字节数为612,是4的倍数。32bpp的图像没有这个问题,因为它总是4的倍数。谢谢。这是一个可以接受的答案。请随时发布。请注意,您不必自己进行此计算-它已在BitmapData.Stride中为您计算。
Public MustInherit Class AbstractBinaryImage
        Implements IDisposable
        Private _width As Integer
        Private _height As Integer

        ''' <summary>
        ''' Left to right, top to bottom
        ''' </summary>
        ''' <remarks></remarks>
        Private _index As Integer
        Private _pixels As Integer()

        Public ReadOnly Property Width As Integer
            Get
                Return _width
            End Get
        End Property

        Public ReadOnly Property Height As Integer
            Get
                Return _height
            End Get
        End Property

        Public ReadOnly Property PixelColor(p_x As Integer, p_y As Integer) As Integer
            Get
                Return PixelColor(p_y * Width + p_x)
            End Get
        End Property

        Public ReadOnly Property PixelColor(p_Index As Integer) As BinaryColor
            Get
                Return CType(Pixel(p_Index), BinaryColor)
            End Get
        End Property

        Public ReadOnly Property Pixel(p_x As Integer, p_y As Integer) As Integer
            Get
                Return Pixel(p_y * Width + p_x)
            End Get
        End Property

        Private ReadOnly Property Pixel(p_Index As Integer) As Integer
            Get
                Return _pixels(p_Index)
            End Get
        End Property

        Public Sub New(p_width As Integer, p_height As Integer)
            _width = p_width
            _height = p_height
            ReDim _pixels(p_width * p_height)
        End Sub

        Public Sub SetPixel(p_x As Integer, p_y As Integer, p_biColor As BinaryColor)
            _pixels(p_y * Width + p_x) = p_biColor
        End Sub

#Region "IDisposable Support"
        Private disposedValue As Boolean ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    _pixels = Nothing
                End If

                ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub

        ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
        'Protected Overrides Sub Finalize()
        '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class
    Public Class BinaryImage
        Inherits AbstractBinaryImage
        Implements IDisposable

        Private Const _DefaultThresh As Integer = 1500
        Private _bgColor As Integer = BLACK

        Private _Thresh As Integer = _DefaultThresh

        Private Function GrayRGB(p_Color As Color) As Integer
            Return CInt(((p_Color.R * 11) + (p_Color.G * 16) + (p_Color.B * 5) / 32))
        End Function

        Private Function Luminance(p_color As Color) As Integer
            Dim _rgbRed As Double = Math.Pow(p_color.R, 2)
            Dim _rgbGreen As Double = Math.Pow(p_color.G, 2)
            Dim _rgbBlue As Double = Math.Pow(p_color.B, 2)

            Return CInt(Math.Sqrt((_rgbRed * 0.299) + (_rgbGreen * 0.587) + (_rgbBlue * 0.114)))
        End Function

        Public ReadOnly Property BackgroundColor As Integer
            Get
                Return _bgColor
            End Get
        End Property

        Private Sub ParseImage(p_Image As Image)
            Dim _bmpParser As New BitmapParser(CType(p_Image, Bitmap))
            _bmpParser.LockBits()

            Dim _blackCnt As Integer = 1
            Dim _whiteCnt As Integer = 0

            For y As Integer = 0 To _bmpParser.Height - 1
                For x As Integer = 0 To _bmpParser.Width - 1

                    Dim _grgb As Integer = GrayRGB(_bmpParser.GetPixel(x, y))

                    If _grgb >= _Thresh Then
                        SetPixel(x, y, BinaryColor.Black)
                    Else
                        SetPixel(x, y, BinaryColor.White)
                    End If
                Next
            Next
            _bmpParser.UnlockBits()
        End Sub

        Public Sub New(p_image As Image)
            MyBase.New(p_image.Width, p_image.Height)
            ParseImage(p_image)
        End Sub



        Public Function GetImage() As Bitmap
            Dim _index As Integer = 0
            Dim _bmp As New Bitmap(Width, Height, Imaging.PixelFormat.Format32bppArgb)
            Dim _bmpParser As New BitmapParser(_bmp)
            _bmpParser.LockBits()
            For y As Integer = 0 To _bmpParser.Height - 1
                For x As Integer = 0 To _bmpParser.Width - 1
                    Dim _color As Color = If(Pixel(x, y) > 0, Color.White, Color.Black)
                    _bmpParser.SetPixel(x, y, _color)
                Next
            Next
            _bmpParser.UnlockBits()
            Return _bmp
        End Function

#Region "IDisposable Support"
        Private disposedValue As Boolean ' To detect redundant calls

        ' IDisposable
        Protected Overridable Shadows Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    MyBase.Dispose()
                End If

                ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub

        ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
        'Protected Overrides Sub Finalize()
        '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Shadows Sub Dispose()
            ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class
Private Sub ConvertJpegToBiIMage(p_fullFileName As String)
    Dim _BinaryImage As BinaryImage = Nothing
    Dim _outPutFolder As String = "C:\BinaryImages\"
    Dim _fileName As String = Path.GetFileNameWithoutExtension(p_fullFileName)
    Dim _outBoundFileName As String = _outPutFolder + "BI__" + _fileName + ".jpeg"

    _BinaryImage = New BinaryImage(Image.FromFile(p_fullFileName))
    _BinaryImage.GetImage.Save(_outBoundFileName, System.Drawing.Imaging.ImageFormat.Jpeg)
End Sub
Private Sub ConvertJpegToBiIMage(p_fullFileName As String)
    Dim _BinaryImage As BinaryImage = Nothing
    Dim _outPutFolder As String = "C:\BinaryImages\"
    Dim _fileName As String = Path.GetFileNameWithoutExtension(p_fullFileName)
    Dim _outBoundFileName As String = _outPutFolder + "BI__" + _fileName + ".jpeg"

    Dim _bmp As Bitmap = Nothing

    Using _obmp = New Bitmap(p_fullFileName)
        _bmp = New Bitmap(_obmp.Width, _obmp.Height, Imaging.PixelFormat.Format32bppArgb)
        Using g As Graphics = Graphics.FromImage(_bmp)
            g.DrawImage(_obmp, New Rectangle(0, 0, _bmp.Width, _bmp.Height))
        End Using
    End Using

    _BinaryImage = New BinaryImage(_bmp)
    _BinaryImage.GetImage.Save(_outBoundFileName, System.Drawing.Imaging.ImageFormat.Jpeg)
End Sub