|
-
Oct 7th, 2006, 10:24 AM
#1
Thread Starter
Hyperactive Member
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!!!
-
Oct 7th, 2006, 03:13 PM
#2
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).
-
Oct 8th, 2006, 06:06 AM
#3
Thread Starter
Hyperactive Member
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!!!
-
Oct 8th, 2006, 08:08 AM
#4
Re: Grayscale Values Of Picture
 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.
 Originally Posted by si_the_geek
VB Code:
iRed = lColour And &HFF
iGreen = (lColour \ &H100) And &HFF
iBlue = lColour \ &H10000
Try those..
chem
Visual Studio 6, Visual Studio.NET 2005, MASM
-
Oct 8th, 2006, 11:41 AM
#5
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:
Picture1.ScaleMode = vbPixels
ReDim Values(0 To Picture1.ScaleWidth, 0 To Picture1.ScaleHeight) As Long
Dim i, j 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" 'there should be no brackets here
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) \ &H100) And &HFF
colBlue = Values(i, j) \ &H10000
Print #IntFileNum, , (Values(i, j) & " " & "Pixel Position " _
& j & " " & i & " " & "colRed" & " " & colRed & " " & "colGreen" _
& " " & colGreen & " " & "colBlue" & " " & colBlue)
Next j
Next i
Close #IntFileNum
MsgBox "Done"
..note that with this change, there is no need for the Values array (you could use a normal Long variable instead).
-
Oct 8th, 2006, 02:04 PM
#6
Thread Starter
Hyperactive Member
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!!!
-
Oct 9th, 2006, 06:10 AM
#7
Thread Starter
Hyperactive Member
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?
-
Oct 9th, 2006, 07:22 AM
#8
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:
Option Explicit
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
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal HDC As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal HDC As Long, ByVal hObject As Long) As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal HDC As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function SetPixelV Lib "gdi32" (ByVal HDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
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
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
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
Private Const SRCCOPY = &HCC0020
Private ImgData() As Byte
Private PicInfo As BITMAP
Private DIBInfo As BITMAPINFO
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
Private Sub Command1_Click()
'On Error GoTo Err:
Dim hdcNew As Long
Dim oldhand As Long
Dim ret As Long
Dim Pic As IPictureDisp
Set Pic = LoadPicture("C:\picture.jpg")
Call GetObject(Pic, Len(PicInfo), PicInfo)
hdcNew = CreateCompatibleDC(0&)
oldhand = SelectObject(hdcNew, Pic)
With DIBInfo.bmiHeader
.biSize = 40
.biWidth = PicInfo.bmWidth
.biHeight = PicInfo.bmHeight
.biPlanes = 1
.biBitCount = 32
End With
ReDim ImgData(1 To 4, 1 To PicInfo.bmWidth, 1 To PicInfo.bmHeight) As Byte
ret = GetDIBits(hdcNew, Pic, 0, PicInfo.bmHeight, ImgData(1, 1, 1), DIBInfo, 0)
Dim i As Long, j As Long
Dim r As Integer, g As Integer, b As Integer
For i = 1 To PicInfo.bmWidth 'Step 1
For j = 1 To PicInfo.bmHeight 'Step -1
r = ImgData(1, i, j)
g = ImgData(2, i, j)
b = ImgData(3, i, j)
r = (r + g + b) / 3
ImgData(1, i, j) = r
ImgData(2, i, j) = r
ImgData(3, i, j) = r
Next j
Next i
ret = SetDIBits(hdcNew, Pic, 0, PicInfo.bmHeight, ImgData(1, 1, 1), DIBInfo, 0)
BitBlt Me.HDC, 0, 0, PicInfo.bmWidth, PicInfo.bmHeight, hdcNew, 0, 0, SRCCOPY
Refresh
Set Pic = Nothing
End Sub
That grayscales an image...like you wanted 
chem
Visual Studio 6, Visual Studio.NET 2005, MASM
-
Oct 9th, 2006, 11:48 AM
#9
Thread Starter
Hyperactive Member
Re: Grayscale Values Of Picture
Thank's a lot!!!I will try this code out.
-
Oct 9th, 2006, 10:12 PM
#10
Re: Grayscale Values Of Picture
 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
-
Oct 10th, 2006, 05:00 AM
#11
Thread Starter
Hyperactive Member
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!!!
-
Oct 11th, 2006, 05:24 AM
#12
Thread Starter
Hyperactive Member
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).
-
Oct 11th, 2006, 06:01 AM
#13
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:
Sub SetPixelValue(X As Long, Y As Long, color As Long)
Values((Y * PictureBox.ScaleWidth) + X) = color
End Sub
' Call it like so
SetPixelValue 5, 8, RGB(255,255,255)
chem
Visual Studio 6, Visual Studio.NET 2005, MASM
-
Oct 11th, 2006, 11:42 AM
#14
Thread Starter
Hyperactive Member
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!
-
Oct 11th, 2006, 11:53 AM
#15
Re: Grayscale Values Of Picture
You would declare the array like this:
VB Code:
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:
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:
SetPixelValue i, j, Picture1.Point(i, j)
-
Oct 12th, 2006, 03:18 AM
#16
Thread Starter
Hyperactive Member
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????
-
Oct 12th, 2006, 03:20 AM
#17
Thread Starter
Hyperactive Member
Re: Grayscale Values Of Picture
I forgot to say that i putted the Dim Values() As Long In the general declarations!!!!
-
Oct 12th, 2006, 10:50 AM
#18
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:
...
For i = 0 To Picture1.ScaleWidth - 1
For j = 0 To Picture1.ScaleHeight - 1
SetPixelValue i, j, Picture1.Point(i, j)
Next j
Next i
...
Alternatively (to both of the above), you could put the code of the sub directly in the loop, eg:
VB Code:
...
For i = 0 To Picture1.ScaleWidth - 1
For j = 0 To Picture1.ScaleHeight - 1
Values((j * PictureBox.ScaleWidth) + i) = Picture1.Point(i, j)
Next j
Next i
...
-
Oct 13th, 2006, 02:05 AM
#19
Thread Starter
Hyperactive Member
Re: Grayscale Values Of Picture
Yes it works correct so far.If i have any problem i'll let you know.
Thank's!!!
-
Oct 13th, 2006, 05:08 AM
#20
Thread Starter
Hyperactive Member
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!
-
Oct 13th, 2006, 05:26 AM
#21
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
-
Oct 14th, 2006, 08:43 AM
#22
Thread Starter
Hyperactive Member
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!!!
-
Oct 14th, 2006, 09:12 AM
#23
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
-
Oct 15th, 2006, 04:33 AM
#24
Thread Starter
Hyperactive Member
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!!!
-
Oct 17th, 2006, 05:58 AM
#25
Thread Starter
Hyperactive Member
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!
-
Oct 17th, 2006, 06:00 AM
#26
Thread Starter
Hyperactive Member
Re: Grayscale Values Of Picture
-
Oct 17th, 2006, 06:25 AM
#27
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|