View Single Post
 
Old 10-06-2014, 03:26 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default Speed up Edge detection

Hello,

I was playing around...
Turns out my code isn't all that fast.
For small images its more or less ok... .2 sec, but when the images become bigger lets say around 4000x4000 it takes around 40 seconds...

so the simple question beeing... does any one see or know of a methode to speed things up a little?


Code:
Imports System.Drawing
Imports EdgeDetection

Public Class EdgeDetection
	
	Private m_Original As Bitmap  
	Private m_Threshold As Double 
	
	Private m_Detected As Bitmap 
	Private m_Rectangle As Rectangle 
	Private m_Data As Imaging.BitmapData
	Private m_Ptr As IntPtr 
	Private m_ByteCount As Integer 
    Private m_RGBValues() As Byte                   ' The RGB Values
    Private m_PixelMatrix(8) As Color           ' Array of pixels. 
    Private m_Pixels() As Color


    Private Offset As Integer
    Private Index As Integer = 0
    Private Black() As Byte = {0, 0, 0}
    Private White() As Byte = {255, 255, 255}

    Public Sub New()
        Me.new(Nothing)
    End Sub
    Public Sub New(Img As Bitmap, Optional Threshold As Double = 0.001)
        Me.m_Original = Img
        Me.m_Threshold = Threshold
    End Sub

    Public Property Image As Bitmap
        Get
            Return Me.m_Original
        End Get
        Set(value As Bitmap)
            Me.m_Original = value

        End Set
    End Property
    Public ReadOnly Property Detected As Bitmap
        Get
            Detect()
            Return Me.m_Detected
        End Get
    End Property

    Private Sub Detect()
        Dim Start As Integer = System.Environment.TickCount

        m_Rectangle = New Rectangle(0, 0, Me.m_Original.Width, Me.m_Original.Height)
        m_Detected = m_Original.Clone(m_Rectangle, m_Original.PixelFormat)
        m_Data = m_Detected.LockBits(m_Rectangle, Imaging.ImageLockMode.ReadWrite, m_Detected.PixelFormat)
        ' Get the address of the first line. 
        m_ByteCount = m_Data.Stride * m_Detected.Height
        '= not RGB But BGR
        ReDim m_RGBValues(m_ByteCount) '  - 1)
        ReDim m_Pixels(Convert.ToInt32(m_ByteCount / 3))
        ' Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(m_Data.Scan0, m_RGBValues, 0, m_ByteCount)
        ' Todo: First transform to pixel array and then do the check. This way the 9 pixels aren't transformt every single time.
        Index = 0
        For I As Integer = 0 To m_ByteCount - 1 Step 3
            m_Pixels(Index) = Color.FromArgb(m_RGBValues(I + 2), m_RGBValues(I + 1), m_RGBValues(I))
            Index += 1
        Next
        ' Y
        ' |X----►
        ' |
        ' ▼
        Try
            For I As Integer = 1 To Me.m_Original.Height - 2
                For J As Integer = 1 To Me.m_Original.Width - 1
                    ' 0 0 0
                    ' 0 X 0
                    ' 0 0 0
                    Index = 0
                    For K As Integer = I - 1 To I + 1
                        For L As Integer = J - 1 To J + 1
                            m_PixelMatrix(Index) = m_Pixels((K * Me.m_Original.Width) + L)
                            Index += 1
                        Next
                    Next
                    Offset = (I * m_Data.Stride) + (J * 3)
                    If Brightest(m_PixelMatrix) - m_PixelMatrix(4).GetBrightness >= m_Threshold Then
                        System.Buffer.BlockCopy(Black, 0, m_RGBValues, Offset, 3)
                    Else
                        System.Buffer.BlockCopy(White, 0, m_RGBValues, Offset, 3)
                    End If
                Next
            Next
        Catch ex As Exception
            Debug.Print(ex.ToString)
        End Try
        ' Copy the RGB values back to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(m_RGBValues, 0, m_Data.Scan0, m_ByteCount)
        ' Unlock the bits.
        m_Detected.UnlockBits(m_Data)

        Debug.Print(((System.Environment.TickCount - Start) / 1000).ToString)
    End Sub

    Private Function Brightest(Pixels As Color()) As Double
        Brightest = Pixels(0).GetBrightness
        For i As Integer = 1 To 8
            If Pixels(i).GetBrightness > Brightest Then
                Brightest = Pixels(i).GetBrightness
            End If
        Next
    End Function
End Class
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote