Results 1 to 27 of 27

Thread: Grayscale Values Of Picture

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Question Grayscale Values Of Picture

    Hello Everybody!!!
    I'm working on a programm(Image Comparing) and i need to take the grayscale pixel values of a picture that i load on picturebox.I used the Picture1.Point(i, j) but I'm receiving a big number like 12961221.What does this mean exactly?Is it an RGB value?
    Then I used this, to take all three values for each pixel->colRed = (Values(i, j) And &HFF&)
    colGreen = (Values(i, j) And &HFF00&) / &H100
    colBlue = (Values(i, j) And &HFF0000) / &H10000
    Values(i, j) is the array where a store the values before printing them in a file.
    Does anybody know how i can get the grayscale values from a grayscale picture that i load in a picturebox?Is it possible.
    Thank you!!!

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Grayscale Values Of Picture

    Welcome to VBForums

    The big number isn't quite an RGB value, it is a Long (big Integer) which contains the same info (in the format the graphics card wants it); your code is used to separate it into the R G and B components.

    For grayscale images, all three components (R, G, and B) should have the same value, so I would expect your colRed/colGreen/colBlue variables to all have the same value in them.


    As for extracting the values from a picture that is already grayscale, you can use exactly the same method - but arguably should only save one of the components (as the other two will be the same).

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Thank you si the geek for your tips!!!They are very helpfull!!!
    I will ad them to my project.Another problem that i have is that only the first pixel has the correct number of R G B values.What i mean:if the fist pixel is red then i get this result 255 colRed 255 colGreen 0 colBlue 0 that is correct.But if the second is blue then i get this 16711680 colRed 255 colGreen 0 colBlue 0 that is not correct(the same as red).I don't know why.Must be something in my code.
    Code
    Picture1.ScaleMode = vbPixels
    ReDim Values(0 To Picture1.ScaleWidth, 0 To Picture1.ScaleHeight) As Long
    Dim i, j As Integer
    For i = 0 To Picture1.ScaleWidth - 1
    For j = 0 To Picture1.ScaleHeight - 1
    Values(i, j) = Picture1.Point(i, j)
    colRed = (Values(i, j) And &HFF&)
    colGreen = (Values(i, j) And &HFF00&) / &H100
    colBlue = (Values(i, j) And &HFF0000) / &H10000
    Next j
    Next i
    Dim IntFileNum As Integer
    IntFileNum = FreeFile
    Open "C:\\Image Values.txt" For Output As #IntFileNum
    Print #IntFileNum, ("Image Values For Each Pixel Are")
    For i = 0 To Picture1.ScaleWidth - 1
    For j = 0 To Picture1.ScaleHeight - 1
    Print #IntFileNum, , (Values(i, j) & " " & "Pixel Position " _
    & j & " " & i & " " & "colRed" & " " & colRed & " " & "colGreen" _
    & " " & colGreen & " " & "colBlue" & " " & colBlue)
    Next j
    Next i
    Close #IntFileNum
    MsgBox "Done"

    If you see something that could cause this wrong results let me know

    For the greyscale value should i do this (red+green+blue)/3 and then combine it with my array Values(i, j) = RGB (grayValue,grayValue,GrayValue)?

    Thank you!!!

  4. #4
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Grayscale Values Of Picture

    Quote Originally Posted by Paytor
    For the greyscale value should i do this (red+green+blue)/3 and then combine it with my array Values(i, j) = RGB (grayValue,grayValue,GrayValue)?
    Yes, that is correct.

    As for the wrong values, from memory those calculations aren't quite correct.
    Quote Originally Posted by si_the_geek
    VB Code:
    1. iRed = lColour And &HFF
    2. iGreen = (lColour \ &H100) And &HFF
    3. iBlue = lColour \ &H10000
    Try those..

    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  5. #5
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Grayscale Values Of Picture

    Ah yes, that's a bit more accurate (the version you had is prone to rounding errors).

    As to the reason for the strange data, it is happening because you are using the first loop to set the variable values, but not using them - so the values get overwritten before they are used (the variables will only contain the last value).

    What you need to do to fix it is merge your two loops, eg:
    VB Code:
    1. Picture1.ScaleMode = vbPixels
    2. ReDim Values(0 To Picture1.ScaleWidth, 0 To Picture1.ScaleHeight) As Long
    3. Dim i, j As Integer
    4. Dim IntFileNum As Integer
    5.  
    6. IntFileNum = FreeFile
    7. Open "C:\\Image Values.txt" For Output As #IntFileNum
    8. Print #IntFileNum, "Image Values For Each Pixel Are"  'there should be no brackets here
    9.  
    10. For i = 0 To Picture1.ScaleWidth - 1
    11.   For j = 0 To Picture1.ScaleHeight - 1
    12.     Values(i, j) = Picture1.Point(i, j)
    13.     colRed = Values(i, j) And &HFF
    14.     colGreen = (Values(i, j) \ &H100) And &HFF
    15.     colBlue = Values(i, j) \ &H10000
    16.     Print #IntFileNum, , (Values(i, j) & " " & "Pixel Position " _
    17.         & j & " " & i & " " & "colRed" & " " & colRed & " " & "colGreen" _
    18.         & " " & colGreen & " " & "colBlue" & " " & colBlue)
    19.  
    20.   Next j
    21. Next i
    22.  
    23. Close #IntFileNum
    24. MsgBox "Done"
    ..note that with this change, there is no need for the Values array (you could use a normal Long variable instead).

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Thank you very much!!!Know i'm getting the correct Red Green Blue Values every time the color changes.If i have another problem in my project i will let you know.
    Thanks again!!!

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Hello everybody!!!
    I have another question that i would like to ask you.Is it possible to take the values of a grayscale(1 byte per pixel) picture that is stored let's say in my "documents" without even loading it in a picturebox???
    Or should i do it the same way i have done it with the colored pictures?Loading it in a pictrurebox and then calculating the values?

  8. #8
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Grayscale Values Of Picture

    You don't have to load it into a picturebox, but its better if you want to have a visual display of the picture for your user. I rewrote your code, its a little faster (especially for larger pictures). You should be able to figure most of it out:
    VB Code:
    1. Option Explicit
    2. Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
    3. Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    4. Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal HDC As Long) As Long
    5. Private Declare Function SelectObject Lib "gdi32" (ByVal HDC As Long, ByVal hObject As Long) As Long
    6. Private Declare Function GetPixel Lib "gdi32" (ByVal HDC As Long, ByVal x As Long, ByVal y As Long) As Long
    7. Private Declare Function SetPixelV Lib "gdi32" (ByVal HDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
    8. Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    9.  
    10. Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    11.  
    12. Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
    13. Private Declare Function SetDIBits Lib "gdi32" (ByVal HDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    14.  
    15. Private Const SRCCOPY = &HCC0020
    16.  
    17. Private ImgData() As Byte
    18. Private PicInfo As BITMAP
    19. Private DIBInfo As BITMAPINFO
    20.  
    21. Private Type BITMAP
    22.   bmType As Long
    23.   bmWidth As Long
    24.   bmHeight As Long
    25.   bmWidthBytes As Long
    26.   bmPlanes As Integer
    27.   bmBitsPixel As Integer
    28.   bmBits As Long
    29. End Type
    30.  
    31. Private Type BITMAPINFOHEADER
    32.    biSize As Long
    33.    biWidth As Long
    34.    biHeight As Long
    35.    biPlanes As Integer
    36.    biBitCount As Integer
    37.    biCompression As Long
    38.    biSizeImage As Long
    39.    biXPelsPerMeter As Long
    40.    biYPelsPerMeter As Long
    41.    biClrUsed As Long
    42.    biClrImportant As Long
    43. End Type
    44.  
    45. Private Type RGBQUAD
    46.    rgbBlue As Byte
    47.    rgbGreen As Byte
    48.    rgbRed As Byte
    49.    rgbReserved As Byte
    50. End Type
    51.  
    52. Private Type BITMAPINFO
    53.   bmiHeader As BITMAPINFOHEADER
    54.   bmiColors As RGBQUAD
    55. End Type
    56.  
    57. Private Sub Command1_Click()
    58. 'On Error GoTo Err:
    59. Dim hdcNew As Long
    60. Dim oldhand As Long
    61. Dim ret As Long
    62. Dim Pic As IPictureDisp
    63.  
    64. Set Pic = LoadPicture("C:\picture.jpg")
    65.  
    66. Call GetObject(Pic, Len(PicInfo), PicInfo)
    67. hdcNew = CreateCompatibleDC(0&)
    68. oldhand = SelectObject(hdcNew, Pic)
    69.  
    70. With DIBInfo.bmiHeader
    71.     .biSize = 40
    72.     .biWidth = PicInfo.bmWidth
    73.     .biHeight = PicInfo.bmHeight
    74.     .biPlanes = 1
    75.     .biBitCount = 32
    76. End With
    77.  
    78. ReDim ImgData(1 To 4, 1 To PicInfo.bmWidth, 1 To PicInfo.bmHeight) As Byte
    79.  
    80. ret = GetDIBits(hdcNew, Pic, 0, PicInfo.bmHeight, ImgData(1, 1, 1), DIBInfo, 0)
    81.  
    82. Dim i As Long, j As Long
    83. Dim r As Integer, g As Integer, b As Integer
    84. For i = 1 To PicInfo.bmWidth 'Step 1
    85.     For j = 1 To PicInfo.bmHeight 'Step -1
    86.         r = ImgData(1, i, j)
    87.         g = ImgData(2, i, j)
    88.         b = ImgData(3, i, j)
    89.        
    90.         r = (r + g + b) / 3
    91.        
    92.         ImgData(1, i, j) = r
    93.         ImgData(2, i, j) = r
    94.         ImgData(3, i, j) = r
    95.     Next j
    96. Next i
    97. ret = SetDIBits(hdcNew, Pic, 0, PicInfo.bmHeight, ImgData(1, 1, 1), DIBInfo, 0)
    98. BitBlt Me.HDC, 0, 0, PicInfo.bmWidth, PicInfo.bmHeight, hdcNew, 0, 0, SRCCOPY
    99. Refresh
    100. Set Pic = Nothing
    101. End Sub
    That grayscales an image...like you wanted

    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Thank's a lot!!!I will try this code out.

  10. #10
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Grayscale Values Of Picture

    Quote Originally Posted by Paytor
    Thank's a lot!!!I will try this code out.
    No worries. If your problem is solved, please mark the thread as resolved using the forum tools at the top of the page

    Also, I just benchmarked the two methods to see how much faster my method was.

    On an 800x600 image, your method takes 8047 milliseconds, so just over 8 seconds, to complete.

    On the same image, mine takes 719 milliseconds, so under a second to complete.

    Just a little bit of useful info

    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    The code works very nice but i must be able to know what every line does exactly and it's a bit confusing.
    I'll work with the grayscale images the same way i worked with coloured because i'm new in visual basic and it's easier for me.But at the same time i will try to undertand your code (above) because it's interesting and something new for me.
    I took the values of a grayscale picture and realised that all three values of red green and blue are the same.Example pixel 0,0 -> red=green=blue=197.So i will take only one value for each pixel.
    For the next step i want to store this values in another array.And with kind of a circle (starting from the center of the table and going "like a circle" right or left through almost the intire table) and calculating the fourier values.This values will be stored in another table(array).Does anybody have any ideas about this.Anything at all just to start.
    Thank you!!!

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    I read that if you you want to compare two arrays it's better if the table has one dimension(1*1).How can i convert my array above Values(i, j) so it will become a one dimensioned table(1*1)???Does anybody have any clue about this???The problem is how i'm going to handle the property Picture.Point(i, j) with an array (1*1).

  13. #13
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Grayscale Values Of Picture

    The theory behind that could be taken from game tile engines, in that, to get the position, you do it like so:
    Code:
    // pseudo code
    
    Values(i, j) = (j * Picture.ScaleWidth) + i
    So, if you wanted to set the value of the 5th pixel across, and 8th pixel down of an image in a 1 dimensional array, you would do it like so:
    VB Code:
    1. Sub SetPixelValue(X As Long, Y As Long, color As Long)
    2. Values((Y * PictureBox.ScaleWidth) + X) = color
    3. End Sub
    4.  
    5.  
    6. ' Call it like so
    7. SetPixelValue 5, 8, RGB(255,255,255)
    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  14. #14

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Where excactly do i add the code you posted above in my project(you see above si the geek):
    : Values(i, j) = (j * Picture.ScaleWidth) + i
    The thing i need to do is to take the values from the picture as i have done until know with the code that posted si the geek.
    The problems are 1) how i will define the array at the beggining like above:

    "ReDim Values(0 To Picture1.ScaleWidth, 0 To Picture1.ScaleHeight) As Long"
    so it will be a one dimensional array and 2)how i will use the property point of the picture in oder to take the values and store them in this one dimensional array.

    Thank's!

  15. #15
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Grayscale Values Of Picture

    You would declare the array like this:
    VB Code:
    1. Dim Values() As Long '(needs to be in the General Declarations section of the form)
    ..and re-size it like this (I think I've got the +1's etc right!):
    VB Code:
    1. ReDim Values(0 To (Picture1.ScaleWidth+1) * (Picture1.ScaleHeight+1) - 1) As Long

    And to use it, change the bit inside the loop to this:
    VB Code:
    1. SetPixelValue i, j, Picture1.Point(i, j)

  16. #16

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Hello si the geek!I did what you said but i don't understand how this will work.Are this are the only things i have to change in my code(below) because i getmany errors.At first i put the two lines that you posted above

    1) Dim Values() As Long '(needs to be in the General Declarations section of the form)

    2)ReDim Values(0 To (Picture1.ScaleWidth+1) * (Picture1.ScaleHeight+1) - 1) As Long

    like this:

    Picture1.ScaleMode = vbPixels
    ReDim Values(0 To (Picture1.ScaleWidth + 1) * (Picture1.ScaleHeight + 1) - 1) As Long
    Dim i, j, Y As Integer
    Dim IntFileNum As Integer

    IntFileNum = FreeFile
    Open "C:\\Image Values.txt" For Output As #IntFileNum
    Print #IntFileNum, "Image Values For Each Pixel Are"

    For i = 0 To Picture1.ScaleWidth - 1
    For j = 0 To Picture1.ScaleHeight - 1
    Values(i, j) = Picture1.Point(i, j)
    grayValue = Values(i, j) And &HFF
    Print #IntFileNum, , (Values(i, j) & " " & "Pixel Position " _
    & j & " " & i & " " & "grayValue" & " " & grayValue)

    Next j
    Next i

    Close #IntFileNum
    MsgBox "Done"

    but without any other changes at all i get the message "subscript out of range"

    Then i changed at all lines the Values(i , j)->Values(i* j + 1) and i didn't got any errors but the values i get are wrong.

    I also put the third line : SetPixelValue i, j, Picture1.Point(i, j)

    But i got the error : sub or Function not defined

    Where do you thing that the problem is????

  17. #17

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    I forgot to say that i putted the Dim Values() As Long In the general declarations!!!!

  18. #18
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Grayscale Values Of Picture

    To correct the "sub or Function not defined", you need to add the SetPixelValue sub from chem's post above.

    For the "subscript out of range", remove the bits inside the loop, and replace them with just the SetPixelValue line, eg:
    VB Code:
    1. ...
    2. For i = 0 To Picture1.ScaleWidth - 1
    3.   For j = 0 To Picture1.ScaleHeight - 1
    4.     SetPixelValue i, j, Picture1.Point(i, j)
    5.   Next j
    6. Next i
    7. ...


    Alternatively (to both of the above), you could put the code of the sub directly in the loop, eg:
    VB Code:
    1. ...
    2. For i = 0 To Picture1.ScaleWidth - 1
    3.   For j = 0 To Picture1.ScaleHeight - 1
    4.     Values((j * PictureBox.ScaleWidth) + i) = Picture1.Point(i, j)
    5.   Next j
    6. Next i
    7. ...

  19. #19

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Yes it works correct so far.If i have any problem i'll let you know.
    Thank's!!!

  20. #20

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    The next step i have to make is to caculate the fourier values of every pixel.For the begging i will calculate the fourier value for a speciffic pixel in my picture.I already have the RGB value with code that we have worked so far and now i must calculate the fourier value from the RGB value that is stored in my array(Values (i , j))
    I have something in mind and i will post it soon.If aybody has any ideas let me know!

    Thank's!

  21. #21
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Grayscale Values Of Picture

    Are you using the multidimensional array still? Why exactly are you required to use a fourier technique on the image? Last I knew that was designed for simplifying the transmition of images across a radio signal

    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  22. #22

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Hello again.About the fourier values you are asking.When you you work the fourier technique through a grayscale image you can make it look better(removes the white spots).I have to calculate the real and image part from the value of a pixel.
    First i wan't to take only the grayvalue that i calculate (above) from the arrays Values(i , j) (one dimension and two dimension) and put it in another arrays so it has only this value stored in it.How can i perform that???
    And second i wan't calculate (at first only one pixel that i choose) the real( Cos ) and image ( Sin ) discrete fourier transform of that value.Any ideas?????
    Thank's!!!

  23. #23
    G&G Moderator chemicalNova's Avatar
    Join Date
    Jun 2002
    Location
    Victoria, Australia
    Posts
    4,246

    Re: Grayscale Values Of Picture

    I have no idea how to implement the fourier technique. I've only read minor documents on it a while ago. Your best bet is Google.

    Sorry

    chem

    Visual Studio 6, Visual Studio.NET 2005, MASM

  24. #24

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Ok about the discrete fourier transform.What about the other question i'm asking.How can i take only the grayvalues that i calculate from the array Values(i , j) and put it in onother array so it has only this stored in it,in both (one dimensional and two dimensional) ways????
    Thank's!!!

  25. #25

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    About the discrete fourier values.I have thought of something.I calculate the image and real part of the pixel values that i have stored in the file "Values.txt".But i'm not if the code is 100% correct because the numbers i get aren't quite wright.Here are the two parts of the code.Can you see any mistakes????
    Code
    Dim values(10)
    PI =3.1415926
    Dim File As Integer
    Dim File2 As Integer
    File = FreeFile
    Open "C:\\Image Values1.txt" For Input As #File
    For i = 0 To 9
    Line Input #File, Values(i)
    Next i
    Close #File
    File2 = FreeFile
    Open "C:\\Fourier Values1.txt" For Output As #File2
    Print #File2, ("Here are the results:")
    For j = 0 To 9
    real = 0#
    imag = 0#
    For k = 0 To 9
    real = real + Values(k) * Cos((2 * PI * k * j) / i)
    imag = imag + Values(k) * Sin((2 * PI * k * j) / i)
    Next k
    Print #File2, imag / i, real / i
    Next j
    Close #File2
    Close #File
    MsgBox ("Finished")
    i,j,k As integer and real,imag,PI As double!Does anybody see any mistakes.If so let me know!
    Thank's!

  26. #26

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2006
    Posts
    322

    Re: Grayscale Values Of Picture

    Wright is Dim Values(10)

  27. #27
    Fanatic Member namrekka's Avatar
    Join Date
    Feb 2005
    Location
    Netherlands
    Posts
    639

    Re: Grayscale Values Of Picture

    I don't know what you want to accomplish with Fourier in pictures. For pictures you must do 2 dimensional FFT but the result is not understandable for humans. It is only done to process the image in a certain domain. Study these links. The first is verry useful and has examples in "universal" Basic.

    http://www.dspguide.com/

    http://local.wasp.uwa.edu.au/~pbourke/other/

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width