|
-
Apr 6th, 2011, 08:27 PM
#1
Thread Starter
Hyperactive Member
[RESOLVED] A challenging pixel problem!
Hello,
Hope you are well. Any help here would be appreciated.
Here is my problem. I would like to iterate through every pixel in a jpeg image and retrieve its' colour code, storing all pixel colours for the image in an array. Finally, I will iterate through the array looking for skin tones and flagging them into a separate array. (The naughty array ) Now, I have the skin tone ranges sorted but here is the question:
What is the quickest way to go about iterating through the pixels in an image and retrieving colour code? (in vb.net)
(I have heard down the grapevine that GetPixel() can be slow, i'd ideally like to be talking a few seconds per image)
Many Thanks!
Jord
Last edited by intraman; Apr 7th, 2011 at 08:22 AM.
-
Apr 7th, 2011, 04:02 AM
#2
Re: A challenging pixel problem!
You convert any color to an Integer with Color.ToARGB. GetPixel is indeed notoriously slow, so you need to use the Bitmap.Lockbits method to convert the image to an array of data. An easy way to do that is to use my FastPix class -- see Rapid Pixel Processing in my signature below. Here's an example (not tested yet!) that copies the skin tone pixels to a 1-dimensional array called naughtyArray whose size equals the number of pixels in the jpeg. You can easily convert that to a 2D array if you want but it would be better to do that outside the loop. First store the skin colors in an Integer array (skinTones in the code below) using Color.ToARGB, and then:
Code:
Dim myBitmap = New Bitmap(myJpeg)
Using fp As New FastPix(myBitmap)
Dim pixels As Integer() = fp.PixelArray
For i As Integer = 0 To pixels.Count-1
Dim px As Integer = pixels(i)
For j As Integer = 0 To skinTones.Count-1
If px = skinTones(j) Then
naughtyArray(i) = px
Exit For
End If
Next j
Next i
End Using
My tests indicate that using FastPix with a simple Integer comparison as in my example works over 100x as fast as a similar loop using SetPixel and GetPixel. The comparison for GetPixel alone will probably be a bit less extreme but considerable all the same.
As a general rule, to get the best performance in an image processing loop like the above:
1. Use only Integer, Logical and Shift operations inside the loop. I haven't checked with floating point (Single or Double) but Integer will always be faster.
2. Avoid "anything with a dot in it" such as Color.ToArgb or Math.Round inside the loop. It takes a lot of time to resolve references to methods and objects outside the class.
BB
Last edited by boops boops; Apr 7th, 2011 at 04:20 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|