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
Related
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)
Working with the code sample from How does QueryFrame work? I noticed that the program used a lot of time to exit if it ran to the end of the video. I wanted to exit quickly on the last frame, and I verified that it's a lot quicker if I don't try to play past the end of the video, but there are some details that don't make sense to me. Here's my code:
import cv2
# create a window
winname = "myWindow"
win = cv2.namedWindow(winname, cv2.CV_WINDOW_AUTOSIZE)
# load video file
invideo = cv2.VideoCapture("video.mts")
frames = invideo.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)
print "frame count:", frames
# interval between frame in ms.
fps = invideo.get(cv2.cv.CV_CAP_PROP_FPS)
interval = int(1000.0 / fps)
# play video
while invideo.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) < frames:
print "Showing frame number:", invideo.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
(ret, im) = invideo.read()
if not ret:
break
cv2.imshow(winname, im)
if cv2.waitKey(interval) == 27: # ASCII 27 is the ESC key
break
del invideo
cv2.destroyWindow(winname)
The only thing is that the frame count returned is 744, while the last played frame number is 371 (counting from 0, so that's 372 frames). I assume this is because the video is interlaced, and I guess I need to account for that and divide interval by 2 and frames by 2. But the question is, how do I figure out that I need to do this? There doesn't seem to be a property to check this:
http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture-get
I have a bunch of videos and depthmaps showing human poses from the Microsoft Kinect.
I can get a skeleton of the human in the video but what I want to do is recognize a certain pose from this skeleton data.
To do that I need to annotate each frame in the videos with a 0 or 1, corresponding to "bad pose" and "good pose", i.e. the frame has a binary state variable.
I want to be able to playback the avi file in matlab and then press space to switch between these two states and simultaneously add the state variable to an array giving the state for each frame in the video.
Is there a tool in matlab that can do this? Otherwise matlab is not a restriction, python, C++ or any other language is fine.
I have been googling around, and most of the stuff I have found is to annotate individual frames with a polygon. I want to do this at maybe half the regular framerate of the video.
EDIT: I used the solution provided by miindlek and decided to share a few things if someone runs into this. I needed to see in the video what annotation I was assigning to each frame, so I made a small circle in the upper left corner of the video as I displayed it. Hopefully this will be useful for someone else later. I also capture the key pressed with waitKey and then do something based on the output. This allows for multiple keys to be pressed during the annotations.
import numpy as np
import cv2
import os
os.chdir('PathToVideo')
# Blue cicle means that the annotation haven't started
# Green circle is a good pose
# Red is a bad pose
# White circle means we are done, press d for that
# Instructions on how to use!
# Press space to swap between states, you have to press space when the person
# starts doing poses.
# Press d when the person finishes.
# press q to quit early, then the annotations are not saved, you should only
# use this if you made a mistake and need to start over.
cap = cv2.VideoCapture('Video.avi')
# You can INCREASE the value of speed to make the video SLOWER
speed = 33
# Start with the beginning state as 10 to indicate that the procedure has not started
current_state = 10
saveAnnotations = True
annotation_list = []
# We can check wether the video capture has been opened
cap.isOpened()
colCirc = (255,0,0)
# Iterate while the capture is open, i.e. while we still get new frames.
while(cap.isOpened()):
# Read one frame.
ret, frame = cap.read()
# Break the loop if we don't get a new frame.
if not ret:
break
# Add the colored circle on the image to know the state
cv2.circle(frame,(50,50), 50, colCirc, -1)
# Show one frame.
cv2.imshow('frame', frame)
# Wait for a keypress and act on it
k = cv2.waitKey(speed)
if k == ord(' '):
if current_state==0:
current_state = 1
colCirc = (0,0,255)
else:
current_state = 0
colCirc = (0,255,0)
if current_state == 10:
current_state = 0
colCirc = (0,255,0)
if k == ord('d'):
current_state = 11
colCirc = (255,255,255)
# Press q to quit
if k == ord('q'):
print "You quit! Restart the annotations by running this script again!"
saveAnnotations = False
break
annotation_list.append(current_state)
# Release the capture and close window
cap.release()
cv2.destroyAllWindows()
# Only save if you did not quit
if saveAnnotations:
f = open('poseAnnot.txt', 'w')
for item in annotation_list:
print>>f, item
f.close()
One way to solve your task is using the opencv library with python, as described in this tutorial.
import numpy as np
import cv2
cap = cv2.VideoCapture('video.avi')
current_state = False
annotation_list = []
while(True):
# Read one frame.
ret, frame = cap.read()
if not ret:
break
# Show one frame.
cv2.imshow('frame', frame)
# Check, if the space bar is pressed to switch the mode.
if cv2.waitKey(1) & 0xFF == ord(' '):
current_state = not current_state
annotation_list.append(current_state)
# Convert the list of boolean values to a list of int values.
annotation_list = map(int, annotation_list)
print annotation_list
cap.release()
cv2.destroyAllWindows()
The variable annotation_list contains all annotations for each frame. To switch between the two modes, you have to press the space bar.
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...