cv2.VideoCapture on python - python

I am running the following code:
import numpy as np
import cv2
import os
count = 0
cap = cv2.VideoCapture("/home/simon/PROJECT/real_data/00000020.mp4")
while not cap.isOpened():
cap = cv2.VideoCapture("./00000020.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) & 0xFF == 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
if ret == True:
frame = cv2.VideoCapture.grab()
frame = 'frame%d' % count
cv2.imwrite('frame%d.png', frame)
count += 1
else:
print 'stopped at' + count
break
And whenever I run it, it loops on the while not loop, printing "wait for header".
There is never an error code or anything like that either.
I have tried to run it as a more simple piece of code, where it doesnt have all these checks, and again that doesn't throw any errors.
I am attempting to run this code to open a video, and then save the frames as png files throughout the video.
Does anyone spot any particular problems with the code?
Or alternatively does anyone know a piece of code that would do what i want more efficiently, as I have trawled through google searches and stack overflow a lot recently and haven't found anything
Thanks in advance
Panda

You need to include a couple of DLLs in your python directory in order to play videos. Please see this for details:
https://li8bot.wordpress.com/2014/07/09/opencvpython-part-1-working-with-videos/

Related

Using OpenCV to take a particular amount of images without pressing any key

I wish to write a program for face recognition. I want my program to automatically take a specific number of images(say,5). Here is what I am currently doing:
import cv2
cam=cv2.VideoCapture(0)
a=0
count=0
for a in range(5):
ret,img=cam.read()
cv2.imshow("Test",img)
if not ret:
break
k=cv2.waitKey(1)
print("Image"+str(count)+"saved")
file='C:/Users/User/Desktop/FACEREC/known_faces/img_test/ad2'+str(count)+'.jpg'
cv2.imwrite(file,img)
a+=1
cam.release()
cv2.destroyAllWindows()
cam.release()
cv2.destroyAllWindows()
It shows "Image 0 saved" five times but in the folder(ad2), there is only a single image. Need some guidance.
Thank you
Lets start interpreting the code line-by-line:
Variable initialization
import cv2
cam=cv2.VideoCapture(0)
a=0
count=0
You load the opencv library and initialize the cam variable for webcam display. Then both a and count are intialized to 0. Now count variable is understandable, most probably count count the frames. What does a do?
Display and save frames
First-part
for a in range(0, 5):
ret,img=cam.read()
cv2.imshow("Test",img)
if not ret:
break
variable a declared again so we don't need to intialize at the beginning. Then current web-frame is being fetched. The frame is given as an input to imshow without even the current frame returned or not. The correct logic should be:
for a in range(5):
ret,img=cam.read()
if ret:
cv2.imshow("Test",img)
Second-part
k=cv2.waitKey(1)
print("Image"+str(count)+"saved")
file='C:/Users/User/Desktop/FACEREC/known_faces/img_test/ad2'+str(count)+'.jpg'
cv2.imwrite(file,img)
a+=1
Now, the k variable is initialized as a key for quiting the program when a key is pressed. Say, when q is pressed program terminates.
k=cv2.waitKey(1) & 0xFF
if k == ord('q'):
break
But if you break during the process, then you can't save the images. Therefore break should be at the end of the line.
For the rest of the code, you can use a as a counter. If you specify the start and end values. For each value a is increased by one. Then you can use it to discriminate the frames.
Code:
# Load the library
import cv2
# Initialize webcam
cam = cv2.VideoCapture(0)
# Save the frames
for a in range(0, 5):
# Get current frame
ret, img=cam.read()
# If frame is returned
if ret: 
# Set the file-name
file='C:/Users/User/Desktop/FACEREC/known_faces/img_test/ad2' + str(a) + '.jpg'
# Write the frame
cv2.imwrite(file, img)
# Inform the user
print("Image" + str(a) + "saved")
# Display the frame
cv2.imshow("Test", img)
# If q is pressed quit
k=cv2.waitKey(1) & 0xFF
if k == ord('q'):
break
# Release the object
cam.release()
# Close the window
cv2.destroyAllWindows()

I am trying to build Motion Detector using openCV and python but display window is not responding when I terminate program

Here is the code for the same, have a look at it. In this, below code I am creating a Motion Detector and with this I will be recording the timings of when the various objects appeared and disappeared for which I am using dataframe.
The issue with this is that the program executes but when the output is displayed in the form of a Window, it freezes when I try to terminate.
import cv2, pandas
from datetime import datetime
first_frame = None
status_list = [None,None]
times = []
df = pandas.DataFrame(columns=["Start", "End"]) #Dataframe to store the time values during which object detection and movement appears.
video = cv2.VideoCapture(0)#VideoCapture object is used to record video using web cam
while True:
#check is a bool data type, returns true if VideoCapture object is read
check,frame = video.read()
status = 0
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # For converting the frame color to gray scale
gray = cv2.GaussianBlur(gray,(21,21),0) # For converting the gray scale frame to GaussianBlur
if first_frame is None:
first_frame = gray # used to store the first image/frame of the video
continue
delta_frame = cv2.absdiff(first_frame,gray)#calculates the difference between first and other frames
thresh_delta = cv2.threshold(delta_frame,30,255,cv2.THRESH_BINARY)[1]
thresh_delta = cv2.dilate(thresh_delta,None,iterations=0) #Provides threshold value, so if the difference is <30 it will turn to black otherwise if >30 pixels will turn to white
(_,cnts,_) = cv2.findContours(thresh_delta.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) #Define the contour area,i.e. adding borders
#Removing noises and shadows, any part which is greater than 1000 pixels will be converted to white
for contour in cnts:
if cv2.contourArea(contour) < 1000:
continue
status = 1 #change in status when the object is detected
#Creating a rectangular box around the object in frame
(x,y,w,h) = cv2.boundingRect(contour)
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),3)
#list of status for every frame
status_list.append(status)
status_list=status_list[-2:]
#Record datetime in a list when change occurs
if status_list[-1]==1 and status_list[-2]==0:
times.append(datetime.now())
if status_list[-1]==0 and status_list[-2]==1:
times.append(datetime.now())
cv2.imshow('frame',frame)
#cv2.imshow('Capturing',gray)
#cv2.imshow('delta',delta_frame)
#cv2.imshow('thresh',thresh_delta)
key = cv2.waitKey(1) #changing the frame after 1 millisecond
#Used for terminating the loop once 'q' is pressed
if key == ord('q'):
break
print(status_list)
print(times)
for i in range(0,len(times),2):
df = df.append({"Start":times[i],"End":times[i+1]},ignore_index=True)
df.to_csv("Times.csv")
video.release()
cv2.destroyAllWindows #will be closing all the windows
Try this:
if cv2.waitKey(1) & 0xFF == ord('q'):
break
For a brief explanation about what "& 0xFF" is, see: What's 0xFF for in cv2.waitKey(1)?
It is basically a bit mask that takes the portion of 'waitKey' value(32 bit) that can be compared to ASCII (8 bit).
You can try this.
k = cv2.waitKey(1) & 0xFF
if k == 27 :
break
where k can be any ASCII code on the keyboard ASCII code help
In this case 27 is 'Esc' button.
However, the problem you're having where it is freezing, have you tried continuously pressing any button besides q? I had a similar problem when I was testing out OpenCV's tutorial code here
but i figured it out by playing around and then realizing i needed to hold down any button besides the 'exit' button.
I had faced the same issue bcz of this piece of code from geeksforgeeks
Please chck the last line of the code:
cv2.destroyAllWindows #will be closing all the windows
Add parenthesis, it shud b:
cv2.destroyAllWindows()
Please try this, rest looks fine
Well you can also pass a particular frame that you want to close like:
cv2.destroyAllWindows("frame")

