can't get the keycode now, using python and opencv - python

okay, i've been using this basic thing for last few months to get key events such as ESC key, or E key etc, to do things when they are pressed in my opencv program.
Now earlier, for detecting ESC key, the code was there already in all the examples in the samples folder and on the web. I understood that. From that i hacked up a way to get the keycodes for other keys, such as E and S etc. Because i wanted to use them to take snapshots of the current frames under processing in my program. And it worked, i found out for E its 101, like for ESC its 27
But that's the ASCII value or something? I'm not sure.
This is what i'm doing now also, but its just not printing the keycode:
import cv
while True:
k = cv.WaitKey(100) % 0x100
if k != 255:
print k
So that when i press some key which doesn't have a value of 255, i should be notified that the that key was pressed. It works in my opencv programs:
while True:
k = cv.WaitKey(10)
if k % 0x100 == 27: # if ESC key is pressed....
#cv.SaveImage(filename,threshed2)
cv.DestroyWindow("threshed") #Destroy the window of detection results
cv.DestroyWindow("gray")
cv.DestroyWindow("edge")
cv.DestroyWindow("pupil")
#cv.DestroyWindow('smooth')
break
elif k == 101: #if E is pressed
eyeSnap = "C:\\Users\\ronnieaka\\Desktop\\PROJ\\openCV\\eyeSnaps\\det_pupil.jpg"
cv.SaveImage(eyeSnap,image)
I know its a basic thing and i just was playing around to get the keys pressed and do something else not related to OpenCV
Why i'm i not getting 101 from the previous code when i press E or the code for other keys when i press them?

This used to be super simple:
k = cv.WaitKey(10)
if k == 27:
# ESC key was pressed
The code above don't work on your system?

I have the same problem as you, but I always could not get keycode (only get 255)
I find it because the cv.WaitKey only receive key from the windows you create not python command line :)

Related

How do I make an autoclicker that goes up and down?

I am trying to make an autoclicker that clicks the up key for 10 seconds, then the down key for 10 seconds. I am using the pyautogui module for this and I am getting this error for some reason whenever I run:
keyUp() missing 1 required positional argument: 'key'
This is the rest of the code:
import pyautogui, time
time.sleep(2)
x = 0
times = 20
while True:
if x == times:
print("Stopped Clicking")
break
else:
pyautogui.keyUp(), time.sleep(10), pyautogui.keyDown()
x += 1
Check the pyautogui docs: https://pyautogui.readthedocs.io/en/latest/keyboard.html#the-press-keydown-and-keyup-functions
The keyUp and keyDown don't correspond to the Up key and the Down key, they correspond to a given key (which you have to supply as the argument) going up and down. For example, keyDown('space') holds the spacebar down and leaves it down until keyUp('space') is called.
What I think you want is to call the press function on the up and down keys, something like:
import pyautogui, time
time.sleep(2)
for _ in range(20):
pyautogui.press("up")
time.sleep(10)
pyautogui.press("down")
print("Stopped Clicking")

OpenCV to close the window on a specific key?

It seems really simple, but I can't get it to work and the couldn't find any questions regarding this particular issue (if there are, please point out in the comments).
I am showing an image and want the window to close on a specific key, but strangely, any key causes it to close.
This is my simple code for testing:
img = cv2.imread("MyImage.png")
cv2.imshow('My Image', img)
k = cv2.waitKey(0) & 0xFF
print(k)
if k == 27: # close on ESC key
cv2.destroyAllWindows()
(based on what is said here)
No matter what key I press, the key code is shown (27 for ESC, 32 for SPACE, ...) and the window closes.
The main problem: the if clause is never reached (I checked by putting the print(k) inside it, and nothing is printed). After the key press, the program simply stops running and it doesn't get to checking the key code.
(I am on macOS Catalina, with Python 3.8)
So, how do I actually make it wait for a specific key?
From my point of view, your program just terminates, and thus all windows are implicitly closed, regardless of which key you press.
One idea might be to put a while True loop around the reading and checking of the pressed key:
import cv2
img = cv2.imread('path/to/your/image.png')
cv2.imshow('My Image', img)
while True:
k = cv2.waitKey(0) & 0xFF
print(k)
if k == 27:
cv2.destroyAllWindows()
break
Running this, pressing some keys, and finally ESC, I get the following output:
103
100
102
27
Also, all windows are closed, and the program is terminated.
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.5
OpenCV: 4.4.0
----------------------------------------
If you want to use specific key, you can use ord():
img = cv2.imread('path/to/your/image.png')
cv2.imshow('My Image', img)
while True:
k = cv2.waitKey(0) & 0xFF
print(k)
if k == ord('c'): # you can put any key here
cv2.destroyAllWindows()
break
Simply do this:
img = cv2.imread("MyImage.png")
cv2.imshow('My Image', img)
k = cv2.waitKey(0)
print(k)
if k == 27: # close on ESC key
cv2.destroyAllWindows()
I have simply removed & 0xFF from it. This works for me but I don't why this would pose a problem as it is simply applying and operation with FF.
Try this, it will wait for key 'q' to be pressed.
import cv2
img = cv2.imread("MyImage.png")
cv2.imshow('My Image', img)
if cv2.waitKey(0) & 0xFF == ord('q'):
cv2.destroyAllWindows()
HIH.

WaitKey requires me to keep pressing and I want to just press it once

