This question already has answers here:
How to detect ESCape keypress in Python?
(5 answers)
Closed 5 years ago.
I made a program that reads pixels from a camera. I have used a while loop. But I can't close the program from terminal without pressing 'Cltrl + C'. I want to close the program using ESC button ( ASCII 27). I tried the following code, which is not working. Any help would be appreciated
import cv2 as cv
import numpy as np
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
redimage = frame[:,:,2]
print(redimage)
k = cv.waitKey(1) & 0xFF
if k == 27:
break
Use:
if k == chr(27):
break
cv.waitKey(1) is working for opencv gui only. You can't capture keyboard events in console with this function.
So, you can change your code to show the frame that you are reading from the camera.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
redimage = frame[:,:,2]
cv2.imshow('frame', frame)
print(redimage)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
You can find in this answer a way to capture keyboard events in console.
Related
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.
I am trying to create a simple program that will play a video using OpenCV on repeat until the waitKey is pressed. The video will play once and then give an error message "(-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'". I was getting this message earlier but fixed it by changing the file location. I'm almost positive that the issue comes from the fact that when the video ends the next frame is nonexistent so it cant be read, as breaking the while loop when the frame is None doesn't give an error. Every solution I have tried has failed. Any help?
import cv2
import numpy as np
cap = cv2.VideoCapture('video_file_location')
while True:
_, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
Try putting the cv2.VideoCapture() into the loop and the frame should only show when the return is True and that is your problem in your code
import cv2
import numpy as np
while True:
#This is to check whether to break the first loop
isclosed=0
cap = cv2.VideoCapture('videoplayback.mp4')
while (True):
ret, frame = cap.read()
# It should only show the frame when the ret is true
if ret == True:
cv2.imshow('frame',frame)
if cv2.waitKey(1) == 27:
# When esc is pressed isclosed is 1
isclosed=1
break
else:
break
# To break the loop if it is closed manually
if isclosed:
break
cap.release()
cv2.destroyAllWindows()
I have the following code, which continuously fetches all the frames from a video by using VideoCapture library in opencv in python:
import cv2
def frame_capture:
cap = cv2.VideoCapture("video.mp4")
while not cap.isOpened():
cap = cv2.VideoCapture("video.mp4")
cv2.waitKey(1000)
print "Wait for the header"
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
while True:
flag, frame = cap.read()
if flag:
# The frame is ready and already captured
cv2.imshow('video', frame)
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
print str(pos_frame)+" frames"
else:
# The next frame is not ready, so we try to read it again
cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
print "frame is not ready"
# It is better to wait for a while for the next frame to be ready
cv2.waitKey(1000)
if cv2.waitKey(10) == 27:
break
if cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
But I want to grab a specific frame in a specific timestamp in the video.
How can I achieve this?
You can use set() function of VideoCapture.
You can calculate total frames:
cap = cv2.VideoCapture("video.mp4")
total_frames = cap.get(7)
Here 7 is the prop-Id. You can find more here http://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html
After that you can set the frame number, suppose i want to extract 100th frame
cap.set(1, 100)
ret, frame = cap.read()
cv2.imwrite("path_where_to_save_image", frame)
this is my first post so please don't rip into me if I don't follow protocol completely. I just wanted to respond to June Wang just in case she didn't figure out how to set the number of frames to be extracted, or in case anyone else stumbles upon this thread with that question:
The solution is the good ol' for loop:
vid = cv2.VideoCapture(video_path)
for i in range(start_frame, how_many_frames_you_want):
vid.set(1, i)
ret, still = vid.read()
cv2.imwrite(f'{video_path}_frame{i}.jpg', still)
I would like to create a program which saves .jpg images taken from the webcam(frames).
What my program do for now is, opening a webcam, taking one and only one frame, and then everything stops.
What i would like to have is more than one frame
My error-code is this one:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
count = 0
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imwrite("frame%d.jpg" % ret, frame) # save frame as JPEG file
count +=1
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(10):
break
Actually it sounds like you are always saving your image with the same name
because you are concatenating ret instead of count in the imwrite method
try this :
name = "frame%d.jpg"%count
cv2.imwrite(name, frame) # save frame as JPEG file
use this -
count = 0
cv2.imwrite("frame%d.jpg" % count, frame)
count = count+1
When no key is pressed and the time delay expires, cv2.waitKey returns -1. You can check it in the doc.
Basically, all you have to do is changing slightly the end of your program:
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(10) != -1:
break
Though this is late I have to say that prtkp's answer is what you needed... the , ret value you use to enumerate your images is wrong. Ret is only a boolean... so while it detects the image it its placing a one there for the name of the image...
I just used this... with a c=0 on the header
cv2.imwrite("img/frame %d.jpg" % c,img)
c=c+1
I am using a loop to access all frames of a video file using Python and OpenCV. While accessing each frame, I add the index of the frame in a list.
However I compare the size of the list and the number of frames that I get using the
Frames = cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)
command and the size of the list is constantly one less element than the number of the frames of the video reytned by cap.get...
Any ideas why is this happening ?
Here is the code I use:
# -*- coding: utf-8 -*-
import cv2
def faceExtraction(inputFile, extractionRate):
cap = cv2.VideoCapture(inputFile)
fps = cap.get(cv2.cv.CV_CAP_PROP_FPS)
Frames = cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)
print 'Frames='+str(Frames)
# if not os.path.exists("registered_face"):
# os.makedirs("registered_face")
frame_counter = 0
outputFrameIndices=[]
while(cap.isOpened()):
frame_counter=frame_counter+1
ret, frame = cap.read() # read current frame
outputFrameIndices.append(frame_counter)
if frame is None:
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# print 'FACE NOT FOUND: frame '+ str(frame_counter)
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
print 'number of frames: ' + str(len(outputFrameIndices))
############## Executing Main App ###########
faceExtraction('Video Filename blah blah',5)
The output my code produces is:
Frames=930.0
number of frames: 929
whereas it should be
Frames=930.0
number of frames: 930
Found the error... Python starts index counters from zero...