time.sleep for only a part of the code inside infinite while loop

I'm working with a code that analyzes frames from a live stream with OpenCV and if a condition is met saves the current frame to file.
The infinite loop to analyze the video frame by frame is something like this:
while True:
ret,frame = stream.read()
if conditionisMet :
pil_image = Image.fromarray(frame)
pil_image.save("/path/to/folder/image.jpg")
cv2.imshow("LiveStream", frame)
What I want to add is that if the condition is met again too soon (20-30 sec) the image does not have to be saved and the while loop has to grab another frame and continue its work. I've tried with time.sleep(30.0) inside the if statement but it blocks the while loop waiting for the 30 sec to pass. Is there a way to use time.sleep in this case, or another method suitable for my needs?
Thanks in advance
you could do something like this:
last_grab=time.time()-30 # this to get things started
while True:
if condition and time.time()-last_grab > 30:
last_grab=time.time()
# Do things here
else:
continue
Just add a variable to keep track of your last saving time:
last_save_time = time.time()
while True:
ret,frame = stream.read()
if conditionisMet and time.time() - last_save_time() > 20:
pil_image = Image.fromarray(frame)
pil_image.save("/path/to/folder/image.jpg")
# update last save time
last_save_time = time.time()
cv2.imshow("LiveStream", frame)
Why not just capture the amount of time running then save image if greater than the given amount of time....
a = dt.now()
b = dt.now()
c = b - a
if c < x:
do something

