locked
Help With Bitmap to Array RRS feed

  • Question

  • I am working on a program that retrieves the ARGB color of a bitmap and puts in into an array (preferably 3D array which will contain (pixelcolor, x-coords, y,coords) for analysis purposes) so that i can retrieve and analyze the data for every pixel of the Image. The purpose of the program is to analyze a picture - identify the object from its background and calculate the area of the object (I'm only working on 2D simple and homogenous colored images - the object is of 1 color only and the background is of also 1 color).

    Here is my code:

    Public Class Form1
    
    
    
     Dim imageBMap As Bitmap
    
    
    
     Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
    
      If MsgBox("Are you sure you want to exit?", MsgBoxStyle.YesNo, "Close Application") _
    
                     = MsgBoxResult.Yes Then
    
       Me.Close()
    
      ElseIf MsgBoxResult.No Then
    
       MsgBox("Program will now resume.", MsgBoxStyle.Information, "Resume")
    
      End If
    
     End Sub
    
    
    
     Public Sub btnLoadImg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadImg.Click
    
    
    
      'load Image Dialog Property/ies
    
      dlgOpenFile.InitialDirectory = "E:\LimeWire\Documents and Projects\AE 191 VB-coded-imaging Project\_Output\Sample Images\Circle Lime.bmp"
    
    
    
      If dlgOpenFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
    
       Try
    
        imageBMap = Image.FromFile(dlgOpenFile.FileName)
    
       Catch ex As Exception
    
        MessageBox.Show("There was an error opening the bitmap." & " Please check the path and file type.")
    
       End Try
    
      End If
    
    
    
      'show image through picture box
    
      InPixBox.Image = imageBMap
    
     End Sub
    
    
    
     Private Sub btnAnalyzImg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnalyzImg.Click
    
      'declaration of needed variables
    
      Dim pixelcolor As Color
    
      Dim xPos, yPos As Integer
    
    
    
      For xPos = 0 To imageBMap.Width - 1
    
       For yPos = 0 To imageBMap.Height - 1
    
        pixelcolor = imageBMap.GetPixel(xPos, yPos)
    
       Next
    
      Next
    
    
    
     End Sub
    
    End Class
    

    My questions are:

    1. how will I get the data retrieved by the GetPixel method (ImageBMap.GetPixel(xPos, yPos)) into a 3D array (Image3DData(color of pixel, x-coords, y-coords))

    2. say i have determined the number of pixels of the object in the image. how will i convert the pixels into area units such as sq. centimeters?

    *Note: I am using VB 2008. I am new to programing especially with imaging.

    your replies will be very much helpful.

    • Edited by hlorenzl Tuesday, May 25, 2010 4:22 AM Forgot to specify Language during inserting code block.
    Tuesday, May 25, 2010 3:59 AM

Answers

  • You can't use arrays like that.

    The statement

    ReDim pxlDatArray(0, 0, 0, 0, imageBMap.Width - 1, imageBMap.Height - 1)

    is an instruction to create a 6-dimensional array in which the first four dimensions will have 1 element each.  You would therefore populate it with a value such as this:

    pxlDatArray(0,0,0,0,xpos,,ypos) = <something>

    but since those first values can only ever be zero, they are redundant.

    Are you trying to associate 4 different values with one (x,y) position - that is, a map of the image?   If so, there is no need to store the four values - just store the color, and extract each component when you need it:

    Create a 2-dimensional array of colors and put each pixel value into the correct array location:

    Dim pxlArray(Width,Height) as Color
    ...
    pxlArray(xpos, ypos) = pixelcolor

    Then you can get the A, R G or B value from that color:

    Dim GreenLevel as Integer = pxlArray(xpos, ypos).G

     

     

    • Marked as answer by hlorenzl Tuesday, May 25, 2010 6:03 AM
    Tuesday, May 25, 2010 5:48 AM

All replies

  • You haven't indicated what values this 3D array is going to hold - I have assumed that it will contain True if the pixel at that position is the color indicated by the array index, otherwise False.  This is not data efficient, but may be required for your subsequent processing.

    Public Class Form1
        
    Dim pxlArray(,,) As Boolean
        Dim imageBMap As Bitmap

        
    Dim AColor As Color = Color.Black
        
    Dim BColor As Color = Color.White

        
    Public Sub btnLoadImg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadImg.Click
            
    'load Image Dialog Property/ies
            dlgOpenFile.InitialDirectory = "E:\LimeWire\Documents and Projects\AE 191 VB-coded-imaging Project\_Output\Sample Images\Circle Lime.bmp"
            If dlgOpenFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Try
                    imageBMap = Image.FromFile(dlgOpenFile.FileName)
                
    Catch ex As Exception
                    MessageBox.Show(
    "There was an error opening the bitmap." & " Please check the path and file type.")
                
    End Try
            End If
            'show image through picture box
            inPixBox.Image = imageBMap
            
    ReDim pxlArray(1, imageBMap.Width, imageBMap.Height)
        
    End Sub

        Private Sub btnAnalyzImg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnalyzImg.Click
            
    For xPos As Integer = 0 To imageBMap.Width - 1
                
    For yPos As Integer = 0 To imageBMap.Height - 1
                    pxlArray(0, xPos, yPos) = 
    False
                    pxlArray(1, xPos, yPos) = False
                    Dim pixelcolor As Color = imageBMap.GetPixel(xPos, yPos)
                    
    If pixelcolor = AColor Then pxlArray(0, xPos, yPos) = True
                    If pixelcolor = BColor Then pxlArray(1, xPos, yPos) = True
                Next
            Next
        End Sub
    End
     Class

    Tuesday, May 25, 2010 4:21 AM
  • hmmmm.. the problem is that the image is/may not be always black and white. So i have to determine the color of each pixel through A, R, G, and B with values ranging from 0 to 255. Then, when the color of each pixel is recorded into an array, i'll let the user specify which color serves as "background" and which color serves as "object" of the picture. And then each pixel with the specified color of the object will be counted.

    thanks for your reply.

    Tuesday, May 25, 2010 4:32 AM
  • 2. say i have determined the number of pixels of the object in the image. how will i convert the pixels into area units such as sq. centimeters?

    Do you mean the actual area of the image as displayed on the user's screen?  There is no simple way to do this without knowing the physical size of the display.  AFAIK there is no way to get the physical size of the display from the operating system  - for instance, it might depend on how far the projector is placed from the wall (to use an extreme example). 

    What you could do is ask the user to indicate the size, in CM of the vertical and horizontal measurements of the image.  You know the number of pixels in the image height and width, so you can get a pixels/cm figure using the user's input, and convert that into an area using the number of pixels in the object.

    Alternatively, you could simply present the number of pixels in the object as a percentage of the total number of pixels, and allow the user to do the calculation based on what they know about the image.

    Tuesday, May 25, 2010 4:37 AM
  • Hi hlorenzl ,

    What is this ultimately leading to?

    If you are trying to move a block of color around the screen then there are easier ways to do that.

    I'm curious what is your ultimate or final aim please?

    You can have an object of any color on any color background, although if they were the same color ,

     you would not see the object unless it had an outline. From the object, its size can represent square centimetres

    or whatever you wish.

     

    Regards,

    John

     


    Please see this thread for Vb.Net learning links.>> http://social.msdn.microsoft.com/Forums/en/vbgeneral/thread/549c8895-6780-42f8-878f-2138214fdeb4
    Tuesday, May 25, 2010 4:44 AM
  • You indicated that the image will always have two colors.  There's no need to know what the A, R, G and B values are.  You can simply select pixels from the image (randomly or not) until you get two different pixel color values, and they become your AColor and BColor values.  You can ask the user which is foreground and which is background by displaying the AColor and BColor values and getting a user response.  That selection determines how you do the counting.

    Tuesday, May 25, 2010 5:07 AM
  • 2. say i have determined the number of pixels of the object in the image. how will i convert the pixels into area units such as sq. centimeters?

    Do you mean the actual area of the image as displayed on the user's screen?  There is no simple way to do this without knowing the physical size of the display.  AFAIK there is no way to get the physical size of the display from the operating system  - for instance, it might depend on how far the projector is placed from the wall (to use an extreme example). 

    What you could do is ask the user to indicate the size, in CM of the vertical and horizontal measurements of the image.  You know the number of pixels in the image height and width, so you can get a pixels/cm figure using the user's input, and convert that into an area using the number of pixels in the object.

    Alternatively, you could simply present the number of pixels in the object as a percentage of the total number of pixels, and allow the user to do the calculation based on what they know about the image.


    This is a very simple and helpful answer for #2.:D thank you very much. :)

    I'l simply display the percentage and allow the user to input the actual size of the image.

    Tuesday, May 25, 2010 5:07 AM
  • Hi hlorenzl ,

    What is this ultimately leading to?

    If you are trying to move a block of color around the screen then there are easier ways to do that.

    I'm curious what is your ultimate or final aim please?

     

    Regards,

    John

     


    Please see this thread for Vb.Net learning links.>> http://social.msdn.microsoft.com/Forums/en/vbgeneral/thread/549c8895-6780-42f8-878f-2138214fdeb4


    The desired program is simply aimed to (1) determine the object in consideration from the given picture (say a picture with a drawn circle at the center; given that the "object" in the picture has only 1 color and that the background is only of 1 color also); and (2) calculate the are of the object.

    That is all sir. :)

    Tuesday, May 25, 2010 5:13 AM
  • You indicated that the image will always have two colors.  There's no need to know what the A, R, G and B values are.  You can simply select pixels from the image (randomly or not) until you get two different pixel color values, and they become your AColor and BColor values.  You can ask the user which is foreground and which is background by displaying the AColor and BColor values and getting a user response.  That selection determines how you do the counting.


    hmmm that is much simplier then. thank you. :)

    but, i was thinking what if the user placed an image with a homogeneuos colored background but the object has different colors. say a color wheel is at the center of the picture and that the user desires to get the area of the colorwheel. so i was thinking maybe there is a need to get argb values or maybe rgb only. And if the application is able to get the argb values, then the application's purpose can be expanded to more complicated analysis and thus maybe more helpful with the user.

    Tuesday, May 25, 2010 5:21 AM
  • I have this code but I don't know what's wrong with my array. hmmm. What could be it?

    Code:

    Private Sub btnAnalyzImg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnalyzImg.Click
        'declaration of needed variables
        Dim pixelcolor As Color
        Dim A, _
          R, _
          G, _
          B As Object
        Dim xPos, yPos As Integer
        ReDim pxlDatArray(0, 0, 0, 0, imageBMap.Width - 1, imageBMap.Height - 1)
    
        For xPos = 0 To imageBMap.Width - 1
          For yPos = 0 To imageBMap.Height - 1
            pixelcolor = imageBMap.GetPixel(xPos, yPos)
            A = pixelcolor.A
            R = pixelcolor.R
            G = pixelcolor.G
            B = pixelcolor.B
            pxlDatArray = (A, R, G, B, xPos, yPos)
          Next
        Next
    
    End Sub
    Tuesday, May 25, 2010 5:27 AM
  • You can't use arrays like that.

    The statement

    ReDim pxlDatArray(0, 0, 0, 0, imageBMap.Width - 1, imageBMap.Height - 1)

    is an instruction to create a 6-dimensional array in which the first four dimensions will have 1 element each.  You would therefore populate it with a value such as this:

    pxlDatArray(0,0,0,0,xpos,,ypos) = <something>

    but since those first values can only ever be zero, they are redundant.

    Are you trying to associate 4 different values with one (x,y) position - that is, a map of the image?   If so, there is no need to store the four values - just store the color, and extract each component when you need it:

    Create a 2-dimensional array of colors and put each pixel value into the correct array location:

    Dim pxlArray(Width,Height) as Color
    ...
    pxlArray(xpos, ypos) = pixelcolor

    Then you can get the A, R G or B value from that color:

    Dim GreenLevel as Integer = pxlArray(xpos, ypos).G

     

     

    • Marked as answer by hlorenzl Tuesday, May 25, 2010 6:03 AM
    Tuesday, May 25, 2010 5:48 AM
  • Thank you very much. That serves as the answer. :)
    Tuesday, May 25, 2010 6:03 AM