Fast way to put image into rgb-matrix (vb.net)

H

Harry

Hello,

I am using a 2-dimensional matrix for image manipulation and recognition.
The x-axes is image.width pixels long and the y-axes image.height.
All fields have a RGB integer value.
To store this value from the image into the matrix I am using the
bitmap.getPixel(x,y) method because manipulating values in the matrix is
much faster than using the bitmap.setPixel(x,y,color) method.
My problem is, that the getPixel function is also very slow.
Is there a way to get the RGB values from the picture more easily?

Thanks,

Harry

P.S: the matrix looks like:
[RGB_11,RGB_12,....,RGB_1n]
[RGB_21,RGB_22,....,RGB_2n]
....
[RGB_n1,RGB_n2,....,RGB_nn]
 
F

Fergus Cooney

Hi Harry,

How are you with C ?

You could put the need-for-speed processing in a C# library using 'unsafe'
pointer manipulation. The following article gives the pros and cons plus a
sample which converts a colour bitmap to grey-scale.


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/
csharp11152001.asp

If that doesn't appeal, GetPixel() is sooo slooow, that it might be
quicker to write your bitmap to a MemoryStream, read it back into an array,
fiddle with the array and the reverse back into your bitmap.

Good luck,

Regards,
Fergus
 
J

Jeremy Cowles

Harry said:
Hello,

I am using a 2-dimensional matrix for image manipulation and recognition.
The x-axes is image.width pixels long and the y-axes image.height.
All fields have a RGB integer value.
To store this value from the image into the matrix I am using the
bitmap.getPixel(x,y) method because manipulating values in the matrix is
much faster than using the bitmap.setPixel(x,y,color) method.
My problem is, that the getPixel function is also very slow.
Is there a way to get the RGB values from the picture more easily?

This is really a question for the dotnet.Framework.Drawing group, but I
might know a way to speed things up; Have you tried using the LockBits( )
function on the bitmaps? It will return a 1 dimensional array of values in
the current bitmap format. The array looks like this (depending on the
bitmap format):

{r,g,b,r,g,b,r,g,b,r,g,b}

By reading the properties of the BitmapData structure, you can determine how
to loop through the structure so you get one pixel each pass (stepping).
Here is some code I was playing with to invert an image (it is hard-coded
for 32bpp ARGB, and will convert your buffer image to this format
[bmpBuffer]):


'-------------------------------8<----------------------------
'// warning: this is not optimised at all!
'
Sub Invert(bmpBuffer as Bitmap)
Dim bts As Drawing.Imaging.BitmapData
Dim b() As Byte
Dim Y, iBDIndex, X As Integer
Dim bmTemp As New Bitmap(bmpBuffer.Width, bmpBuffer.Height, _
Drawing.Imaging.PixelFormat.Format32bppRgb)

Dim g As Graphics = Graphics.FromImage(bmTemp)

ReDim b((bmpBuffer.Width * 4) * (bmpBuffer.Height))

g.DrawImage(bmpBuffer, 0, 0)
g.Dispose()

bts = bmTemp.LockBits(New Rectangle(0, 0, bmpBuffer.Width, _
bmpBuffer.Height), Drawing.Imaging.ImageLockMode.ReadWrite, _
Drawing.Imaging.PixelFormat.Format32bppArgb)

Runtime.InteropServices.Marshal.Copy(bts.Scan0, b, 0,
((bmpBuffer.Width) * 4) _
* (bmpBuffer.Height))

iBDIndex = 0

'// divides by 4, and steps by 4 because it is ARGB 32bpp

For Y = 0 To (bmpBuffer.Height - 1)
For X = 0 To ((UBound(b) / 4) / (bmpBuffer.Height)) - 1
b(iBDIndex) = Not b(iBDIndex)
b(iBDIndex + 1) = Not b(iBDIndex + 1)
b(iBDIndex + 2) = Not b(iBDIndex + 2)
iBDIndex += 4
Next
Next

Runtime.InteropServices.Marshal.Copy(b, 0, bts.Scan0, _
((bmpBuffer.Width) * 4) * (bmpBuffer.Height))

bmTemp.UnlockBits(bts)

picMain.Image.Dispose()
bmpBuffer.Dispose()
bmpBuffer = New Bitmap(bmTemp)
bmTemp.Dispose()
End Sub
'-------------------------------8<----------------------------

A good site for drawing is http://www.vbaccelerator.com/ and the Drawing
newsgroup (microsoft.public.dotnet.framework.drawing).

HTH,
Jeremy
 
J

Jeremy Cowles

Fergus Cooney said:
Hi Harry,

How are you with C ?

You could put the need-for-speed processing in a C# library using 'unsafe'
pointer manipulation. The following article gives the pros and cons plus a
sample which converts a colour bitmap to grey-scale.

When I posted a similar topic to the Preformance group (asking if C++ would
execute faster given a standard algorithm), one of the guys from MS JIT
compiler team was saying that there is no way C++/C would be faster than
..NET unless you made the GC to work overtime. I thought that was wierd, but
he was very insistant that the IL code should execute just as fast as the
C/C++ native ASM...


~
Jeremy
 
H

Herfried K. Wagner [MVP]

Hello,

Fergus Cooney said:
You could put the need-for-speed processing in a C#
library using 'unsafe' pointer manipulation. The following article
gives the pros and cons plus a sample which converts a
colour bitmap to grey-scale.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/
csharp11152001.asp

Additional information:

Part 1: http://www.codeproject.com/cs/media/csharpgraphicfilters11.asp
Part 2: http://www.codeproject.com/cs/media/csharpfilters.asp
Part 3: http://www.codeproject.com/cs/media/edge_detection.asp
Part 4: http://www.codeproject.com/cs/media/imageprocessing4.asp
Part 5: http://www.codeproject.com/cs/media/DisplacementFilters.asp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top