Is there a way to use cv2.waitkey() without showing the window? - python

I followed this program tutorial that captures the screen and puts it in a video file. The recording stops when the 'q' button is pressed. However, I didn't want to show the screen in a mini window and just write straight to the file. I am just calling the while loop shown in the tutorial except that I didn't include the part about showing the image to the 'Live' window. Now when I use:
while True:
img = pyautogui.screenshot()
frame = np.array(img)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
out.write(np.array(frame))
# cv2.imshow('Live', frame)
if cv2.waitKey(1) == ord('q'):
print('done')
break
it won't detect my pressing q. What is going on here? When I press q the loop should stop right? I am just getting a 44 bit mp4 file as an end result from this. I think it might be because I didn't use imshow so waitkey won't do anything but I am not sure. Is there a way to get it to stop recording on a key press?

It's very likely that waitKey() doesn't do anything unless there's a window, since it's likely related to a window key event handler.
If you're on Windows, you could try msvcrt.kbhit(), which is a non-blocking call to request whether a key has been pressed on the console and could be read.
On other platforms, waiting for a keypress in a non-blocking manner might be non-trivial.

I think, you are right in assuming that since you didn't start the display(ie., cv2.imshow()) the cv2.watikey() doesn't work. Since your goal is to stop recording on key press I think you can follow this link's suggestion.
or try this pattern:
try:
while True:
break
#replace break with your code
except KeyboardInterrupt:
print("Press Ctrl-C to terminate while statement")
pass

Related

How to stop repeat on button press/hold - Python

I was hoping someone might have some insight on how to stop a script from continuing to repeat if a button is held (or in my case pressed longer than a second)?
Basically i've a button setup on the breadboard, and I have it coded to play an audio file when the button is pressed. This works, however if the button isn't very quickly tapped, then the audio will repeat itself until button is fully released. Also if the button is pressed and held, the audio file will just repeat indefinitely.
I've recorded a quick recording to demonstrate the issue if its helpful, here: https://streamable.com/esvoy6
I should also note that I am very new to python (coding in general actually), so its most likely something simple that I just haven't been able to find yet. I am using gpiozero for my library.
Any help or insight is greatly appreciated!
Here is what my code looks like right now:
from gpiozero import LED, Button
import vlc
import time
import sys
def sleep_minute(minutes):
sleep(minutes * 60)
# GPIO Pins of Green LED
greenLight = LED(17)
greenButton = Button(27)
# Green Button Pressed Definition
def green_btn_pressed():
print("Green Button Pressed")
greenButton.when_pressed = greenLight.on
greenButton.when_released = greenLight.on
# Executed Script
while True:
if greenButton.is_pressed:
green_btn_pressed()
time.sleep(.1)
print("Game Audio Start")
p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
p.play()
So from a brief look at it, it seems that 'time.sleep(.1)' is not doing what you are expecting. Ie. it is obviously interrupted by button presses. This is not abnormal behaviour as button presses on Ardiuno and raspPi (guessing here) would be processed as interrupts.
The script itself does not contain any prevention from double pressing or press and hold etc.
Have you put in any debug lines to see what is executing when you press the button?
I would start there and make adjustments based on what you are seeing.
I am not familiar with this gpiozero, so I can't give any insight about what it may be doing, but looking at the code and given the issue you are having, I would start with some debug lines in both functions to confirm what is happening.
Thinking about it for a minute though, could you not just change the check to 'if greenButton.is_released:'? As then you know the button has already been pressed, and the amount of time it is held in for becomes irrelevant. May also want to put in a check for if the file is already playing to stop it and start it again, or ignore and continue playing (if that is the desired behaviour).
Further suggestions:
For this section of code:
# Executed Script
while True:
if greenButton.is_pressed:
green_btn_pressed()
time.sleep(.1)
print("Game Audio Start")
p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
p.play()
You want to change this to something along these lines:
alreadyPlaying = 0
# Executed Script
while True:
if greenButton.is_pressed:
green_btn_pressed()
#Check if already playing file.
if alreadyPlaying == 1:
# Do check to see if file is still playing (google this, not sure off the top of head how to do this easiest).
# If file still playing do nothing,
#else set 'alreadyPlaying' back to '0'
break
#Check if already playing file.
if alreadyPlaying == 0:
time.sleep(.1)
print("Game Audio Start")
p = vlc.MediaPlayer("/home/pi/Desktop/10 Second Countdown.mp3")
p.play()
alreadyPlaying = 1
Hopefully you get the idea of what I am saying. Best of luck!
i think you have to write something like this in your loop:
import time, vlc
def Sound(sound):
vlc_instance = vlc.Instance()
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(sound)
player.set_media(media)
player.play()
time.sleep(1.5)
duration = player.get_length() / 1000
time.sleep(duration)

Python Image Window Not Closing Properly on Mac

