I have a func that retrieve information from program. It point the mouse grab an image, resize it, then get recognized with tesseract and add to ValueIndex.
from PIL import Image
import pytesseract
import pyscreenshot as ImageGrab
from pynput.mouse import Button, Controller
import re
def GetValues(): #Read matrix of digit from
pytesseract.pytesseract.tesseract_cmd ='C:\\Program Files (x86)\\Tesseract-OCR\\tesseract'
mouse = Controller()
Mul=2
ValueIndex=[0 for i in range(0,170)] # Results
y1=163
if __name__ == "__main__":
for j in range(0,1):# get 1 line for example
y1=y1+67
x1=1350
for i in range(0,13):
x1=x1+67
mouse.position = (x1, y1)
mouse.press(Button.left)
mouse.release(Button.left)
im=ImageGrab.grab(bbox=(1485, 1112,1680, 1177))
x,y = im.size
x=x*Mul
y=y*Mul
size=x,y
im_resized = im.resize(size, Image.ANTIALIAS) # resize for tesseract
im_resized.save('test%s.png' % i)
data = pytesseract.image_to_string(im_resized)
q=''.join(re.findall('\d',data)) # gt digits from str
if (len(q)==4):
q=indexq[:2]+'.'+q[2:]
if len(q)==3:
q=q[:1]+'.'+q[1:]
GetInd=j*13+i+1
ValueIndex[GetInd]=float(q)
print(i,' ',data,' ',ValueIndex[GetInd]) # print to see the progress
return(ValueIndex)
GetValues() #When i comment it, print only 1 time
print('Why so many times?:)')
It work properly, but when i add print in body of prorgam it output multiple times. It's not in func loop, whats wrong?
Why so many times?:)
0 +9.76% 9.76
Why so many times?:)
1 +619% 6.19
Why so many times?:)
2 +5.36% 5.36
and so on
Related
I am using opencv for a project which displays an image and after you close the displayed image, that same image will open as well as a new additional image. The code is below but it is only displaying one image and not 2.
import cv2
import time
import random
import os
k = 0
rep = 0
window_name = "Monkey Virus"
files = os.listdir("Z:\Y10 Python\images wow\img")
delay = random.randint(0,10)
monkeyChoice = random.randint(1,len(files))
image = "Z:\\Y10 Python\\images wow\\img\\" + str(monkeyChoice) + ".jpg"
monkeyHist = 1
def draw_img():
global monkeyHist
if rep == 0:
time.sleep(delay)
monkeyHist += 1
img = cv2.imread(image, cv2.COLOR_BGR2RGB)
cv2.imshow(window_name, img)
cv2.setWindowProperty(window_name, cv2.WND_PROP_TOPMOST, 1)
cv2.waitKey(0)
draw_img()
rep = rep + 1
if cv2.getWindowProperty('Monkey Virus', cv2.WND_PROP_VISIBLE) < 1:
while k < monkeyHist:
draw_img()
You call cv2.imshow(...) followed by cv2.waitKey(0) on the main thread. Therefore, after the first call, the thread will be blocked and no further code will be executed until the user presses a key. If you want to show a second image, you need to call cv2.imshow() again with a different window_name argument before the call to cv2.waitKey(0).
(Also
while k < monkeyHist:
draw_img()
is probably an endless loop, as your draw_img() function only ever increases monkeyHist, but never increases k; therefore, k is forever smaller than monkeyHist.)
so I'm trying to read out text from MS Teams and use that text to make inputs on the keyboard.
Right now, I work with the threading module to have one thread for the input and one thread for the image_to_string. Following is the function for the image_to_string.
def imToString():
global message
print("Image getting read")
pytesseract.pytesseract.tesseract_cmd ='C:\\Users\\gornicec\\AppData\\Local\\Programs\\Tesseract-OCR\\tesseract.exe'
while(True):
print("preIMGgrab")
cap = ImageGrab.grab(bbox=(177, 850, 283, 881))
grayCap = cv2.cvtColor(np.array(cap), cv2.COLOR_BGR2GRAY)
print("postIMGgrab")
t = time.perf_counter()
print("preMSG" + str(t))
message = pytesseract.image_to_string(
grayCap,
lang ='deu',config='--psm 6')
print(str(message) + "was read" + str(time.perf_counter() - t))
I don't know how but it takes about 8 seconds to read an image thats 1000 pixels big. I need this to be at highest 2 seconds. I'll add the whole code at the end. If there is any way to make it faster or to do it differently please tell me so.
WHOLE CODE:
import numpy as np
import time
import pytesseract
from win32gui import GetWindowText, GetForegroundWindow
import win32api
import cv2
import pyautogui
from PIL import ImageGrab
import threading
from ahk import AHK
import keyboard
message = ""
ahk = AHK(executable_path='C:\\Program Files\\AutoHotkey\\AutoHotkey.exe')
def Controls():
global message
while True:
booleanVal = True
if booleanVal:
#imToString()
print("message")
#print("rechts" in message.lower())
#print(f'LĂ„NGE: {len(message)}')
if "vorne" in message.lower():
# Control(message, 'w')
ahk.key_press('w')
#message = ""
if "hinten" in message.lower():
# Control(message, 's')
ahk.key_press('s')
#message = ""
if "links" in message.lower():
# Control(message, 'a')
ahk.key_press('a')
#message = ""
if "rechts" in message.lower():
# Control(message, 'd')
#print("HAHAHA")
ahk.key_press('d')
#message = ""
if "greif" in message.lower():
ahk.key_press('space')
#message = ""
time.sleep(0.5)
#IMGTOSTRING---
controls = threading.Thread(target=Controls)
controls.start()
grab = threading.Thread(target=imToString)
grab.start()
pytesseract is not suit for large amount of images or images that are already in memory, its write them to a file and then pass the file path to tesseract cli, if you want to improve the performance of you script try using library that works directly with tesseract api.
like this: https://pypi.org/project/tess-py-api/
I am trying to take several screeenshots with Python each time I press the key 'p' on my keyboard, with the page number being updated with each new screenshot. However, the program ends up taking several screenshots with each press of the key.
from PIL import ImageGrab
import keyboard
def shot(number):
while True:
if keyboard.is_pressed('p'):
image = ImageGrab.grab(bbox=(580, 0, 1340, 1080))
image.save(f"{number} page.pdf")
shot(number + 1)
else:
pass
for i in range(1, 2):
shot(i)
from PIL import ImageGrab
import keyboard
def shot(number):
while True:
if keyboard.is_pressed('p'):
image = ImageGrab.grab(bbox=(580, 0, 1340, 1080))
image.save(f"{number} page.pdf")
shot(number + 1)
break #to break loop
else:
pass
for i in range(1, 2):
shot(i)
The problem is recursion you use, you call it right after you take screen, try this:
from PIL import ImageGrab
import keyboard
import time
def shot(number):
while True:
if keyboard.is_pressed('p'):
image = ImageGrab.grab(bbox=(580, 0, 1340, 1080))
image.save(f"{number} page.pdf")
break
else:
pass
i=1
while True:
shot(i)
#suspend for a second, so we don't take another screen immediately
time.sleep(1)
i+=1
But there is way simpler method, you don't need to use loops if you use keyboard.wait, which is also way more efficient.
Also to avoid memory consumption we can get rid of recursion with a simple loop:
from PIL import ImageGrab
import keyboard
import time
def shot(number):
keyboard.wait("p")
image = ImageGrab.grab(bbox=(580, 0, 1340, 1080))
image.save(f"{number} page.pdf")
time.sleep(1)
i=1
while True:
shot(i)
i+=1
I'm trying to get the angle of the middle line in a domino. SimpleBlobDetector can find it, but it gives me an angle value of -1.
Does anyone know why that can be? and how can i fix that still using SimpleBlobDetector? and if SimpleBlobDetector is not an option, what else can i do to find the center and angle of these lines?
import numpy as np
import cv2
import os
import time
#from matplotlib import pyplot as plt
def main():
capWebcam = cv2.VideoCapture(0) # declare a VideoCapture object and associate to webcam, 0 => use 1st webcam
params = cv2.SimpleBlobDetector_Params()
params.filterByCircularity = True
params.minCircularity = 0.73
params2 = cv2.SimpleBlobDetector_Params()
params2.filterByInertia = True
params2.maxInertiaRatio = 0.3
# show original resolution
print "default resolution = " + str(capWebcam.get(cv2.CAP_PROP_FRAME_WIDTH)) + "x" + str(capWebcam.get(cv2.CAP_PROP_FRAME_HEIGHT))
capWebcam.set(cv2.CAP_PROP_FRAME_WIDTH, 320.0) # change resolution to 320x240 for faster processing
capWebcam.set(cv2.CAP_PROP_FRAME_HEIGHT, 240.0)
capWebcam.set(cv2.CAP_PROP_FPS, 1)
# show updated resolution
print "updated resolution = " + str(capWebcam.get(cv2.CAP_PROP_FRAME_WIDTH)) + "x" + str(capWebcam.get(cv2.CAP_PROP_FRAME_HEIGHT))
if capWebcam.isOpened() == False: # check if VideoCapture object was associated to webcam successfully
print "error: capWebcam not accessed successfully\n\n" # if not, print error message to std out
os.system("pause") # pause until user presses a key so user can see error message
return # and exit function (which exits program)
# end if
while cv2.waitKey(1) != 27 and capWebcam.isOpened(): # until the Esc key is pressed or webcam connection is lost
blnFrameReadSuccessfully, img = capWebcam.read() # read next frame
if not blnFrameReadSuccessfully or img is None: # if frame was not read successfully
print "error: frame not read from webcam\n" # print error message to std out
os.system("pause") # pause until user presses a key so user can see error message
break # exit while loop (which exits program)
det = cv2.SimpleBlobDetector_create(params)
det2 = cv2.SimpleBlobDetector_create(params2)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
time.sleep(0.1)
keypts = det.detect(gray)
time.sleep(0.1)
keypts2 = det2.detect(gray)
print len(keypts)
print len(keypts2)
for l in keypts2:
print l.pt
print l.angle
time.sleep(0.3)
imgwk = cv2.drawKeypoints(gray, keypts, img,color= (200,0,139),flags=2)
time.sleep(0.1)
imgwk2 = cv2.drawKeypoints(img, keypts2, gray,color= (200,0,139),flags=2)
cv2.namedWindow("img", cv2.WINDOW_AUTOSIZE) # or use WINDOW_NORMAL to allow window resizing
cv2.imshow("img", img)
# hold windows open until user presses a key
cv2.destroyAllWindows()
return
###################################################################################################
if __name__ == "__main__":
main()
I'm not sure if SimpleBlob detector is the best for this, but have you looked at
Detect centre and angle of rectangles in an image using Opencv
It seems quite similar to you question, and seems to do very well at identifying the angle of the rectangles
I am trying to apply the numpy palette method to an opencv processed video (references: this question and this tutorial ). I aim at replacing all frame pixels of a certain color range by another. The code below is an example that replaces black with green. Unfotunately, my code raises an error on line:
image[np.where((image==[0,0,0]).all(axis=2))]=green
the error: exceptions.ValueError:axis(=2) out of bounds
I am running python 2.7 with PyScripter, and I find it odd because the code did work before, and I did not make any major modification to it. Can someone please help me? I am quite stuck on this one...
My code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##IMPORTS
import cv2.cv as cv
import numpy as np
import time
##VARIABLES
#colors
green=[0,255,0]
##MAIN
#video file input
frames = raw_input('Please input video file:')
if not frames:
print "This program requires a file as input!"
sys.exit(1)
#create window
cv.NamedWindow("image", 1)
#File capture
vidFile = cv.CaptureFromFile(frames)
nFrames = int( cv.GetCaptureProperty( vidFile, cv.CV_CAP_PROP_FRAME_COUNT ) )
fps = cv.GetCaptureProperty( vidFile, cv.CV_CAP_PROP_FPS )
waitPerFrameInMillisec = int( 1/fps * 1000/1 )
#time adjustment, frame capture
for f in xrange( nFrames ):
frame = cv.QueryFrame( vidFile )
# create the images we need
image = cv.CreateImage (cv.GetSize (frame), 8, 3)
# copy the frame, so we can draw on it
if not frame:
break
else:
cv.Copy (frame, image)
#get pixel HSV colors
rows,cols=cv.GetSize(frame)
image=np.asarray(image)
image[np.where((image==[0,0,0]).all(axis=2))]=green
image=cv.fromarray(image)
#show the image
cv.ShowImage("image", image)
#quit command ESC
if cv.WaitKey(waitPerFrameInMillisec)==27:
break
else:
cv.WaitKey(waitPerFrameInMillisec) % 0x100
I solved it. In fact, the answer was not a modification of the line raising the exception, but rather on a modification of the arguments that were passed to this line. Indeed, it seems that the '[:,:]' arguments are required in opencv when converting cvMat to Numpy and back.
Here is the corrected code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##IMPORTS
import cv2.cv as cv
import numpy as np
##VARIABLES
#colors
green=[0,255,0]
##MAIN
#start video stream analysis
frames = raw_input('Please enter video file:')
if not frames:
print "This program requires a file as input!"
sys.exit(1)
# first, create the necessary windows
cv.NamedWindow ('image', cv.CV_WINDOW_AUTOSIZE)
#File capture
vidFile = cv.CaptureFromFile(frames)
nFrames = int( cv.GetCaptureProperty( vidFile, cv.CV_CAP_PROP_FRAME_COUNT ) )
fps = cv.GetCaptureProperty( vidFile, cv.CV_CAP_PROP_FPS )
waitPerFrameInMillisec = int( 1/fps * 1000/1 )
for f in xrange( nFrames ):
#time adjustment, frame capture
sec = f/fps
frame = cv.QueryFrame( vidFile )
# create the images we need
image = cv.CreateImage (cv.GetSize (frame), 8, 3)
# copy the frame, so we can draw on it
if not frame:
break
else:
cv.Copy (frame, image)
#Replace pixel colors
rows,cols=cv.GetSize(frame)
image=np.asarray(image[:,:])
image[np.where((image==[0,0,0]).all(axis=2))]=green
image=cv.fromarray(image[:,:])
#show the image
cv.ShowImage("image", image)
#quit command ESC
if cv.WaitKey(waitPerFrameInMillisec)==27:
break
else:
cv.WaitKey(waitPerFrameInMillisec) % 0x100
cv.DestroyAllWindows()