Jump to content

Why PixelGetColor is reported to NOT work


Recommended Posts

I don't know about games or refresh rates and graphics cards or the other discussions on this topic.

I looked at the graph you provided and am I understanding your question correctly?

You have repeatedly checked the color at the same cords and it always gives you one of two colors.

Over the course of less than any one tenth of a second, one of the colors reoccurs much less than the other and you want to know which of these two colors to ignore?

Yes, but I know which one to ignore and I cannot always predict what the "true" color is supposed to be. I wrote a very tight loop to repeatedly sample the same pixel and dump it's value to the console. Then, I plotted its value to see if infact it was changing over time and the answer is 'yes'. I do see 2 dominant values over time, however, I occasionally get some intermediate values on the rising and falling edges.

Recently I have tried to compensate for this problem by doing the following: 1) Sample the same pixel 10x and take the maximum value (I also did this with 25x, 50x, 100x, 250x), 2) Apply an 85% theshold based on a time averaged pixel buffer, and 3) Apply a finite state machine to detect the rising and falling edges of the changing pixel values. These approaches seemed to help, but then I noticed that the characteristics of the "pixel waveform" varied a bit on different hardware. Specifically, on my Dual SLI 6800 machine, the frequency of low to high changes is higher and there is an overshoot in the pixel value before it settled into the correct value. Thus my code still does not work.

I still believe that this problem is due to double buffering of the video frames to create the illusion of seamless motion.

I think this problem will have to be fixed insite the AutoIT code itself.

Attached is a copy of my attempts:

HotKeySet("^{F1}", "GetPixelColor")     ;Initialize the colors on Toolbar #1
HotKeySet("^{F9}", "Idle")      ;Initialize the colors on Toolbar #1

Global $pixelColorBase
Global $pixelColor

Idle()

;.....................................................................
Func Idle()
    While 1
    Wend
EndFunc

;.....................................................................
Func GetPixelColor()
    While 1
;       $pixelColor = PixelGetColorMax(1000,1141)
;       $pixelColor = PixelGetColorMax10(1000,1141)
;       $pixelColor = PixelGetColorMax25(1000,1141)
        $pixelColor = PixelGetColorFSMConservative(1000,1141)
;       $pixelColor = PixelGetColorFSMAggressive(1000,1141)

        ConsoleWrite($pixelColor & @CRLF)       
    Wend
EndFunc

;.....................................................................
Func PixelGetColorMax25($x, $y)
    $pixelValue1 = 0
    $pixelValue2 = 0
    For $i = 0 To 49
        $pixelValue2 = PixelGetColor($x, $y)
        If ($pixelValue1 < $pixelValue2) Then $pixelValue1 = $pixelValue2
    Next
    Return $pixelValue1 
EndFunc

;.....................................................................
Func PixelGetColorMax10($x, $y)
    $pixelValue1 = 0
    $pixelValue2 = 0
    For $i = 0 To 49
        $pixelValue2 = PixelGetColor($x, $y)
        If ($pixelValue1 < $pixelValue2) Then $pixelValue1 = $pixelValue2
    Next
    Return $pixelValue1 
EndFunc

;.....................................................................
Func PixelGetColorMax1($x, $y)
    Return PixelGetColor($x, $y)    
EndFunc

Func PixelGetColorFSMConservative($x, $y)
Local $__DETECTING = 0
Local $__FALLING = 1
Local $__FLATLOW = 2
Local $__RISING = 3
Local $__FLATHIGH = 4   
Local $count

    $state = $__DETECTING
    $p1 = PixelGetColor($x, $y)
    While 1
        $p2 = PixelGetColor($x, $y)
        Select
            Case $state == $__DETECTING
                If ($p1 > $p2) Then
                    $state = $__FALLING
                Else
                    If ($p1 < $p2) Then
                        $state = $__RISING; 
                    EndIf
                EndIf
            Case $state == $__FALLING
                If ($p1 == $p2) Then
                    $state = $__FLATLOW
                ElseIf ($p1 < $p2) Then
                        $state = $__DETECTING ;$__RISING
                EndIf
            Case $state == $__FLATLOW
                If ($p1 < $p2) Then
                    $state = $__RISING
                ElseIf ($p1 > $p2) Then
                    $state = $__DETECTING; $__FALLING
                EndIf
            Case $state == $__RISING
                If ($p1 == $p2) Then
                    $state = $__FLATHIGH
                    $count = 1
                ElseIf ($p1 > $p2) Then
                        $state = $__DETECTING; $__FALLING
                EndIf
            Case $state == $__FLATHIGH
                If ($p1 == $p2) Then
                    $count += 1
                    If ($count == 5) Then 
                        return $p2
                    EndIf
                ElseIf ($p1 <> $p2) Then
                        $state = $__DETECTING
                EndIf
            EndSelect
        $p1 = $p2
    WEnd
