Pyautogui - which approach is faster? - python

So I'm having 3 days education seminar which isn't of much use for me, so I'm writing my program on a paper and I'm wondering something since I can't test it at-the-moment.
I'm basically scanning my screen for image, and screen is divided into 8 segments. I don't need to scan all 8 segments, but for instance now, let's say I only need to scan 5 out of those 8 where image can pop out.
Is it faster to just make pyautogui to scan whole screen and write down coordinates where image was seen, and I'll then know by coordinated on which screen it popped, or is it faster to make multiple pyautogui searches with defined regions? So is it faster if pyautogui searches whole screen once or if pyautogui makes multiple searches with defined regions, searching only 20-70% of screen?
If it depends on how much screen in the end I search, what would be aproximate percentage where one becomes faster than other? For instance: searching 4 times 50% of screen is faster than searching once 100% screen, but searching 6 times 75% of screen is slower than searching once 100%.

I think that the faster and more efficient/accurate process here would be searching the whole screen through pyautogui and write down the coordinates where the image was seen, and you then knowing by the coordinated on which screen it popped...
So I would reccomend using this method as the second methos would be more slower and not as efficient as this

Related

Pygame Draw Circle Causing Lag

I am creating a infinity scrolling 2d space battle game in pygame. I have just implemented a parallax star background, but my framerate is now 30fps. Do you how to get more performance, i've tried creating blitting instead of draw.circle, and hwsurface, but cant increase fps.
Download zip
I would suggest that you do not create the star background on the fly the way it sounds like you are doing. Instead create a surface that contains it at the start and then scroll through that. Wrap it around on itself so that as you go past the edge it continues from the beginning. You will want to make sure that the two edges blend and appear seamless.
Then you can just blit the part of the background onto the screen and you will not find it has much impact on your performance vs generating it on the fly all the time.
In fact if you are doing it ahead of time you can do something fancier than just circles. You can do stars with different sizes and brightness (color). Maybe even a glare effect.
Edited after comment from OP:
I thought from what you described you were scrolling it not rotating. If you are doing rotations, I assume that you are using pygame.transform.rotate() for the rotations. One thing I have done in the past if I need rotated images is again to rotate them before hand and save them. That can work well if you are just rotating (even saving 360 rotated images is not that bad memory wise), but if you are scrolling and rotating then that would not work

Pyautogui - Problems with Changing Screenshots

ok, I've got into programming with python and thus far was having a fair amount of success. I've typed up a program that uses pyautogui to automates atask I need to do on a monthly basis.
I took Screenshots of where I needed the mouse to click and when all was done I had a working program that searched the screen for the button to clicked, controlled the mouse that location, and printed out the report I needed. So, all I needed to do was plug it into the task scheduler and it would do the work for me!
Several days afterwards, I decided to go ahead and schedule it. I ran the program again, and it crashed! Long Story short, the screen shots didn't match. I took a screen shot again, and zoomed both images 800% in Paint, and check the pixel next to the "I" in The two different images and sure enough the rgb values are different.
I tried several other places to, and while they looked the same... The rgb values are different by maybe one or two points! I'm curious as to why is this happening!
Use confidence, default value is 0.999. Reason is pyscreeze is actually used by pyautogui which has the confidence value which most likely represents a percentage from 0% - 100% for a similarity match. Looking through the code with my amateur eyes reveals that OpenCV and NumPy are required for confidence to work otherwise a different function would be used that doesn't have the confidence value.
for example:
by doing pyautogui.locateCenterOnScreen('foo.png', confidence=0.5) will set your confidence to 0.5, which means 50%.

How can I track extremly slow objects

Using OpenCV and python 2.7 I have written a script that detects and marks movement in a stream from a webcam. In order to detect movement in the image I use the RunningAvg function in openCV like so. . .
cv.RunningAvg(img, running_avg, 0.500, None)
cv.AbsDiff(img, running_avg, difference)
The overall script works great but I'm having a difficult time fine tuning it to pickup subtle motions(breathing for instance). I want to be able to target slow movements breathing specifically. I want to be able to do this without knowing things like color or size of targets ahead of time. I'm wondering if there is another method that is more suited to picking up subtle movements.
I think you should probably change the running average parameter way down to like 0.01
because 0.5 means the running average is half of the last frame.
This is assuming that breathing is the only motion in the frame. If there larger motions or the camera is moving you are going to need a more adaptive baseline.

Pygame: Tiled Map or Large Image