opencv while loops, going back to first loop

I have a the following python code (and I'm using opencv3). What this code needs accomplish is to take a live stream of a generic camera, and then analyze a static picture (or frame). The problem that I have have, is that after exiting the second nested while loop, i can figure out how to go back to the initial loop (#1st loop).
The code should :
Take live stream
press 'q' to capture frame and go to the next loop
on this second loop:
if 's' -after the images is analyzed- it should go back to the 1st loop. if 'esc' the program should be terminated.
I did tried the recursion method (def () ) but I run into another problem in which i couldn't figure out how to terminate the program.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
#Set LED brightness for camera
cap.set(cv2.CAP_PROP_BRIGHTNESS, 120)
#1st loop
while (True):
#capture camera stream
ret, frame = cap.read()
cv2.imshow('live image', frame)
if cv2.waitKey(0) == ord('q'):
cap.release()
cv2.destroyAllWindows()
pass
print ('image alteration block')
#2nd loop
while (True):
img = frame
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k == 27: # wait for ESC key to exit and terminate progra,
cv2.destroyAllWindows()
break
elif k == ord('s'): # wait for 's' key to save the image and go back to the live stream
cv2.imwrite('messigray.png',img)
print ('go back to the beginning')
cv2.destroyAllWindows()
continue #NOT SURE WHAT TO DO HERE
You're not allowing the program to escape the second while loop. Use a different while condition in the second loop. Instead of while(True) use a boolean:
#2nd loop
second=True
while (second):
img = frame
cv2.imshow('image',img)
k = cv2.waitKey(0)
if k == 27: # wait for ESC key to exit and terminate progra,
cv2.destroyAllWindows()
break
elif k == ord('s'):
cv2.imwrite('messigray.png',img)
print ('go back to the beginning')
cv2.destroyAllWindows()
#modify the loop condition
second = False
continue
That should get you out of the second loop, relying on breaks is not always the best way to handle while loops.

Start video read from a particular frame

I have obtained the frame_count of a saved video.
self.frame_count = self.capture.get(cv.CV_CAP_PROP_FRAME_COUNT) - 1
Now, I want to start a frame read from a particular frame_count. How do I do this?
Reason: I need to track an object and I have found the location of the object I want to track using HSV image segmentation. Now to track it, I intend to start the video from that particular frame and set the track window to the objects' coordinates.
Want: It should not be redundant and computationally intensive.
Use the below code to accomplish your task.
The Opencv version you are using is old. Use Opencv2.
Link : http://docs.opencv.org/trunk/doc/py_tutorials/py_tutorials.html
import numpy as np
import cv2
import os
cam = cv2.VideoCapture('full_path/bird.avi')
i = 1
initialize_first_frame = cam.read()[1]
start_from_frame = 5
dir = './testImages/'
os.makedirs(dir)
while True:
if(i>=start_from_frame):
cv2.imshow('Frame Conversion',cam.read()[1])
cv2.imwrite(dir + "/image-"+str(i).zfill(5)+".png",cam.read()[1])
i = i + 1
key = cv2.waitKey(10)
if key == 27:
cv2.destroyWindow('Frame Conversion')
break
print "End"
I hope this is the code you want.
Try the following:
f = # put here the frame from which you want to start
self.capture.set(CV_CAP_PROP_POS_FRAMES, f)
while f < self.frame_count:
retval, image = self.capture.read()
f += 1
For any version 3 and 4 of OpenCV Python, follow this -
import cv2
# suppose you want to start reading from frame no 500
frame_set_no = 500
cap = cv2.VideoCapture("full_path/cow.mp4")
# capture is set to the desired frame
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_set_no)
while True:
ret, frame = cap.read()
cv2.imshow("Video", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

Categories