EndFunc

;.....................................................................
Func PixelGetColorFSMAggressive($x, $y)
Local $__DETECTING = 0
Local $__FALLING = 1
Local $__FLATLOW = 2
Local $__RISING = 3
Local $__FLATHIGH = 4   
Local $count

    $state = $__DETECTING
    $p1 = PixelGetColor($x, $y)
    While 1
        $p2 = PixelGetColor($x, $y)
        Select
            Case $state == $__DETECTING
                If ($p1 > $p2) Then
                    $state = $__FALLING
                Else
                    If ($p1 < $p2) Then
                        $state = $__RISING; 
                    EndIf
                EndIf
            Case $state == $__FALLING
                If ($p1 == $p2) Then
                    $state = $__FLATLOW
                ElseIf ($p1 < $p2) Then
                        $state = $__RISING
                EndIf
            Case $state == $__FLATLOW
                If ($p1 < $p2) Then
                    $state = $__RISING
                ElseIf ($p1 > $p2) Then
                    $state = $__FALLING
                EndIf
            Case $state == $__RISING
                If ($p1 == $p2) Then
                    $state = $__FLATHIGH
                    $count = 1
                ElseIf ($p1 > $p2) Then
                        $state = $__FALLING
                EndIf
            Case $state == $__FLATHIGH
                If ($p1 == $p2) Then
                    $count += 1
                    If ($count == 2) Then 
                        return $p2
                    EndIf
                ElseIf ($p1 <> $p2) Then
                        $state = $__DETECTING
                EndIf
            EndSelect
        $p1 = $p2
    WEnd
EndFunc
Edited by mvriesen2004
Link to comment
Share on other sites

This has absolutely nothing to do with the way AutoIt works. AutoIt works perfectly. It does not read your screen. It get's the information from the OS.

It has a really simple solution. FIX YOUR CODE! Your using it to detect color changes. Fix your detection algorithm it's probably way to simple.

As you say, "stupid is as stupid does". Maybe you have a better algorithm to reliably detect changes, I shared mine above. What do you have?

Link to comment
Share on other sites

Okay so your original provocative posting with accompanying chart asked a question that had nothing to do with what you really wanted to know. Why cant you just say heres whats happening, instead of veiling questions and throwing down gauntlets?

I still believe that this problem is due to double buffering of the video frames to create the illusion of seamless motion.

I think this problem will have to be fixed insite the AutoIT code itself.

You seem to have put in much effort to solve this and I dont know, you might be absolutely right, so let me asked you two more questions regarding your above statements, please:

1)What is causing the double buffering, your game I assume?

2) Have you run these same scripts in other languages and they flat out all the time?

Link to comment
Share on other sites

Okay so your original provocative posting with accompanying chart asked a question that had nothing to do with what you really wanted to know. Why cant you just say heres whats happening, instead of veiling questions and throwing down gauntlets?

You seem to have put in much effort to solve this and I dont know, you might be absolutely right, so let me asked you two more questions regarding your above statements, please:

1)What is causing the double buffering, your game I assume?

2) Have you run these same scripts in other languages and they flat out all the time?

If my original question is wrong, then it is because I have learned so much in trying to solve the problem. When I asked the original question, I had not formed my opinion of what was really happening. I also don't think I have veiled my questions. I have an application that uses real-time graphs and video to predict and track system performance and I am trying to arm it with additional sensors (since it is COTS). I have not tried other languages, but today I started looking at other macroing tools to see if the problem is repeatable.

(FYI - I also play a game called Lineage II - But it blocks macros, so AutoIT would NEVER work on that and that is not my problem.)

Worst case is I have to write my own application, but I am a Java programmer (and a rusty C++/VB programmer) and Java does not seem like the best language for this job. I have downloaded the AutoIT source and started looking at it.