I'm working with OpenCV and trying to figure this out. When I want to read and show an image:
import cv2
img = cv2.imread('baboon.jpg', 0)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyWindow('image')
I write this. But whenever the image display window pops up, I'm not able to close it and execute everything after
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyWindow('image')
because the window will not close unless I quit it.
For example, if I run this code
import cv2
img = cv2.imread('baboon.jpg', 0)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyWindow('image')
#Nothing after this will get executed
print('Hello')
I get no output in my console, but the image window does pop up.
How can I fix this?
(I'm using Pycharm if that helps)
EDIT:
It seems that whenever I press any key the window closes and it works as intended (code after the comment is executed). Not sure why this is happening.
I believe the quit is acting as an interrupt, which quits the entire python program. This is different than pressing a key, which is incorporated into the logic of the actual program and continues to completion:
cv2.waitKey(0) # waits for any key to be pressed to continue the logic of the program
# this is what actually allows you to "display" an image without it immediately disappearing.
I believe you can click on anywhere in the pic and it would return to the code window

How to keep an image open in OpenCV even if u press a key

How I do it? In matplotlib we have Show with False argument you can keep the image without closing. In my script, I pop out two images with cv2.imshow and I read that I can keep them up with waitKey(0), but when I press a key, they dissapear as the waitKey stablishs.
I want to know if there is a equivalent method for OpenCV as Show(False) from matplotlib.pyplot.
When you use waitKey(number), you are setting a timer for how long OpenCV should wait for any key to be pressed and will halt execution during that time until either a key is pressed or the timer is up. When you set number = 0, this is shorthand for saying wait forever until a key is pressed.
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
The above code sets it so that when you press a key, it returns the key that you pressed to the variable: key. Now if key = 27 (i.e. the esacpe key has been pressed), then it will close the window. If not, then it will not. More details can be seen in the link below!
OpenCV Images
Cheers,
warning: if you are using a 64-bit machine, then you need to use
k = cv2.waitKey(0) & 0xFF
You can use a while loop:
while cv2.waitKey(0) != 27:
pass
The loop waits until Escape key is pressed.
Put it at the end of the script, because it's blocking the execution.

How to exit loop on a keypress with python/osx?

I am on OSX.
I am importing opencv-python, so it might help; however, I am not showing anything, it's all command line off-screen processing.
While True:
do work ....
key = cv2.waitKey(1)
print key
The call to cv2.waitKey(1) consistently returns -1.
If I call cv2.imshow(..) before it, then it behaves correctly.
However, I have nothing to show, any chance I can still detect a keypress?
I need a keypress which isn't ctrl+c

GUI button got stuck

I created a GUI using Tkinter. It has three buttons. one to capture image. second for capturing continuous images until i press third button i.e stop button.
When I press the first button it works fine i.e it runs a function which captures an image and save that image to a particular location.
But when I press the second button for continuous capturing of images then it starts capturing images but button gets stuck or GUI stopped working. because of this I am not able to stop this continuous capturing of images because I cannot press the third button i.e stop button.
I am running a while loop for continuous capturing of images and I can only break this loop if a Global variable STOP will have "0" in it and I can only make it zero by pressing stop button of GUI. But I cannot press stop button to make this STOP variable "0" so that loop can break. I think while loop is stopping the GUI main-loop and creating this problem. if you some have alternative or solution please share it.this is the code
Second button just call this function
def capture_video():
stop = '1'
l=Lepton()
l.enter()
path="/home/ubuntu/Desktop/IR_videos/vid_"
file=open("/home/ubuntu/Desktop/IR_videos/vid_no.txt",'r')
no=file.read()
file.close()
folder_name=path+no
os.mkdir(folder_name)
i=0
print("Image capturing started")
print("____Press Stop button to stop____")
while True:
a=l.capture()
cv2.normalize(a,a,0,65535,cv2.NORM_MINMAX)
np.right_shift(a,8,a)
img=np.uint8(a)
img_name=folder_name+"/"+str(i)+".jpg"
cv2.imwrite(img_name,img)
i=i+1
if stop == "0":
print("Image capturing stoped\n")
print("Press video button to capture again")
break
no=int(no)+1
file=open("/home/ubuntu/Desktop/IR_videos/vid_no.txt",'w')
file.write(str(no))
file.close()
cv2.destroyAllWindows()
l.exit()
here lepton is a class and capture() is function to capture image from flir lepton camera
and this is code of GUI stop button function :
def stop_it():
lep.stop='0'
time.sleep(1)
lep.stop='1'
You should run capture_video() on another thread than the main so that the main does not freeze. This way, you will be able to click on your Stop button. Also, make sure your stop variable inside capture_video is accessible by your stop_it function. In your capture_video, your stop variable is local and thus cannot be changed.
You can find an excellent answer on how to run a function on another thread here: https://stackoverflow.com/a/14331755/9729313
Here another example with threading and Tkinter:
https://stackoverflow.com/a/50175727/9729313

Categories