Need For Speed - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Need For Speed

Dark KaiDark Kai Posts: 11Member
Hi there. I'm writing some Image Processing software in VB.Net.
I need to process image data real quick and was wondering is there such thing as processing it in memory ? Izzit the same as if my data is in a array or something ?? couze i have some functions that performs the same thing in photoshop but mine is like 10 times slower(around 3 secs while in photoshop is less then 1 sec). Hope some1 could shade some light to me. Thanks in advance.
«1

Comments

  • iwilld0itiwilld0it Posts: 1,134Member
    : Hi there. I'm writing some Image Processing software in VB.Net.
    : I need to process image data real quick and was wondering is there such thing as processing it in memory ? Izzit the same as if my data is in a array or something ?? couze i have some functions that performs the same thing in photoshop but mine is like 10 times slower(around 3 secs while in photoshop is less then 1 sec). Hope some1 could shade some light to me. Thanks in advance.
    :

    You will need to tap into win32 api if your looking for optimal speed. For instance, if you need to copy images from one surface to another extremely fast then you need the BitBlt function. Here is a link to an old messageboard response that I wrote to demonstrate how to use it.

    http://www.programmersheaven.com/c/MsgBoard/read.asp?Board=39&MsgID=152527

    Basically the function copies an image from one device context to another. For instance it can copy an image from one picturebox to another for instance. This example demonstrates calling the win32 api from VB.NET and is not the only way.

    If you need to work with image bits, I suggest looking into the GetBitmapBits and SetBitmapBits api functions. These functions also work in conjunction with the CopyMemory api function.

    Of course the direct-x api, whether its direct-x 7, 8, or 9 have a alot of functions for copying images and manipulating image bits at faster rates than the win32 api.




  • michaelBmichaelB Posts: 30Member
    : Hi there. I'm writing some Image Processing software in VB.Net.
    : I need to process image data real quick and was wondering is there such thing as processing it in memory ? Izzit the same as if my data is in a array or something ?? couze i have some functions that performs the same thing in photoshop but mine is like 10 times slower(around 3 secs while in photoshop is less then 1 sec). Hope some1 could shade some light to me. Thanks in advance.
    :
    To answer your first question about in memory; ALL data is manipulated in memory. Show me a hard drive that 'manipulates' my data and I will show you one ready to be trashed.

    A few years back Charles Petzold wrote a classic book called Programming Windows Fifth Ed. The definitive guide to the Win32 API. In this book Charles devotes over 400 pages to the bitmap, which is the native storage format for pictures. It is in and of itself a fascinating programming area. Other then loading a pic into a Picturebox I doubt there are any significant 'quick' picture manipulations.

    I have yet to explore the bitmap in .Net an exercise I look quite forward too. Having a good sound foundation of file formats, compression schemes, etc. will insure your experience with it is a good one. I do have, but have yet to read, Charles' newer book Programming Microsoft Windows with C# which has many sections devoted to the bitmap. If I had to steer back into the bitmap area this is where I would start.

    PhotoShop, as you might agree, is one of the premier software programs on the planet. Those boys and girls know their stuff. The fact that you were able to duplicate even some of their functions shows me you have talent. I encourage you, should you be able, to explore this beautiful area of programming. Again, always buy and read anything Petzold or Prosise put out. Good Luck


  • pingpongpingpong Posts: 937Member
    .NET uses GDI+ for its imaging. GDI+ has a Bitmap class that lets you load/create bitmaps. This is the equivalant of a DIB and DDB (hBitmap) in Win32 and basically your one and only native .NET source for anything image.

    This System.Drawing.Bitmap class has a method that lets you access the data directly. The LockBits method. The problem is LockBits returns a pointer to the bitmap data as an IntPtr class. This is as you might know, is a pointer. C# and C++ people will have no problem casting it to the appropriate byte*, ushort* or uint* and start changing the bitmap data directly.

    VB.NET as you are aware do not support pointers. If you insist, you need to use the Marshal.Copy, Marshal.ReadXXX/WriteXXX or Marshal.UnsafeAddrOfPinnedArrayElement to access this data from VB. This is an overkill and will add more overhead and performance hit than already is.

    But just for fun, here's code that loads a bitmap then flips it in VB.NET:
    [code]
    Sub Flip(ByVal theBitmap As Bitmap)
    ' first lock it
    Dim bd As BitmapData = theBitmap.LockBits( _
    New Rectangle(0, 0, theBitmap.Width, theBitmap.Height), _
    ImageLockMode.ReadWrite, _
    theBitmap.PixelFormat)

    ' allocate memory for 2 scan lines
    Dim row1(bd.Stride - 1) As Byte
    Dim row2(bd.Stride - 1) As Byte

    ' loop throw the scan lines
    Dim y1 As Integer = 0
    Dim y2 As Integer = bd.Height - 1

    While y1 < y2
    ' get the address of the scanline at y1 and at y2
    Dim row1Ptr = New IntPtr(bd.Scan0.ToInt32() + y1 * bd.Stride)
    Dim row2Ptr = New IntPtr(bd.Scan0.ToInt32() + y2 * bd.Stride)

    ' get scan line y1 into row1, line at y2 into row2
    Marshal.Copy(row1Ptr, row1, 0, bd.Stride)
    Marshal.Copy(row2Ptr, row2, 0, bd.Stride)

    ' put row2 into y1 and row1 into y2
    Marshal.Copy(row2, 0, row1Ptr, bd.Stride)
    Marshal.Copy(row1, 0, row2Ptr, bd.Stride)

    ' next scanline
    y1 = y1 + 1
    y2 = y2 - 1
    End While

    ' put the data back
    theBitmap.UnlockBits(bd)
    End Sub
    [/code]

  • Dark KaiDark Kai Posts: 11Member
    Thanks.
    Well I was curious couze some1 told me that are some special way to process stuff in the memory(will boost up speed alot) so i thought that i'm missing out something in my codes. Well if it is the winAPI that does some peformance enhancing then where should i start ??

    eg:
    if lets say i need to speed up some process in the following chunk of code:

    for j=0 to 500
    for i = 0 to 500
    myimage.pixel(i,j).r=128+128
    myimage.pixel(i,j).g=100+100
    myimage.pixel(i,j).b=28+39
    next
    next

    what do i do ??
    lets say all the maths equation could not be taken out of the loop.
    is this the best it could be ?? are there any other method in stead of using a loop ??
  • Dark KaiDark Kai Posts: 11Member
    Thanks. I've read in some artical saying that GDI was kindda slow for image processing. My speed isue lies within the processing not the display or loading of the image. Anyway i'll try n see if i can use any part of your code. Once again thanks alot.
  • Dark KaiDark Kai Posts: 11Member
    Thanks man. How about enhancing the speed of other processes ?like loops and recursive functions ??

    Well in vb.net i've experience a big problem with recursive functions. Always getting the stack overflow error.

  • michaelBmichaelB Posts: 30Member
    I was in the process of stealing pingpong's neat little sub for my archive (sorry pingpong) when I ran across this code from TheVB2TheMax Team [They sell CodeBox which is an application I wish I had discovered 8 years ago.] I thought it might be useful. Sure looks efficient but don't know personally.
    [code]
    ' Flip an image on one or both axes. The x and y
    ' parameters are the coordinates of the upper-left point
    ' Note: requires Imports System.Drawing.Imaging

    Sub DrawFlipImage(ByVal gr As Graphics, ByVal bmp As Bitmap, ByVal x As Single, ByVal y As Single, ByVal flipX As Boolean, ByVal flipY As Boolean)
    ' Start with values of parallelogram's vertex as if no flipping occurs.
    Dim x0 As Single = x
    Dim y0 As Single = y
    Dim x1 As Single = x + bmp.Width
    Dim y1 As Single = y
    Dim x2 As Single = x
    Dim y2 As Single = y + bmp.Height

    ' Account for horizontal flipping.
    If flipX Then
    x0 = x + bmp.Width
    x1 = x
    x2 = x0
    End If
    ' Account for vertical flipping.
    If flipY Then
    y0 = y + bmp.Height
    y1 = y0
    y2 = y
    End If
    ' Create the points array.
    Dim points() As Point = {New Point(x0, y0), New Point(x1, y1), New Point(x2, y2)}
    ' Draw the flipped image
    gr.DrawImage(bmp, points)
    End Sub
    [/code]
  • iwilld0itiwilld0it Posts: 1,134Member
    : Thanks man. How about enhancing the speed of other processes ?like loops and recursive functions ??
    :
    : Well in vb.net i've experience a big problem with recursive functions. Always getting the stack overflow error.
    :
    :

    Recursion can be dangerous if you dont have a proper stopping condition. You get stack overflows more frequently when there is alot of arguments in the function and there are alot of local variables within the function. Because each time the function recurses all those new arguments and variables get thrown on the stack memory which is a limited resource. Also all function calls in the recursion will be thrown on the stack before any are popped off the stack, so if the function recurses 10000 times you will have a huge stack. My advice to you is to see if there is an alternate way to write the function using normal DO, FOR, or WHILE loops. There may be slightly more coding but the speed difference and the conservative stack usage will be worth the effort. Dont get me wrong, there are some situations which recursion is the only solution. In those cases minimize your arguments and local variables, add a stopping condition that only allows the function to recurse so many times. You could use a static variable like so ...

    [code]
    Public Sub Recurse()
    Static count As Integer = 0
    count += 1
    If count <= 10 Then
    Call Recurse()
    Else
    Return
    End If
    End Sub
    [/code]

    This function only recurses 10 times.

    As for loops, try to declare most of your variables and initialization outside of the loop. Use variables outside the Loop instead of reinitializing the state of a local variable within a loop. Too many local variables within a loop can slow the loop because of so many create and destroy operations. Of course leave out functions that have too much processing in them. You should be able to have the state of the program ready before you jump in a loop as opposed to recreating the state of a program with each loop.

    [code]
    Dim i As Integer
    For i = 1 To 10000
    ' These are local variables
    Dim today As Date = Date.Now
    ' etc...
    Next
    [/code]

    This loop can be improved like so ...

    [code]
    Dim i As Integer
    Dim today As Date = Date.Now
    For i = 1 To 10000

    Next
    [/code]

    See there was no need to recreate the today variable with each loop so the second loop is a magnitude faster. Even though this example is trivial you can easily see how a loop may become faster if there are multiple variables involved. Here is another example ...

    [code]
    Public Sub HugeInit()
    ' Alot of initialization code
    End Sub

    Dim i As Integer

    ' Slow loop
    For i = 1 To 10000
    Call HugeInit()
    ' Do other stuff
    Next

    ' Faster loop
    Call HugeInit()
    For i = 1 To 10000
    ' Do other stuff
    Next
    [/code]

    Another thing you need to watch out for is nested loops. Using complexity theory terminology a single nested loop is an O2 process. This means that a nested loop inner and outer loops are multiplied to give you the actual number of loops that wil be processes. For example:

    [code]
    Dim i As Integer
    Dim j As Integer

    For i = 1 To 1000
    For j = 1 To 1000
    ' Process code
    Next
    Next
    [/code]

    This code loops 1,000,000 (1000 x 1000) times. Doesn't seem like much code but the net effect is huge. In practice you should not nest more than two levels deep. Each level you nest adds a greuling amount of code to process. You basically multiply each level. Also in a nested loop you can declare local variables outside the inner loop to improve speed.

    [code]
    Dim i As Integer
    Dim j As Integer

    For i = 1 To 1000
    Dim someVar As Integer = i

    For j = 1 To 1000
    someVar += j
    Next
    Next
    [/code]




  • pingpongpingpong Posts: 937Member
    Yes, that flips it too. Also you can use the Bitmap.RotateFlip method directly.

    I was just showing the original poster a way to get/set the scanlines of a .NET bitmap. Once you get the scan line in a byte array, you can do whatever image processing operation you want to it.
  • Dark KaiDark Kai Posts: 11Member
    Cool man....
    I've tried all the following but still nothing near to the job done by the guys/gal in adobe(speed wise).

    :(
    BTW : any1 have a algorithm for frame averaging ??( or any fast noise removal and image construction methods )

    i've median filter and mean filtering(kindda slow also)
«1
Sign In or Register to comment.