My new questions are:

1) What other macro programming tools might do this job, so I can see if it is repeatable. I own a copy of Macro Express and I found ACTool (Apparently written for Acheron's Call so I don't think it will be useful in the long run). Both languages look sophisticated, but I like the syntax of AutoIT better and was hoping to not have to rewrite my entire application (about 50 pages of script including a GUI)

2) If my problem is double buffering, can this even be solved so that pixels can be reliably scraped from the screen? Or am I just out of luck? I am sensing the latter and am about ready to drop this thread.

3) And to throw down the gauntlet, Can AutoIT reliably sense pixel colors on real-time displays or not?

My belief now is that this is a limitation of AutoIT (I am not criticizing) and difficult to solve by anyone other than the AutoIT programmers who would have to dig in at a very low level.

Link to comment
Share on other sites

My belief now is that this is a limitation of AutoIT (I am not criticizing) and difficult to solve by anyone other than the AutoIT programmers who would have to dig in at a very low level.

I used your first posted script extensively on all the applications that I use on a regular basis none are games. I never got any deviation. So its got to be your game or your system. As I say you may be absolutely right about Autoit but until you prove it with other languages, you are just speculating. Please go do the homework and report back when you have proven your theory. Good luck.
Link to comment
Share on other sites

I used your first posted script extensively on all the applications that I use on a regular basis none are games. I never got any deviation. So its got to be your game or your system. As I say you may be absolutely right about Autoit but until you prove it with other languages, you are just speculating. Please go do the homework and report back when you have proven your theory. Good luck.

I guess what I am not communicating effectively is that my application is like a game, but it is not a game. If you have ever seen 2d and 3d simulation systems for control applications (www.mak.com), then you know what I am talking about.

My script works fine for the vast majority of applications that are traditional Windows applications and do not use real-time displays. I will do what I can to test further, but I am closing out this thread.

Bye Bye and GL - I'm sure this topic will be revisited by someone else.

Link to comment
Share on other sites

As you say, "stupid is as stupid does". Maybe you have a better algorithm to reliably detect changes, I shared mine above. What do you have?

At the moment I have no problem with how GetPixelColor works. So either my usage fits the language better or I have better code to prevent action on false positives.

If my original question is wrong, then it is because I have learned so much in trying to solve the problem. When I asked the original question, I had not formed my opinion of what was really happening. I also don't think I have veiled my questions. I have an application that uses real-time graphs and video to predict and track system performance and I am trying to arm it with additional sensors (since it is COTS). I have not tried other languages, but today I started looking at other macroing tools to see if the problem is repeatable.

(FYI - I also play a game called Lineage II - But it blocks macros, so AutoIT would NEVER work on that and that is not my problem.)

Worst case is I have to write my own application, but I am a Java programmer (and a rusty C++/VB programmer) and Java does not seem like the best language for this job. I have downloaded the AutoIT source and started looking at it.

My new questions are:

1) What other macro programming tools might do this job, so I can see if it is repeatable. I own a copy of Macro Express and I found ACTool (Apparently written for Acheron's Call so I don't think it will be useful in the long run). Both languages look sophisticated, but I like the syntax of AutoIT better and was hoping to not have to rewrite my entire application (about 50 pages of script including a GUI)

Why do you expect a macro language to be able to track changes in a "realtime system"?

3) And to throw down the gauntlet, Can AutoIT reliably sense pixel colors on real-time displays or not?

My belief now is that this is a limitation of AutoIT (I am not criticizing) and difficult to solve by anyone other than the AutoIT programmers who would have to dig in at a very low level.

Does the driver used to do the real-time update bypass the OS at anny time (activeX, directdraw)?

My experience is based on old TV cards and early versions of DiretX drivers. They could, and had to, bypass the OS to get data fast enough to the screen. I expect this is the same for many 2D/3D hardware accelerated operations. If your graphics card is able to do the job. The OS does not know the exact output to the screen.

So your solution would be. Use a camera to read the real screen. Use a algorithm that takes care of the fluctuations (blips) you get.

Don't take my word for it I'm no expert on this field. But I thing the analysis you have presented and the questions you ask seems to point in that direction.

Wish you the best of luck. I really hope you can figure it out. ;)

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...