How To Fix Error Automation Game Python Code - python

I'm Trying To Use An Automation Piano Game With Python, But When I Want To Try Implementing The Code, I Get An Error
As Shown In The Attached Picture
Please Help Me To Fix This Error, I Used ** Python 3.8.4 **
*<!-- The Code -->*
import mss as mss
import numpy as np
from cv2 import cv2
import time
import pyautogui
import keyboard
pyautogui.PAUSE = 0.005
def take_screenshot():
with mss.mss() as sct:
filename = sct.shot(output="fullscreen.png")
return filename
# take_screenshot()
def get_frame(region):
with mss.mss() as sct:
screen = np.array(sct.grab(region))
screen_grayscale = cv2.cvtColor(screen, cv2.COLOR_BGR2BGRA)
# print(screen_grayscale.shape)
# cv2.imwrite('region.png', screen_grayscale)
return screen_grayscale
def detect_tiles(frame):
for x in range(frame.shape[0]):
for y in range(frame.shape[1]):
if frame[x, y] == 1:
return x, y
return None
region = {"top": 560, "left": 350, "width": 300, "height": 2}
time.sleep(3)
while True:
if keyboard.is_pressed('q'):
break
start_time = time.time()
frame = get_frame(region)
coors = detect_tiles(frame)
if coors:
target_x = region['left'] + coors[1] + 1
target_y = region['top'] + coors[0] + 1
pyautogui.moveTo(x=target_x, y=target_y)
pyautogui.mouseDown()
print("%d FPS" % (1 / (time.time() - start_time)))
*<!-- end code -->*
my error image:

Your problem seems to stem from the fact that frame[x,y] is not a single value but a list or tuple of values. Hence, when you execute if frame[x,y] == 1 you get an error message like ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
Depending on what you want to accomplish you can use one of the following remedies:
Use the .all method which will result in True if and only if all elements of frame[x] and frame[y] equal 1. Using the following:
if frame[x,y].all() == 1:
Use the .any method which will result in True if and only if any frame[x] or frame[y] element equals 1. Using the following:
if frame[x,y].any() == 1

Related

Generative Art in Python- Upstream Logic causing "Invalid Literal for int()"

I'm a novice coder working on a small generative art exercise to make space-invader sprites, have been stuck on this for a while even though it's probably a trivial problem. The goal of the code is to allow the user to define their own inputs in the command line for a grid of sprite characters, like this:
python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]
'''
import PIL, sys, random
from PIL import Image, ImageDraw
origDimension = 1500
r = lambda: random.randint(50,255)
rc = lambda: ('#%02X%02X%02X' % (r(),r(),r()))
listSym = []
def create_square(border, draw, randColor, element, size):
if (element == int(size/2)):
draw.rectangle(border, randColor)
elif (len(listSym) == element+1):
draw.rectangle(border,listSym.pop())
else:
listSym.append(randColor)
draw.rectangle(border, randColor)
def create_invader(border, draw, size):
x0, y0, x1, y1 = border
squareSize = (x1-x0)/size
randColors = [rc(), rc(), rc(), (0,0,0), (0,0,0), (0,0,0)]
i = 1
for y in range(0, size):
i *= -1
element = 0
for x in range(0, size):
topLeftX = x*squareSize + x0
topLeftY = y*squareSize + y0
botRightX = topLeftX + squareSize
botRightY = topLeftY + squareSize
create_square((topLeftX, topLeftY, botRightX, botRightY), draw, random.choice(randColors), element, size)
if (element == int(size/2) or element == 0):
i *= -1;
element += i
def main(size, invaders, imgSize):
origDimension = imgSize
origImage = Image.new('RGB', (origDimension, origDimension))
draw = ImageDraw.Draw(origImage)
invaderSize = origDimension/invaders
padding = invaderSize/size
for x in range(0, invaders):
for y in range(0, invaders):
topLeftX = x*invaderSize + padding/2
topLeftY = y*invaderSize + padding/2
botRightX = topLeftX + invaderSize - padding
botRightY = topLeftY + invaderSize - padding
create_invader((topLeftX, topLeftY, botRightX, botRightY), draw, size)
origImage.save("Examples/Example-"+str(size)+"x"+str(size)+"-"+str(invaders)+"-"+str(imgSize)+".jpg")
if __name__ == "__main__":
main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))
'''
When I run this code I get a value error from the last line where the argv's are soposed to go. but I'm not sure where I'm going wrong upstream. Any help greatly appreciated.
'''
---------------------------------------------------------------------------
ValueError Traceback (most recent call
15
16 if __name__ == "__main__":
---> 17 main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))
ValueError: invalid literal for int() with base 10: '--ip=127.0.0.1'
'''
Assuming you've got a Python script script.py:
import sys
print(sys.argv)
And you run it from the terminal via:
python script.py firstarg 123 thirdarg
The output will be:
['script.py', 'firstarg', '123', 'thirdarg']
Notice: sys.argv is a list of strings, where each string represents one of the command line arguments passed in when the script was initially executed. Also notice that the first command line argument will always be a string with the script file's name. Even if you run the same script with no "custom" command line arguments, your program will always get at least one command line argument by default (the script's name.)
EDIT - Here is the image that's generated when I run your script (no changes):

