My current mode of recording video using opencv looks something like this
import cv
capture=cv.CaptureFromCAM(self.deviceID)
img_size=cv.GetSize(cv.QueryFrame(capture))
#create a writer object for the video
writer=cv.CreateVideoWriter(
filename='temp.avi',
fourcc=cv.CV_FOURCC('M','J','P','G'),
fps=15,
frame_size=img_size,
is_color=1)
while True:
#grab the frame
img=cv.QueryFrame(capture)
#write frame to video
cv.WriteFrame(writer,img)
#if 'Enter' or 'Esc' key is pressed, end video capture
c = cv.WaitKey(7) % 0x100
if c == 27 or c == 10:
break
The problem is that I have to manually set the frames per second in advance. I've storing the images in a list and keeping track of how much time has elapsed, but that just exports a file with no frames:
import cv
import time
capture=cv.CaptureFromCAM(self.deviceID)
img_size=cv.GetSize(cv.QueryFrame(capture))
imgList=[]
zero=time.time()
while True:
#grab the frame
img=cv.QueryFrame(capture)
imgList.append(img)
cv.ShowImage("Window1",img)
#if 'Enter' or 'Esc' key is pressed, end video capture
c = cv.WaitKey(7) % 0x100
if c == 27 or c == 10:
break
duration=time.time()-zero
framesPerSecond=len(imgList)/duration)
writer=cv.CreateVideoWriter(
filename='temp.avi',
fourcc=cv.CV_FOURCC('M','J','P','G'),
fps=framesPerSecond,
frame_size=img_size,
is_color=1)
for i in imgList:
cv.writeFrame(writer,i)
A little stucks. Any suggestions on an alternative method or tweaks to my existing code would be greatly helpful.
Related
I'm trying to read a video, put some shapes on it and write it out using opencv-python (using VideoWriter class):
def Mask_info(path):
"""This function will mask the information part of the video"""
video = cv.VideoCapture(path)
framenum = video.get(cv.CAP_PROP_FRAME_COUNT)
fps = video.get(cv.CAP_PROP_FPS)
fourcc = cv.VideoWriter_fourcc(*"vp09")
width = int(video.get(cv.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv.CAP_PROP_FRAME_HEIGHT))
size = (width,height)
if (video.isOpened ==False ):
print("Error while reading the file.")
result = cv.VideoWriter("masked_video.mp4",fourcc,fps,size)
while(True):
isTrue,frame = video.read()
cv.rectangle(frame,(65,0),(255,10),(0,0,0),-1)
cv.rectangle(frame,(394,0),(571,10),(0,0,0),-1)
if isTrue == True:
result.write(frame)
cv.imshow("Masked Video",frame)
if cv.waitKey(1) & 0xFF == ord("d"):
break
else:
break
video.release()
result.release()
cv.destroyAllWindows()
Mask_info("samplesound.webm")
The problem is that the output video length is zero, while the input video is 10 seconds.
To elaborate on my comment above:
You should verify that video.read() returns any valid frame.
It could be that due to path or other issue the VideoCapture failed to open the input file.
You attempt to draw the rectangles (using cv.rectangle) before the if that checks whether you have a valid frame.
But if video.read() failed (e.g. when reaching the end of the input) frame will be None. Then cv.rectangle will throw an exception causing the program to terminate without flushing and closing the output file.
Instead you should do the drawings inside the isTrue == True branch of the if:
if isTrue == True:
cv.rectangle(frame,(65,0),(255,10),(0,0,0),-1)
cv.rectangle(frame,(394,0),(571,10),(0,0,0),-1)
result.write(frame)
# ...
I just want to capture one frame, save it to test.png and then exit the code.
In this program exit() doesn't work, I have to use CTRL+C from the terminal every time.
import cv2
#cv2.namedWindow("window")
cap = cv2.VideoCapture(0)
if cap.isOpened(): # if we are able to capture the first frame.
val, frame = cap.read()
else:
val = False
while val:
#cv2.imshow("window", frame)
cv2.imwrite('test.png',frame)
val, frame = cap.read()
key = cv2.waitKey(20)
if key == 27: # exit on ESC
break
cap.release
cv2.destroyAllWindows()
exit()
Thanks in advance.
cv::waitKey only works if any openCV window is present and maybe active.
Since you commented #cv2.namedWindow("window") and #cv2.imshow("window", frame) out there is no waitKey time and no chance to fetch the key.
Does it work if you activate namedWindow and imshow?
To be sure additionally try
if key > 0: # exit on ESC
break
to cancel on ANY keypress (but you still need an active openCV window)
To capture a single frame try this:
import cv2
cap = cv2.VideoCapture(0)
val = False
maxTry = 100 # maximum number of tries to capture a frame from an opened device
cTry = 0
if cap.isOpened(): # if we are able to capture the first frame.
while (!val) and (cTry < maxTry)
val, frame = cap.read()
cTry = cTry + 1
else:
val = False
if val:
cv2.imwrite('test.png',frame)
else:
print "No image captured"
cap.release
exit()
I am not a python programmer so please forgive me any syntax errors (and give me a hint to correct them)
The method waitkey(t) waits t in milliseconds, so your code is waiting 20 ms for a key press for each loop. Considering that your
cv2.imwrite('test.png',frame)
might take some time to write to file, are you perhaps pressing your exiting key at the wrong moment?
Try adding & 0xFF to the wait key:
key = cv2.waitKey(20) & 0xFF
You also need an active window:
Note
The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active.
for python3
cv2.imshow('imafast', frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
Aim : Detect the motion and save only the motion periods in files with names of the starting time.
Now I met the issue about how to save the video to the files with video starting time.
What I tested :
I tested my program part by part. It seems that each part works well except the saving part.
Running status: No error. But in the saving folder, there is no video. If I use a static saving path instead, the video will be saved successfully, but the video will be override by the next video. My codes are below:
import cv2
import numpy as np
import time
cap = cv2.VideoCapture( 0 )
bgst = cv2.createBackgroundSubtractorMOG2()
fourcc=cv2.VideoWriter_fourcc(*'DIVX')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
n = "start_time"
while True:
ret, frame = cap.read()
dst = bgst.apply(frame)
dst = np.array(dst, np.int8)
if np.count_nonzero(dst)>3000: # use this value to adjust the "Sensitivity“
print('something is moving %s' %(time.ctime()))
path = r'E:\OpenCV\Motion_Detection\%s.avi' %n
out = cv2.VideoWriter( path, fourcc, 50, size )
out.write(frame)
key = cv2.waitKey(3)
if key == 32:
break
else:
out.release()
n = time.ctime()
print("No motion Detected %s" %n)
What I meant is:
import cv2
import numpy as np
import time
cap = cv2.VideoCapture( 0 )
bgst = cv2.createBackgroundSubtractorMOG2()
fourcc=cv2.VideoWriter_fourcc(*'DIVX')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
path = r'E:\OpenCV\Motion_Detection\%s.avi' %(time.ctime())
out = cv2.VideoWriter( path, fourcc, 16, size )
while True:
ret, frame = cap.read()
dst = bgst.apply(frame)
dst = np.array(dst, np.int8)
for i in range(number of frames in the video):
if np.count_nonzero(dst)<3000: # use this value to adjust the "Sensitivity“
print("No Motion Detected")
out.release()
else:
print('something is moving %s' %(time.ctime()))
#label each frame you want to output here
out.write(frame(i))
key = cv2.waitKey(1)
if key == 32:
break
cap.release()
cv2.destroyAllWindows()
If you see the code there will be a for loop, within which the process of saving is done.
I do not know the exact syntax involving for loop with frames, but I hope you have the gist of it. You have to find the number of frames present in the video and set that as the range in the for loop.
Each frame gets saved uniquely (see the else condition.) As I said I do not know the syntax. Please refer and follow this procedure.
Cheers!
anybody familiar with openCV know how to make it so the output is a different file each time. OR how to make it so the video appends to the original one.
here is the code I am working with
import RPi.GPIO as GPIO
import cv2
import numpy as np
import datetime
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.IN)
import os
# Setup the camera such that it closes
# when we are done with it.
os.chdir ("/home/pi/Videos")
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
while True:
if GPIO.input(11) == 1:
filename = datetime.datetime.now() .strftime ("%Y-%m-%d-%H.%M.%$
print("about to record")
out = cv2.VideoWriter('video.avi', fourcc, 20.0, (640,480))
ret, frame = cap.read()
if ret==True:
out.appendleft(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q') or GPIO.input(11) $
break
else:
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
thanks in advance for any and all help!
This function will store data in a progressive filename system
from os import path
def open_next_file(someData, template='incomingVideo{}.jpg'):
"""Creates a new file for storing new Firmware."""
## Store upto 100 file names
for serial in range(100):
if not path.exists(template.format(serial)):
## if file does not exist,
## enter data into the new file
with open(template.format(serial), 'wb+') as f:
f.write(someData)
break
else:
## if file already exists then,
## don't write on existing files
pass
return template.format(serial)
you can call this function everytime you want to write a new data to a new file viz. incomingVideo1.jpg or incomingVideo2.jpg
You can change the parameters according your needs.
Example
newFile = open_next_file(someDat="Write this inside")
print(newFile)
gives result as incomingVideoX.jpg where x depends on range() function in the loop
I tried to search in SO but could not find.I want to iterate video file frame by frame and want to detect if there is any point when resolution of two consecutive frame changes. The desired functionality in pseudocode:
resolution1 = videoFile[0]->resolution
resolution2 = 0;
for frame in videoFile[1:]:
resolution2 = frame->resolution
if (resolution1 != resolution2):
print 'Changes occured'
else:
resolution1 = resolution2
Please give me the name of a library to implement them, I have tried and read documentation of OpenCV and PiCamera.
Thanks in advance
You should use OpenCV to iterate through each frame. This should print "Changes occured" whenever the video changes resolution:
import cv2
capture1 = cv2.VideoCapture('videoname') #Open the video
ret, frame = capture1.read() #Read the first frame
resolution1 = frame.shape #Get resolution
while capture1.isOpened():
ret, frame = capture1.read() #Read the next frame
if ret == False or frame == None:
break #Quit if video ends
resolution2 = frame.shape #Get the new resolution
if resolution1 != resolution2:
print 'Changes occured'
#Change resolution1 to resolution2 so that the new resolutions are
#compared with resolution2, not resolution1.
resolution1 = resolution2