navajo Posted August 21, 2006 Posted August 21, 2006 (edited) Ok, this sounds strange, but I've been working on this in two directions, on with hex (what a mess) and one with in Dec. here is what I have currently. I attempt to average the colors in Dec. and come up with an odd skew' to my color average. I believe i need to work in hex and average each RGB segment and rebuild it. But I'm lost on how to even start to do that. - Navajo expandcollapse popup; attempt to average colors across a 3x3 area within AutoIT #include <Color.au3> $basepoint_x = 41 $basepoint_y = 256 AutoItSetOption("PixelCoordMode", 2) run("c:\Program Files\Internet Explorer\iexplore.exe http://www.kondrashov.org/color.print.test.page.jpg") sleep(100) WinWaitActive("http://www.kondrashov.org/") sleep(100) Global $a[4][4] $a[1][1] = PixelGetColor($basepoint_x -1, $basepoint_y -1) $a[1][2] = PixelGetColor($basepoint_x -1, $basepoint_y) $a[1][3] = PixelGetColor($basepoint_x -1, $basepoint_y +1) $a[2][1] = PixelGetColor($basepoint_x, $basepoint_y -1) $a[2][2] = PixelGetColor($basepoint_x, $basepoint_y) $a[2][3] = PixelGetColor($basepoint_x, $basepoint_y +1) $a[3][1] = PixelGetColor($basepoint_x +1, $basepoint_y -1) $a[3][2] = PixelGetColor($basepoint_x +1, $basepoint_y) $a[3][3] = PixelGetColor($basepoint_x +1, $basepoint_y +1) ; Get average $c = 0 $string = " our string is:" & @CRLF for $x = 1 to 3 for $y = 1 to 3 $string = $string & " [" & $x & "]" & "[" & $y & "] = " & $a[$x][$y] & " " & Hex($a[$x][$y]) & @CRLF $c = $c + $a[$x][$y] Next Next $a[0][0] = Round($c / 9 ) $string2 = "Color average is: " & $a[0][0] MsgBox(1, "color average", $string & $string2 & Hex($a[0][0])) Edited August 21, 2006 by navajo
Smorg Posted August 21, 2006 Posted August 21, 2006 why do you need this? isn't that exactly what pixelchecksum does?
navajo Posted August 21, 2006 Author Posted August 21, 2006 (edited) Currently I'm working on a test bed system that has problems with color pallets, I would like to grab an areas around a set point and pull in the averages around that point. Not the checksum. As the manual says. A checksum only allows you to see if "something" has changed in a region - it does not tell you exactly what has changed. and this is not an average. I need a ratio across the pixel, not a checksum. Edited August 21, 2006 by navajo
Rad Posted August 21, 2006 Posted August 21, 2006 So um... basically are you trying to blend the colors together? I did a few tests and yours is close, but the tint is off pretty bad expandcollapse popup; attempt to average colors across a 3x3 area within AutoIT #include <Color.au3> #include <GUIConstants.au3> #include <IE.au3> $basepoint_x = 41 $basepoint_y = 256 AutoItSetOption("PixelCoordMode", 2) $ie = _IECreate("http://www.kondrashov.org/color.print.test.page.jpg") _IELoadWait($ie) sleep(100) WinWaitActive("http://www.kondrashov.org/") sleep(100) Global $a[4][4] $a[1][1] = PixelGetColor($basepoint_x -1, $basepoint_y -1) $a[1][2] = PixelGetColor($basepoint_x -1, $basepoint_y) $a[1][3] = PixelGetColor($basepoint_x -1, $basepoint_y +1) $a[2][1] = PixelGetColor($basepoint_x, $basepoint_y -1) $a[2][2] = PixelGetColor($basepoint_x, $basepoint_y) $a[2][3] = PixelGetColor($basepoint_x, $basepoint_y +1) $a[3][1] = PixelGetColor($basepoint_x +1, $basepoint_y -1) $a[3][2] = PixelGetColor($basepoint_x +1, $basepoint_y) $a[3][3] = PixelGetColor($basepoint_x +1, $basepoint_y +1) ; Get average $c = 0 $string = " our string is:" & @CRLF for $x = 1 to 3 for $y = 1 to 3 $string = $string & " [" & $x & "]" & "[" & $y & "] = " & $a[$x][$y] & " " & Hex($a[$x][$y]) & @CRLF $c = $c + $a[$x][$y] Next Next $a[0][0] = Round($c / 9 ) $string2 = "Color average is: " & $a[0][0] MsgBox(1, "color average", $string & $string2 &@CRLF& Hex($a[0][0]) &@CRLF&"0x" & StringTrimLeft(Hex($a[0][0]),2)) GUICreate("test") For $i = 1 To 3 For $ii = 1 to 3 GUICtrlCreateLabel("",$i*30-30,$ii*30-30,30,30) GUICtrlSetBkColor(-1,$a[$i][$ii]) Next Next GUICtrlCreateLabel("",90,0,90,90) GUICtrlSetBkColor(-1,"0x" & StringTrimLeft(Hex($a[0][0]),2)) GUISetState() While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit Wend Labels can help you with visualizing it rather than using math for it all lol
PsaltyDS Posted August 21, 2006 Posted August 21, 2006 (edited) So um... basically are you trying to blend the colors together? I did a few tests and yours is close, but the tint is off pretty bad expandcollapse popup; attempt to average colors across a 3x3 area within AutoIT #include <Color.au3> #include <GUIConstants.au3> #include <IE.au3> $basepoint_x = 41 $basepoint_y = 256 AutoItSetOption("PixelCoordMode", 2) $ie = _IECreate("http://www.kondrashov.org/color.print.test.page.jpg") _IELoadWait($ie) sleep(100) WinWaitActive("http://www.kondrashov.org/") sleep(100) Global $a[4][4] $a[1][1] = PixelGetColor($basepoint_x -1, $basepoint_y -1) $a[1][2] = PixelGetColor($basepoint_x -1, $basepoint_y) $a[1][3] = PixelGetColor($basepoint_x -1, $basepoint_y +1) $a[2][1] = PixelGetColor($basepoint_x, $basepoint_y -1) $a[2][2] = PixelGetColor($basepoint_x, $basepoint_y) $a[2][3] = PixelGetColor($basepoint_x, $basepoint_y +1) $a[3][1] = PixelGetColor($basepoint_x +1, $basepoint_y -1) $a[3][2] = PixelGetColor($basepoint_x +1, $basepoint_y) $a[3][3] = PixelGetColor($basepoint_x +1, $basepoint_y +1) ; Get average $c = 0 $string = " our string is:" & @CRLF for $x = 1 to 3 for $y = 1 to 3 $string = $string & " [" & $x & "]" & "[" & $y & "] = " & $a[$x][$y] & " " & Hex($a[$x][$y]) & @CRLF $c = $c + $a[$x][$y] Next Next $a[0][0] = Round($c / 9 ) $string2 = "Color average is: " & $a[0][0] MsgBox(1, "color average", $string & $string2 &@CRLF& Hex($a[0][0]) &@CRLF&"0x" & StringTrimLeft(Hex($a[0][0]),2)) GUICreate("test") For $i = 1 To 3 For $ii = 1 to 3 GUICtrlCreateLabel("",$i*30-30,$ii*30-30,30,30) GUICtrlSetBkColor(-1,$a[$i][$ii]) Next Next GUICtrlCreateLabel("",90,0,90,90) GUICtrlSetBkColor(-1,"0x" & StringTrimLeft(Hex($a[0][0]),2)) GUISetState() While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit Wend Labels can help you with visualizing it rather than using math for it all lol I'm not sure I understand the problem, but here is an untested function that should give you the pixel color average of a 3x3 block, centered around the given x/y coordinate: ; ======================= ; Function _PixelAvg($x, $y) ; Reads 3x3 pixel block centered around $x/$y ; Returns average color in 0xRRGGBB format ; Returns 0 and sets @error = 1 if invalid coordinates ; ======================= Func _PixelAvg($x, $y) Local $row, $col, $color, $avgR = 0, $avgG = 0, $avgB = 0 For $col = -1 To 1 For $row = -1 To 1 $color = PixelGetColor($x + $col, $y + $row) If $color = -1 Then Return SetError(1, 0, 0) $avgR += BitShift(BitAnd($color, 0xFF0000), 16) $avgG += BitShift(BitAnd($color, 0x00FF00), 8) $avgB += BitAnd($color, 0xFF) Next Next $color = BitAnd(BitShift(Round($avgR / 9), -16), BitShift(Round($avgG / 9), -8), Round($avgB / 9)) Return $color EndFunc Hope that helps! Edit: Tweak typo in code... Edit2: Doh! Another typo... mixed up RGB to RBG Edited August 21, 2006 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
PsaltyDS Posted August 21, 2006 Posted August 21, 2006 (edited) Hmm... Got a chance to test it and the mask/shift ops don't produce expected results, don't know why. So I changed it to the following, which tested OK: $Xcoord = 100 $Ycoord = 100 $Result = _PixelAvg($Xcoord, $Ycoord) MsgBox(64, "Test", "Avg at " & $Xcoord & "/" & $Ycoord & " is: " & Hex($Result) & " @error = " & @error) ; ======================= ; Function _PixelAvg($x, $y) ; Reads 3x3 pixel block centered around $x/$y ; Returns average color in 0xRRGGBB format ; Returns 0 and sets @error = 1 if invalid coordinates ; ======================= Func _PixelAvg($x, $y) Local $row, $col, $color, $avgR = 0, $avgG = 0, $avgB = 0 For $col = -1 To 1 For $row = -1 To 1 $color = PixelGetColor($x + $col, $y + $row) If $color = -1 Then Return SetError(1, 0, 0) $avgR += BitShift(BitAND($color, 0xFF0000), 16) $avgG += BitShift(BitAND($color, 0x00FF00), 8) $avgB += BitAND($color, 0xFF) Next Next $avgR = Round($avgR / 9) $avgG = Round($avgG / 9) $avgB = Round($avgB / 9) $color = ($avgR * 256 * 256) + ($avgG * 256) + $avgB Return $color EndFunc ;==>_PixelAvg Edited August 21, 2006 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Paulie Posted August 21, 2006 Posted August 21, 2006 so you're trying to add the red green and blue values of a pixel and then divide by three right? that will give you a grey-ish color, though of doing a similar thing in my greyscale filter, but found a better algorithim what is the purpose of this?
PsaltyDS Posted August 21, 2006 Posted August 21, 2006 so you're trying to add the red green and blue values of a pixel and then divide by three right? that will give you a grey-ish color, though of doing a similar thing in my greyscale filter, but found a better algorithimwhat is the purpose of this?That wasn't my impression of what was desired. I think he wants to break out the R, G, and B portion of the color, get the average of each primary color, and reassemble that to an average color for the 3x3 grid. This is what my function is attempting to do, anyway. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Paulie Posted August 21, 2006 Posted August 21, 2006 That wasn't my impression of what was desired. I think he wants to break out the R, G, and B portion of the color, get the average of each primary color, and reassemble that to an average color for the 3x3 grid. This is what my function is attempting to do, anyway. Okay, now I'm REALLY confused Is he looking for _ColorGetRed()_ColorGetGreen()_ColorGetBlue()the "Average" color for ANY RGB value is going to be either black, grey, or whitelook at The interactive flash thing HERE for proofset those sliders to any numbers you want, the average the decimal values, and set them to the result, and you will see that it turns out gray
PsaltyDS Posted August 21, 2006 Posted August 21, 2006 Okay, now I'm REALLY confused Is he looking for _ColorGetRed()_ColorGetGreen()_ColorGetBlue()the "Average" color for ANY RGB value is going to be either black, grey, or whitelook at The interactive flash thing HERE for proofset those sliders to any numbers you want, the average the decimal values, and set them to the result, and you will see that it turns out grayWell, we need to hear from navajo to see if I've misunderstood him, but...Assume a block of 9 pixels (3x3) that are the following colors coordinates are relative to the center pixel:-1,-1 = 0xFF0000 ; Red0, -1 = 0x00FF00 ; Green1, -1 = 0xFFFF00 ; Red/Green-1,0 = 0xFF0000 ; Red0, 0 = 0x00FF00 ; Green1, 0 = 0xFFFF00 ; Red/Green-1,1 = 0xFF0000 ; Red0, 1 = 0x00FF00 ; Green1, 1 = 0xFFFF00 ; Red/GreenMy script breaks each pixel's color into R, G, and B values and adds all the Reds together, all the Greens together, and all the Blues together. Then it divides each by 9, giving the average redness, average greeness, and average blueness. Lastly those three averaged tints are recombined into a single average RGB color.-1,-1 = 0xFF0000 ; Red = FF, 00, 000, -1 = 0x00FF00 ; Green = 00, FF, 001, -1 = 0xFFFF00 ; Red/Green = FF, FF, 00-1,0 = 0xFF0000 ; Red = FF, 00, 000, 0 = 0x00FF00 ; Green = 00, FF, 001, 0 = 0xFFFF00 ; Red/Green = FF, FF, 00-1,1 = 0xFF0000 ; Red = FF, 00, 000, 1 = 0x00FF00 ; Green = 00, FF, 001, 1 = 0xFFFF00 ; Red/Green = FF, FF, 00Add up the Reds:FF + 00 + FF + 00 + FF + 00 + FF + 00 + FF = 0x4FBAdd up the Greens:00 + FF + 00 + FF + 00 + FF + 00 + FF + 00 = 0x3FCAdd up the Blues:0 + 0 + 0+ 0 + 0+ 0 + 0+ 0 + 0 = 0Average each color (separately):0x4FB / 9 = 0x8D ; Average redness0x3FC / 9 = 0x71 ; Average greeness0 / 9 = 0 ; Average bluenessAssemble the average component colors into a single average color:RGB = 8D, 71, 00 = 0x8D7100So the average color of those 9 pixels is 0x8D7100. At least, as I understand it, and my code above calculates it. What are the other theories? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Paulie Posted August 21, 2006 Posted August 21, 2006 Well, we need to hear from navajo to see if I've misunderstood him, but...Assume a block of 9 pixels (3x3) that are the following colors coordinates are relative to the center pixel:-1,-1 = 0xFF0000 ; Red0, -1 = 0x00FF00 ; Green1, -1 = 0xFFFF00 ; Red/Green-1,0 = 0xFF0000 ; Red0, 0 = 0x00FF00 ; Green1, 0 = 0xFFFF00 ; Red/Green-1,1 = 0xFF0000 ; Red0, 1 = 0x00FF00 ; Green1, 1 = 0xFFFF00 ; Red/GreenMy script breaks each pixel's color into R, G, and B values and adds all the Reds together, all the Greens together, and all the Blues together. Then it divides each by 9, giving the average redness, average greeness, and average blueness. Lastly those three averaged tints are recombined into a single average RGB color.-1,-1 = 0xFF0000 ; Red = FF, 00, 000, -1 = 0x00FF00 ; Green = 00, FF, 001, -1 = 0xFFFF00 ; Red/Green = FF, FF, 00-1,0 = 0xFF0000 ; Red = FF, 00, 000, 0 = 0x00FF00 ; Green = 00, FF, 001, 0 = 0xFFFF00 ; Red/Green = FF, FF, 00-1,1 = 0xFF0000 ; Red = FF, 00, 000, 1 = 0x00FF00 ; Green = 00, FF, 001, 1 = 0xFFFF00 ; Red/Green = FF, FF, 00Add up the Reds:FF + 00 + FF + 00 + FF + 00 + FF + 00 + FF = 0x4FBAdd up the Greens:00 + FF + 00 + FF + 00 + FF + 00 + FF + 00 = 0x3FCAdd up the Blues:0 + 0 + 0+ 0 + 0+ 0 + 0+ 0 + 0 = 0Average each color (separately):0x4FB / 9 = 0x8D ; Average redness0x3FC / 9 = 0x71 ; Average greeness0 / 9 = 0 ; Average bluenessAssemble the average component colors into a single average color:RGB = 8D, 71, 00 = 0x8D7100So the average color of those 9 pixels is 0x8D7100. At least, as I understand it, and my code above calculates it. What are the other theories? OHHH, thats a pretty nifty idea that makes sense, but i don't see whats wrong in your code
PsaltyDS Posted August 21, 2006 Posted August 21, 2006 OHHH, thats a pretty nifty idea that makes sense, but i don't see whats wrong in your code Nothing at all wrong with the code in my post #6 in this thread. We just haven't heard from navajo if it answers his question or not... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
navajo Posted August 21, 2006 Author Posted August 21, 2006 Yes, thats exactly what I was looking to do, I just could not figure out how to pull out the colors, thank you! That wasn't my impression of what was desired. I think he wants to break out the R, G, and B portion of the color, get the average of each primary color, and reassemble that to an average color for the 3x3 grid. This is what my function is attempting to do, anyway.
Paulie Posted August 21, 2006 Posted August 21, 2006 (edited) Nothing at all wrong with the code in my post #6 in this thread. We just haven't heard from navajo if it answers his question or not... Oh... i misread, I saw the "...masks/shifts didn't produce expected results..." and jump too conclusions without finishing the sentanceEDIT:@Navajo-Glad all worked out for you Edited August 21, 2006 by Paulie
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now