I am trying to decide if it is better to use a pre-rendered large image for a scrolling map game or to render the tiles individual on screen each frame. I have tried to program the game both ways and don't see any obvious difference in speed, but that might be due to my lack of experiences.
Besides for memory, is there a speed reasons to not use a pre-rendered map?
The only reason I can think of for picking one over the other on modern hardware (anything as fast and with as much ram as, say, an iPhone), would be technical ones that make the game code itself easier to follow. There's not much performance wise to distinguish them.
One exception I can think of, is if you are using a truly massive background, and doing tile rendering in a GPU, tiles can be textures and you'll get a modest speed bump since you don't need to push much data between cpu and gpu per frame, and it'll use very little video ram.
Memory and speed are closely related. If your tile set fits in video memory, but the pre-rendered map doesn't, speed will suffer.
Maybe it really depends of the map's size but this shouldn't be a problem even with a low-level-computer.
The problem with big images is that it takes a lot of time to redraw all the stuff on it so you will get an unflexible "map".
But a real advantage with an optimized image(use convert()-function and 16 bit) is are the fast blittings.
I work with big images as well on a maybe middle-good-computer and I have around 150 FPS by blitting huge images which require just ~ 100? MB RAM
image = image.convert()#video system has to be initialed
The following code creates an image(5000*5000), draws something on it, (blit this to the screen, fill the screen)*50 times and at the end it tells how long it took to do one blit and one flip.
def draw(dr,image,count,radius,r):
for i in range(0,5000,5000//count):
for j in range(0,5000,5000//count):
dr.circle(image,(r.randint(0,255),r.randint(0,255),r.randint(0,255)),[i,j],radius,0)
def geschw_test(screen,image,p):
t1 = p.time.get_ticks()
screen.blit(image,(-100,-100))
p.display.flip()
return p.time.get_ticks() - t1
import pygame as p
import random as r
p.init()
image = p.Surface([5000,5000])
image.fill((255,255,255))
image.set_colorkey((255,255,255))
screen = p.display.set_mode([1440,900],p.SWSURFACE,16)
image = image.convert()#extremely efficient
screen.fill((70,200,70))
draw(p.draw,image,65,50,r)#draw on surface
zahler = 0
anz = 20
speed_arr = []
while zahler < anz:
zahler += 1
screen.fill((0,0,0))
speed_arr.append(geschw_test(screen,image,p))
p.quit()
speed = 0
for i in speed_arr:
speed += i
print(round(speed/anz,1),"miliseconds per blit with flip")
Depends on the size of the map you want to make, however, with the actual technologies it's very hard to see a tile-map "rendered" to take longer than expected, tiled based games are almost extinguished, however is always a good practice and a starting point to the world of game programming

Python (Jython) Playing notes from pixels in picture

This is from a class assignment:
This program is about listening to colors. We will treat pictures as piano scores.
Write a function called listenToPicture that takes one picture as an argument. It first shows the picture. Next, it will loop through every 4th pixel in every 4th row and do the following. It will compute the total of the red, green and blue levels of the pixel, divide that by 9, then add the result to 24. That number will be the note number played by playNote.
That means that the darker the pixel, the lower the note; the lighter the pixel, the higher the note. It will play that note at full volume (127) for a tenth of a second (100 milliseconds). Every time it moves to a new row, it prints out the row number (y value) on the console.
Your main function will ask the user to select a file with a picture. It will print the number of notes to be played (which is the number of pixels in the picture divided by 16; why?). It will then call the listenToPicture function.
Ok I edited in what I have so far and the only thing I haven't figured out (I believe) is how to print the number of notes in the main function. By the way, thanks to everyone who helped. You guys are amazing. Is there a place to donate to this site?
def main():
pic=makePicture(pickAFile())
show (pic)
listenToPicture(pic)
def listenToPicture(pic):
w=getWidth(pic)
h=getHeight(pic)
for y in range(0,h,4):
printNow(str(y))
for x in range (0,w,4):
px=getPixel(pic,x,y)
r=getRed(px)
g=getGreen(px)
b=getBlue(px)
tot=((r+g+b)/9)+24
playNote(tot,100,127)
Robbie is right for the width/height for loops.
The loop you are using to get the pixels and play the notes looks as if it is getting ALL the pixels and playing them all every time you get a unique x and y. What you should be doing is be getting the pixel at (x,y) then pulling out the rgb values and calling play note on that. You really shouldn't even need the 3rd for loop. You're not too far off. Try writing the problem out in logical steps in plain English. I find that helps a ton before I start coding.
Good Luck.
You asked about similar things before. Well, since you didn't put any code in about actually retrieving the pixel value, I'll assume that you still aren't able to do that. I know this is going way beyond your question, but last time you were pretty vague about your question and indicated that you needed more help than just what you had asked. If any of this is not necessary then just ignore it. I'm just trying to offer some advice and you can take it or leave it.
In case you haven't figured out how to read a pixel, I recommend using PIL. It has functions for opening images documented here. Then you can access a pixel in the image by its x and y value using getpixel which is documented on the same page.
For playing the note I would recommend looking into the PyAudio module and just making your own sinusoids of various frequencies (depending on the magnitude of the pixel) that you write to an open audio stream. There might be better packages for this part, but this is what I have used in my small adventures in Python audio.
For the audio stuff, I would try just outputting a sound at a fixed frequency before trying to actually emit a varying frequency.
Edit:
Your loops look better now so I took out my stuff about your loops.

Categories

Resources