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()
Related
So I am trying to code up something that keeps a video running until a condition is met and some processes are done and new video is loaded immediately after these processes. These processes should continue without closing the current video and should only close the current video when the new video is loaded and ready for vizualization.
This is best formulated by an example as given below:
import numpy as np
import os
import pygame
import cv2
import time
def play_video(vid_loc):
pygame.init()
infos = pygame.display.Info()
screen_size = (infos.current_w, infos.current_h)
cap = cv2.VideoCapture(vid_loc)
frame_counter =0
while(True):
ret, frame = cap.read()
frame_counter += 1
if frame_counter == cap.get(cv2.CAP_PROP_FRAME_COUNT):
frame_counter = 0
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
frame= cv2.resize(frame,screen_size)
cv2.namedWindow('image', flags=cv2.WINDOW_GUI_NORMAL)
cv2.setWindowProperty("image", cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
cv2.imshow('image',frame)
if cv2.waitKey(1000) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
vid_loc = ["home/odd.ogv", "home/even.ogv"]
while True:
n = random.randint(1, 100)
if n%2 == 0:
play_video(vid_loc[1])
else:
play_video(vid_loc[0])
time.sleep(10)
So this code generates a random number and checks if it is a even number or not. If even it runs a different video and if odd another video. My expectation with this code was to keep the random number being generated every
10 second and keep the video running while the "while loop" runs again , generates another random number and checks if it is even or not without closing the video. If the number is odd , another video is run immediately after current video is closed. However this code would just keep the video running in loop as intended but does not generate another random number.
It basically gets stuck at cv2.imshow until "q" key is pressed and only then the "while loop" runs again.
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.
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...