I am running some code called bcf.py it is very long and convoluted, but in short, it extracts 300 feature points from each image from a group of folders. So potentially there could be hundreds of images.
When I go to run the script, everything works except I have to keep pressing the return button to extract all the feature points and repeat this button pressing for every image, which is frustrating.
Why does it do this, and how would I fix it? The goal is to press the wait key once and extract the features.
Thank you
I do not know what this is called to be able to search for an answer.
def _svm_classify_test(self):
clf = self._load_classifier()
label_to_cls = self._load_label_to_class_mapping()
testing_data = []
labels = []
for (cls, idx) in self.data.keys():
testing_data.append(self.data[(cls, idx)]['spp_descriptor'])
labels.append(hash(cls))
predictions = clf.predict(testing_data)
correct = 0
for (i, label) in enumerate(labels):
if predictions[i] == label:
correct += 1
else:
print("Mistook %s for %s" % (label_to_cls[label], label_to_cls[predictions[i]]))
print("Correct: %s out of %s (Accuracy: %.2f%%)" % (correct, len(predictions), 100. * correct / len(predictions)))
def show(self, image):
cv2.imshow('image', image)
_ = cv2.waitKey()
The goal is to press the wait key once and automatically runs through​ all the images and extract the features.
The function cv.waitKey([, delay]) as it is explained in the documentation, it may take a value which you can consider as timeout. That means, you can pass a 10 and it will block the function for 10 milliseconds for a keyboard input.
For your case, I do not see where in the code you use your function show so I can't know exactly how you should do it to have that behaviour, but as a pseudocode for you to get an idea, it will be something like:
filenames = [] #lets assume your filenames are here
for f in filenames:
img = cv2.imread(f)
cv2.imshow("image", img)
cv2.waitKey(10)
If you want a pause at the beginning you can do an imshow outside the loop and a waitkey with 0 after it. Also, you can play with the amount of time, like 5000 to display it for 5 seconds before continuing.
But if it takes too long to process you may consider putting the imshow part in a thread, since the window maybe unresponsive after the waitKey while it waits for the feature extraction process to finish. Also, it may be good to add something like 'q' to quit the app or something.... These are just some suggestions :)

Record two set of point location from mouse event from first frame of a video

I have a video of the cow farm. My objectives are -
(a) get the location of the corners of the cow pen (cowhouse)
(b) get the corners of the food container
Here is my approach I am thinking about-
(a) - capture the frame and freeze on the 1st frame
- user will manually put the mouse on the corners
- the x,y location will be saved in a list
- press "p" key to proceed to the next frame
(b) - freeze the frame on the second frame
- user will manually put the mouse on the corners
- the x,y location will be saved in another list
- press "c" key to proceed to next frames
I already have other codes to carry out other operations. I tried the following codes to get point from an image (not video). Now sure how to pause the video and use the existing frame as the input image
import cv2, numpy as np
ix,iy = -1,-1
# the list of locations
mouse = []
def get_location(event,x,y,flags,param):
global ix,iy
if event == cv2.EVENT_LBUTTONDBLCLK:
ix,iy = x,y
mouse.append([x,y])
# take image and name it
img = cv2.imread("colo.png",0)
cv2.namedWindow('image')
cv2.setMouseCallback('image',get_location)
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(20) & 0xFF
if k == 27:
break
elif k == ord('a'):
print (ix,iy)
print (mouse)
cv2.destroyAllWindows()
The answers I am looking for are - (a) how to freeze the frame on a specific frame number and (b) cv2.setMouseCallback('image',get_location) is taking a string as the first argument, how to insert the frame as argument here?
a) use a variable to set the waitKey to 0. Only after a key press the next frame will be shown. Change the variable after "c" is pressed, so the video runs normally:
waitTime = 0
k = cv2.waitKey(waitTime)
if k == ord('c'):
waitTime = 20
b) the string argument is the name of the window where the callback is attached to. To 'insert the frame', just call imshow on the window. The code you have seems fine in that regard.

How to update polygon size with cumulative key press in Psychopy

I am using Psychopy to create a psychological task. For a given routine, I would like the height of a polygon (rectangle) to increase with every key press (same key every time), until it reaches the maximum number of key presses (e.g. 10). I cannot figure out how to create a loop to count number of key presses within the same routine, nor how to use this to generate a variable that will constantly update the size of the polygon.
Here is what I have tried as code in the routine which gets stuck in while loop... and I am not sure if the loop should go in the code "Before Routine" or for "Each Frame"
total_key_count = 0
while True:
resp_key = event.waitKeys(keyList=['1'])
if resp_key == '1':
total_key_count = total_key_count + 1
# .. or break out of the loop if reach 10
elif total_key_count == 10:
break
Thanks!
Never use event.waitKeys() in a Builder code component. Builder is structured around a drawing loop that requires updating the screen and responding to events on every screen refresh. If you call waitKeys(), you pause execution completely until a key is pressed, which will completely break Builder's temporal structure.
In the Begin routine tab, put this:
key_count = 0
max_keys = 10
In the Each frame tab, put this:
key_press = event.getKeys('1')
if key_press: # i.e. if list not empty
key_count = key_count + 1
if key_count <= max_keys:
# increment the height of the stimulus by some value
# (use what is appropriate to its units):
your_stimulus.size[1] = your_stimulus.size[1] + 0.1
else:
# terminate the routine (if required)
continueRoutine = False
Note that getKeys(), unlike waitKeys() just checks instantaneously for keypresses. i.e. it doesn't pause, waiting for a key. This is fine though, as this code will run on every screen refresh, until the required number of keys have been pushed.
Presumably you also need to save some data about the response. This would best be done in the End routine tab, e.g.
thisExp.addData('completion_time', t) # or whatever needs recording

Categories

Resources