Speed up Edge detection
Speed up Edge detection
Speed up Edge detection
Speed up Edge detection
Speed up Edge detection
Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection
Speed up Edge detection Speed up Edge detection
Speed up Edge detection
Go Back  Xtreme Visual Basic Talk > > > Speed up Edge detection


Reply
 
Thread Tools Display Modes
  #1  
Old 10-06-2014, 04: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
  #2  
Old 10-13-2014, 06:09 PM
dotnetwrassler dotnetwrassler is offline
Regular
 
Join Date: Sep 2014
Location: USA (Pacific/West Coast)
Posts: 71
Default Parallel Processing?

Perhaps if you created a new class to spawn separate threads to process the image in parallel?
Attached Files
File Type: zip SobelEdgeDetection.zip (277.0 KB, 17 views)
Reply With Quote
  #3  
Old 10-16-2014, 04:34 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default

Thank you for the hint, i will take a loop at your example and try to understand it. :-)
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #4  
Old 04-24-2015, 12:07 PM
Oswald Oswald is offline
Regular
 
Join Date: Apr 2005
Posts: 63
Default

- dont use expressions in for..next lines, calculate the value beforehand and put it into a var (otherwise these will be calculated on each run)
- dont use variants they are slow as hell, declare all variables
- this line calculates brightness twice. put brigtness into a var:

If Pixels(i).GetBrightness > Brightest Then
Brightest = Pixels(i).GetBrightness

- color.fromargb probably much slower, than you could do yourself, just AND's and bitshifts in the end!
- its a pointless convert anyway argb->rgb, you can extract the color just as good from argb.
- why blockcopy into rgbvalues, when its a perfectly usable array?

-Me.m_Original.Width this in the very inner loop should also be replaced to a local var. you force .net to dig trough objects a gazillion time to get that width value.

Last edited by Oswald; 04-24-2015 at 12:15 PM.
Reply With Quote
  #5  
Old 06-26-2015, 09:07 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default Tweaked the code a little...

It now run's alot faster.

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_RGBOutput() As Byte                   ' The RGB Values
    
    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.1)
        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 OriginalWidth As Integer = Me.m_Original.Width
        Dim PixelMatrix(26) As Byte
        Dim Start As Integer = System.Environment.TickCount
        Dim Offset As Integer = 0
        Dim StepSize As Integer = 3

        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)
        ReDim m_RGBOutput(m_ByteCount)
        ' Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(m_Data.Scan0, m_RGBValues, 0, m_ByteCount)
        System.Runtime.InteropServices.Marshal.Copy(m_Data.Scan0, m_RGBOutput, 0, m_ByteCount)
        Select Case m_Detected.PixelFormat
            Case Imaging.PixelFormat.Format16bppArgb1555, Imaging.PixelFormat.Format16bppGrayScale, Imaging.PixelFormat.Format16bppRgb555
            Case Imaging.PixelFormat.Format32bppArgb, Imaging.PixelFormat.Format32bppPArgb, Imaging.PixelFormat.Format32bppRgb
                Offset = 1
                StepSize = 4
        End Select
        '
        For Row As Integer = 1 To m_Detected.Height - 2
            For Column As Integer = Offset To m_Data.Stride - 9 Step StepSize
                System.Buffer.BlockCopy(m_RGBValues, ((Row - 1) * m_Data.Stride) + Column, PixelMatrix, 0, 9)
                System.Buffer.BlockCopy(m_RGBValues, (Row * m_Data.Stride) + Column, PixelMatrix, 9, 9)
                System.Buffer.BlockCopy(m_RGBValues, ((Row + 1) * m_Data.Stride) + Column, PixelMatrix, 18, 9)
                If IsBrighterThenTreshold(PixelMatrix) Then
                    System.Buffer.BlockCopy(Black, 0, m_RGBOutput, (Row * m_Data.Stride) + Column + 3, 3)
                Else
                    System.Buffer.BlockCopy(White, 0, m_RGBOutput, (Row * m_Data.Stride) + Column + 3, 3)
                End If
            Next
        Next
        ' Copy the RGB values back to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(m_RGBOutput, 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 GetBrightness(R As Double, G As Double, B As Double) As Double
        ' Return (R + R + B + G + G + G) / 6
        Return (0.2126 * R + 0.7152 * G + 0.0722 * B)
        ' Return(.299 * R^2 + .587 * G^2 + .114 * B^2)
        ' Return (R * R * 0.241 + G * G * 0.691 + B * B * 0.068) ^ 0.5
    End Function

    Private Function IsBrighterThenTreshold(RGB() As Byte) As Boolean
        Dim Current As Double
        Dim Brightest As Double = GetBrightness(RGB(0), RGB(2), RGB(1))
        For I As Integer = 3 To 26 Step 3
            Current = GetBrightness(RGB(I), RGB(I + 2), RGB(I + 1))
            If Current > Brightest Then
                Brightest = Current
            End If
        Next
        Return (Brightest - GetBrightness(RGB(12), RGB(14), RGB(13)) >= m_Threshold)
    End Function
End Class
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Speed up Edge detection
Speed up Edge detection
Speed up Edge detection Speed up Edge detection
Speed up Edge detection
Speed up Edge detection
Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection Speed up Edge detection
Speed up Edge detection
Speed up Edge detection
 
Speed up Edge detection
Speed up Edge detection
 
-->