Problems with red pixel and loop check

I am new here and also in python (^_^')
I have a question about my code.
This is an infinite loop, when my code finds a red pixel in a saved screenshot send me a message, it works if there is a red pixel, but if I try to test another red pixel or delete the last red pixel detected and then re-use it, my code stops working with this error:
Warning (from warnings module):
File "C:\Users\Desktop\DCN.py", line 126
comparison_dcn = check_dcn == control_dcn
DeprecationWarning: elementwise comparison failed; this will raise an error in the future.
Traceback (most recent call last):
File "C:\Users\Desktop\DCN.py", line 127, in <module>
equal_dcn= comparison_dcn.all()
AttributeError: 'bool' object has no attribute 'all'
My idea was to create a numpy array to save the coordinates (x,y) and check if already exist inside this array, it must not detect it to me two times...
I tried to figure out the problem, but it is too early for my python experience....
I hope my english is understandable XD
Can someone kindly help me with my code and explain my issue?
#libaries
import mss
import mss.tools
from PIL import image
import psutil
import time
import cv2
import numpy as np
#global variables
loop = 1
check_dcn = np.column_stack((0,0))
counter_dcn = 0
while loop == 1 :
#detect red pixel
def detect_color(rgb, filename):
img = Image.open(filename)
img = img.convert('RGBA')
data = img.getdata()
for item in data:
if item[0] == rgb[0] and item[1] == rgb[1] and item[2] == rgb[2]:
return True
return False
with mss.mss() as sct:
# The screen part to capture
monitor = {"top": 190, "left": 0, "width": 1920, "height": 840}
output = "example.png".format(**monitor)
# Grab the data
sct_img = sct.grab(monitor)
# Save to the picture file
mss.tools.to_png(sct_img.rgb, sct_img.size, output=output)
print (detect_color((255,102,102), 'example.png')) #dcn red pixel
#dcn alarm detected
if detect_color((255,102,102), 'example.png'):
pixel_img = cv2.imread('example.png')
pop = [102,102,255] #BGR order
X,Y = np.where(np.all(pixel_img == pop, axis = 2)) #coordinates
control_dcn = np.column_stack((X,Y)) #assign coordinates
print(control_dcn) #test
if counter_dcn == 0:
counter_dcn = 1
check_dcn = control_dcn
print("first round dcn") #test
print(check_dcn) #test
###looking for solution here to empty comparison_dcn
comparison_dcn = check_dcn == control_dcn
equal_dcn= comparison_dcn.all()
if equal_dcn:
print("red pixel alread reported,waiting 20 seconds") #test
time.sleep(20)
else:
check_dcn = np.column_stack(X,Y)
print("red pixel added,waiting 5 seconds") #test
print(check_dcn) #test
time.sleep(5)
else:
print("Nothing, waiting 10 seconds")
time.sleep(10)

Search all pixels and PNGs in a single grab using ImageGrab in Python

I am having some problems with multi-process in Xlib.thread or ImageGrab.
When I put like 3 or more references to get (getPixel and locateOnScreen(pyautogui)) in multi threads, it works fast and without errors initially, but 2 or 3 hours later the commands are getting slow and an error appears in the cmd warning that "it can't happen!"
Here's an example of the code:
from PIL import ImageGrab, Image
from pymouse import PyMouse
from pykeyboard import PyKeyboard
import time
m = PyMouse()
k = PyKeyboard()
def start(self):
if self.hotkeyEscolhidaManaTraining != None:
self.isManaTrainingOn = True
if self.isManaTrainingOn:
self.timerstartManaTraining=Interval.set_interval(self.startManaTraining, 1)
def startManaTraining(self):
if self.runningTimerManaTraining == True:
self.timerstartManaTraining.cancel()
return
self.runningTimerManaTraining = True
ManaTrainingBox = pyautogui.locateOnScreen('Pics/heal/manaLow.png', 0.8, True)
startBoxLeft = ManaTrainingBox[0]+2
self.startBoxTopManaTraining = ManaTrainingBox[1]+5
pixeisTotais = 92
if self.isManaTrainingOn:
pixelManaTraining = (self.porcentagemEscolhidaManaTraining * pixeisTotais) / 100
self.endBoxLeftManaTraining = startBoxLeft + pixelManaTraining
self.timerManaTraining = Interval.set_interval(self.validateManaTraining, 0.5)
def validateManaTraining(self):
if self.isManaTrainingOn:
pixelRGB = ImageGrab.getPixel((self.endBoxLeftManaTraining, self.startBoxTopManaTraining))
if not self.validatePixelsMana(pixelRGB):
pyautogui.press(self.hotkeyEscolhidaManaTraining)
return
and others 10 code like this in multi-threads, have a way to get all pixels and PNGs in just one 'locateOnScreen' without saving the img?

TypeError: an integer is required

Beginner to Python, I've been trying to alter the pixel values of an image as follows. I've been getting an error that says 'TypeError: an integer is required'on the last but one line
How do I sort this out?
This is my code:
from PIL import Image
img = Image.open(r'...')
pix = img.load()
def quantf(pval):
if pval>=0 and pval<0.25:
pval=0
elif pval>=0.25 and pval<0.5:
pval=0.25
elif pval>=0.5 and pval<0.75:
pval=0.5
elif pval>=0.75 and pval<1:
pval=0.75
elif pval==1:
pval=1
for i in range (0,31):
for j in range (0,31):
pix[i,j]=quantf(pix[i,j])
img.show()
According to:
http://pillow.readthedocs.io/en/3.4.x/reference/PixelAccess.html#example
After performing an image load each pixel is a tuple when using a multi-band image, otherwise it's an individual value:
from PIL import Image
im = Image.open('hopper.jpg')
px = im.load()
print (px[4,4])
prints:
(23, 24, 68)
or
0.23
You'll need to adjust your quantf(pval) function in order to account for this as well as ensuring that quantf(pval) actually returns a value.
For example:
def quantf(pval):
if pval[0]>=0 and pval[0]<64:
pval=(0, pval[1], pval[2])
elif pval[0]>=64 and pval[0]<128:
pval=(64, pval[1], pval[2])
elif pval[0]>=128 and pval[0]<192:
pval=(128, pval[1], pval[2])
elif pval[0]>=192 and pval[0]<256:
pval=(192, pval[1], pval[2])
return pval
or
def quantf(pval):
if pval>=0 and pval<0.25:
pval=0
elif pval>=0.25 and pval<0.5:
pval=0.25
elif pval>=0.5 and pval<0.75:
pval=0.5
elif pval>=0.75 and pval<1:
pval=0.75
elif pval==1:
pval=1
return pval

NoneType error .convert appear

i would like to do some program by capture image from webcam, then cropped it. after crop, i do some image processing and from the process it will run my robots. Here the full program:
import cv2
from cv2 import *
import numpy as np
import pylab
import pymorph
import mahotas
from matplotlib import pyplot
from PIL import Image
# initialize the camera
cam = VideoCapture(0) # 0 -> index of camera
s, img = cam.read()
# frame captured without any errors
if s:
imwrite("img.jpg",img) #save image
#Crop Image
imageFile = "img.jpg"
im1 = Image.open(imageFile)
def imgCrop(im):
box = (0, 199, 640, 200)
region = im.crop(box)
region.save('crop.jpg')
cImg = imgCrop(im1)
#thresholding
def greyImg(im):
gray = im.convert('L')
bw = gray.point(lambda x: 0 if x<128 else 255, '1')
bw.save("bw.jpg")
tImg = greyImg(cImg )
#direction
def find_centroid(im, rez):
width, height = im.size
XX, YY, count = 0, 0, 0
for x in xrange(0, width, rez):
for y in xrange(0, height, rez):
if im.getpixel((x, y)) == 255:
XX += x
YY += y
count += 1
return XX/count, YY/count
print find_centroid(tImg, 1)
def robo_direct():
cen = find_centroid(im, 1)
diff = cen[0] - 320
if diff > 10:
print 'right'
if diff < -10:
print 'left'
else:
print 'straight'
print robo_direct()
The error was come out like this:
File "compile.py", line 32, in greyImg
gray = im.convert('L')
AttributeError: 'NoneType' object has no attribute 'convert'
That is because im is a None object.
Try again the code with:
print im is None
And you'll see. I don't know about threshold, but obviously you are creating the im object the wrong way.
Your function imgCrop(im1) has no return statement and as such returns None. And then your greyImg(im) function also has no return statement and also will return None.
To fix that add return statements to both functions that for the first return region and the second return bw.
Also your robo_direct() function should return and not print the direction so that the call to it in the statement print robo_direct() would print the direction.

Categories

Resources