How to Deploy Frame differencing python file , to get an endpoint? - python

I want to exact frames from a screen recorded video file, and those frames are used to object detection process later. I already have a python code which can simply exact frames and save them inside my local storage.
import os
import numpy as np
import cv2
from glob import glob
def create_dir(path):
try:
if not os.path.exists(path):
os.makedirs(path)
except OSError:
print(f"ERROR: creating directory with name {path}")
def save_frame(video_path, save_dir, gap=10):
name = video_path.split("/")[-1].split(".")[0]
save_path = os.path.join(save_dir, name)
create_dir(save_path)
cap = cv2.VideoCapture(video_path)
idx = 0
while True:
ret, frame = cap.read()
if ret == False:
cap.release()
break
if idx == 0:
cv2.imwrite(f"{save_path}/{idx}.png", frame)
else:
if idx % gap == 0:
cv2.imwrite(f"{save_path}/{idx}.png", frame)
idx += 1
if __name__ == "__main__":
video_paths = glob("C:/Users/Asus/Documents/4th year/Research/Frame Differencing/video to frame/capture1.mp4")
save_dir = "save"
for path in video_paths:
save_frame(path, save_dir, gap=50)
I want to deploy this to get endpoint (HTTP request). The Request input should be a video file and response should be frames of it. Please help me to deploy this

Related

Save a video with different file name each time we give a Trigger in opencv

This is the process I am trying to achieve :
Live Stream is captured from webcam and the Image frames are stored in a particular folder.
Now, If I give a trigger the frames in that folder at that moment should be converted into a video and get saved with name eg. video1.mp4.
Now again if I press a trigger another video should be saved as video2.mp4.
I have attached the code here . If I press R , it is saving one video as a0.mp4 . But If I press again, nothing seems to happen.
def frametovideo(img_array):
for i in range(len(img_array)):
out.write(img_array[i])
if name == "main":
img_array = []
videono = 0
cap = cv2.VideoCapture(0)
for filename in glob.glob('./output/*.jpg'):
img = cv2.imread(filename)
height, width, layers = img.shape
size = (width,height)
img_array.append(img)
path = 'a' + str(videono) + '.mp4'
out = cv2.VideoWriter(path,cv2.VideoWriter_fourcc(*'mp4v'), 15, size)
while True:
ret, frame = cap.read()
if ret == True:
cv2.imshow("frame",frame)
k = cv2.waitKey(5) & 0xff
if k == ord('r'):
frametovideo(img_array)
videono += 1
You do not understanding how to save filenames Do not used operator. Used string format python 3.8 or later. Try this in below. Actually, you can modified key press.
import cv2
import os
i = 1
wait = 0
video = cv2.VideoCapture(0)
while video.isOpened():
ret, img = video.read()
cv2.imshow('live video', img)
# wait for user to press any key
key = cv2.waitKey(100)
# wait variable is to calculate waiting time
wait = wait+100
if key == ord('q'):
break
# when it reaches to 5000 milliseconds
# we will save that frame in given folder
if wait == 5000:
filename = f'Frame_{str(i)}.jpg'
# Save the images in given path
cv2.imwrite(filename, img)
i += 1
wait = 0
# close the camera
video.release()
# close open windows
cv2.destroyAllWindows()
Btw,look in line #27-34. Correct way to do this if __name__ == "__main__":

Extracting images from camera video at predetermined intervals

I have the code to get images from the video stream of a laptop camera. I want to reduce the photo saving interval to one photo per minute. The original code looks like this
# Importing all necessary libraries
import cv2
import os
# Read the video from specified path
cam = cv2.VideoCapture(0)
try:
# creating a folder named data
if not os.path.exists('data'):
os.makedirs('data')
# if not created then raise error
except OSError:
print ('Error: Creating directory of data')
# frame
currentframe = 0
while(True):
# reading from frame
ret,frame = cam.read()
if ret:
# if video is still left continue creating images
name = './data/frame' + str(currentframe) + '.jpg'
print ('Creating...' + name)
# writing the extracted images
cv2.imwrite(name, frame)
# increasing counter so that it will
# show how many frames are created
currentframe += 1
else:
break
# Release all space and windows once done
cam.release()
cv2.destroyAllWindows()
For this task I try to use the parameter CAP_PROP_POS_MSEC
[...]
# Read the video from specified path
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_POS_MSEC,20000)
[...]
while(True):
[...]
# writing the extracted images
cv2.imwrite(name, frame)
cv2.waitKey()
[...]
But, the saving speed remains the same and I see the following error
videoio error v4l2 property pos_msec is not supported
I use Ubuntu 18.04, Python 3.7, and OpenCV 4.1.
Where do I have a mistake, and whether I chose the right way to minimize the load on my computer's resources?
UPD
Using the recommendation of J.D. this code is working
import cv2
import os
import time
prev_time = time.time()
delay = 1 # in seconds
# Read the video from specified path
cam = cv2.VideoCapture(0)
currentframe = 0
while (True):
# reading from frame
ret, frame = cam.read()
if ret:
if time.time() - prev_time > delay:
# if video is still left continue creating images
name = './data/frame' + str(currentframe) + '.jpg'
print('Creating...' + name)
# writing the extracted images
cv2.imwrite(name, frame)
currentframe += 1
prev_time = time.time()
else:
break
EDIT: this answer is not a good solution - due to the frame buffer, as described in the comments. Because of the relevant information in the comments I will leave the answer.
If you don't plan to expand the code to do other things, you can just use the waitkey:
cv2.waitKey(60000) will freeze code execution 60 secs.
If you want to expand the code, you have to create a time based loop:
import time
prev_time = time.time()
count = 0
delay = 1 # in seconds
while True:
if time.time()-prev_time > delay:
count += 1
print(count)
prev_time = time.time()
you should read separately and set the values again for each image, like this:
while(True):
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_POS_MSEC,20000)
# reading from frame
ret,frame = cam.read()
if ret:
# if video is still left continue creating images
name = './data/frame' + str(currentframe) + '.jpg'
print ('Creating...' + name)
# writing the extracted images
cv2.imwrite(name, frame)
cv2.waitKey()
# increasing counter so that it will
# show how many frames are created
currentframe += 1
else:
break
cam.release()
and check your openCV version for python about the error.

Recording video in specified time intervals and then saving them into file OpenCv Python

Here are my goals.
Capture video continuously until 'q; is pressed
Every ten seconds save the video in created directory file
Continue step two until 'q' is pressed
I am executing the following code. But when creating files it's creating 6kb files and saying cannot play. I am fairly new to opencv and python. Not sure what I am missing. Running this code on pycharm with Python 3.6. Also the
cv2.imshow('frame',frame)
stops after ten seconds but recording is happening in background and files are created.
import numpy as np
import cv2
import time
import os
import random
import sys
fps=24
width=864
height=640
video_codec=cv2.VideoWriter_fourcc('D','I','V','X')
name = random.randint(0,1000)
print (name)
if (os.path.isdir(str(name)) is False):
name = random.randint(0,1000)
name=str(name)
name = os.path.join(os.getcwd(), str(name))
print('ALl logs saved in dir:', name)
os.mkdir(name)
cap = cv2.VideoCapture(0)
ret=cap.set(3, 864)
ret=cap.set(4, 480)
cur_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
start=time.time()
video_file_count = 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
print('Capture video saved location : {}'.format(video_file))
while(cap.isOpened()):
start_time = time.time()
ret, frame = cap.read()
if ret==True:
cv2.imshow('frame',frame)
if (time.time() - start > 10):
start = time.time()
video_file_count += 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
video_writer = cv2.VideoWriter(video_file,video_codec, fps,(int(cap.get(3)),int(cap.get(4))))
time.sleep(10)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
I want files with the recorded videos. Files are generated but size 6kb and nothing is being recorded.
You're almost there! Given that I understood what your goal is, and with minimal change to your code, here is what worked for me.
This writes a new video file every ten seconds while recording each frame into the current video.
import numpy as np
import cv2
import time
import os
import random
import sys
fps = 24
width = 864
height = 640
video_codec = cv2.VideoWriter_fourcc("D", "I", "V", "X")
name = random.randint(0, 1000)
print(name)
if os.path.isdir(str(name)) is False:
name = random.randint(0, 1000)
name = str(name)
name = os.path.join(os.getcwd(), str(name))
print("ALl logs saved in dir:", name)
os.mkdir(name)
cap = cv2.VideoCapture(0)
ret = cap.set(3, 864)
ret = cap.set(4, 480)
cur_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
start = time.time()
video_file_count = 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
print("Capture video saved location : {}".format(video_file))
# Create a video write before entering the loop
video_writer = cv2.VideoWriter(
video_file, video_codec, fps, (int(cap.get(3)), int(cap.get(4)))
)
while cap.isOpened():
start_time = time.time()
ret, frame = cap.read()
if ret == True:
cv2.imshow("frame", frame)
if time.time() - start > 10:
start = time.time()
video_file_count += 1
video_file = os.path.join(name, str(video_file_count) + ".avi")
video_writer = cv2.VideoWriter(
video_file, video_codec, fps, (int(cap.get(3)), int(cap.get(4)))
)
# No sleeping! We don't want to sleep, we want to write
# time.sleep(10)
# Write the frame to the current video writer
video_writer.write(frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
break
cap.release()
cv2.destroyAllWindows()
A sign that the videos are being received at 6 kb, an error with the codec. You need to download opencv_ffmpeg.dll and place it in the Python3.2.1 folder and renamed to opencv_ffmpeg321.dll
This solved the problem for me, and before that, 5.6 kb videos were created, regardless of what I do. But the problem is deeper than it seems, it can still be connected with a mismatch in the resolution of the stream and the recording.
For OpenCV version X.Y.Z
opencv_ffmpeg.dll ==> opencv_ffmpegXYZ.dll
For 64-bit version of OpenCV X.Y.Z
opencv_ffmpeg.dll ==> opencv_ffmpegXYZ_64.dll

close current and open a new openCV window if file modified Python

I was wondering if anyone could help me out a bit with this problem I cannot solve. I am using Pafy to search Youtube from a text file that has a song name written in it and that gets a new song every few minutes.
I am using Watchdog to watch for file modification and when i first run the script, watchdog catches the file modification and runs the pafy and opencv script, but it won't do the same when the following modification occurs.
#watchdog file change monitoring
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
print ("Received modified event - %s." % event.src_path)
cv2.destroyAllWindows()
if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='//PLAYING', recursive=False)
observer.start()
try:
while True:
#read PLAYING.txt
PLAYING = open('//PLAYING.txt').readline()
PLAYING = PLAYING[7:]
print (PLAYING)
#search youtube based on NowOnAir.txt
query_string = urllib.parse.urlencode({"search_query" : PLAYING})
html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
link = ('http://www.youtube.com/watch?v=' + search_results[0])
videoPafy = pafy.new(link)
best = videoPafy.getbestvideo()
videompv = best.url
#opencv youtube video output
video = cv2.VideoCapture(videompv)
while(video.isOpened()):
ret, frame = video.read()
resize = cv2.resize(frame, (1680, 1050))
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
result = cv2.addWeighted(image, 0.2, resize, 0.8, 0)
cv2.namedWindow('frame', 0)
cv2.resizeWindow('frame', 1680, 1050)
cv2.imshow('frame', result)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
So, I what I want to happen is, when file gets modified, I want openCV to close the window and open a new one with the new youtube query result.
Any suggestions would be quite welcome, thank You in advance.
If the file is just updated once per track change, then you could check the timestamp of the file for modification and use that to trigger your search.
import os.path
import time
last_modified = time.ctime(os.path.getmtime(file))
while True:
time.sleep(1)
if last_modified != time.ctime(os.path.getmtime(file)):
# search for the track on youtube
last_modified = time.ctime(os.path.getmtime(file))

How to solve OverflowError: Python int too large to convert to C long with opencv?

__author__ = 'Kyle'
HELP_MESSAGE = """Script: frame_grabber.py
Usage: python frame_grabber.py path/to/video
Requires: OpenCV 2.4.8+
Purpose: Select and save frames from a given video.
Commands:
Key Function
a previous frame
d next frame
q exit
SHIFT + a skip 10 frames forward
SHIFT + d skip 10 frames backwards
s saves current frame
dbl click saves current frame
Controls:
Slider Navigate through the video
"""
# Check if the user has provided a path to a file
# otherwise display the HELP_MESSAGE
import sys
import time as t
# Check if OpenCV module is present
# otherwise stop the application
try:
import cv2
except ImportError as e:
print "Fatal Error: Could not import OpenCV, ", e
exit(-1)
else:
print "Using OpenCV ", cv2.__version__
# these flags may depend on your opencv version:
# in opencv 3.0.0 these flags are implemented as
# cv2.CAP_PROP_POS_FRAMES and
# cv2.CAP_PROP_FRAME_COUNT
CURRENT_FRAME_FLAG = cv2.cv.CV_CAP_PROP_POS_FRAMES
TOTAL_FRAMES_FLAG = cv2.cv.CV_CAP_PROP_FRAME_COUNT
WIN_NAME = "Frame Grabber"
POS_TRACKBAR = "pos_trackbar"
#VIDEO_PATH = 'camera13.h264'
#try:
# VIDEO_PATH = sys.argv[1]
# except IndexError as e:
# print HELP_MESSAGE
# exit(-1)
cap = cv2.VideoCapture("camera13.h264")
if not cap.isOpened():
print "Fatal Error: Could not open the specified file."
exit(-1)
ret, frame = cap.read()
if not ret:
print "Fatal Error: Could not read/decode frames from specified file."
exit(-1)
def dummy():
pass
def save_image():
filename = "image_%0.5f.png" % t.time()
cv2.imwrite(filename, frame)
def seek_callback(x):
global frame
i = cv2.getTrackbarPos(POS_TRACKBAR, WIN_NAME)
cap.set(CURRENT_FRAME_FLAG, i-1)
_, frame = cap.read()
cv2.imshow(WIN_NAME, frame)
def mouse_callback(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDBLCLK:
save_image()
def skip_frame_generator(df):
def skip_frame():
global frame
cf = cap.get(CURRENT_FRAME_FLAG) - 1
cap.set(CURRENT_FRAME_FLAG, cf+df)
cv2.setTrackbarPos(POS_TRACKBAR, WIN_NAME, int(cap.get(CURRENT_FRAME_FLAG)))
_, frame = cap.read()
return skip_frame
cv2.namedWindow(WIN_NAME)
cv2.createTrackbar(POS_TRACKBAR, WIN_NAME, 0, int(cap.get(TOTAL_FRAMES_FLAG)), seek_callback)
cv2.setMouseCallback(WIN_NAME, mouse_callback)
actions = dict()
actions[ord("D")] = skip_frame_generator(10)
actions[ord("d")] = skip_frame_generator(1)
actions[ord("a")] = skip_frame_generator(-1)
actions[ord("A")] = skip_frame_generator(-10)
actions[ord("q")] = lambda: exit(0)
actions[ord("s")] = save_image
while True:
cv2.imshow(WIN_NAME, frame)
key = cv2.waitKey(0) & 0xFF
actions.get(key, dummy)()``
When the code is executed, I receive the error - OverflowError: Python int too large to convert to C long. How may I go about solving this please? This code is meant to create a frame grabber that allows me to pick a frame that I want and save it.
Well, the error is telling you that you are passing a number in this line:
cv2.createTrackbar(POS_TRACKBAR, WIN_NAME, 0,int(cap.get(TOTAL_FRAMES_FLAG)), seek_callback)
That is too large to be cast to ctypes.c_long; The maximum number that can be represented by this type is (2**31)-1 = 2147483647.
This is presumably your TOTAL_FRAMES_FLAG. Now that's a lot of frames (approx. 500 days #50fps), so it can't be right.
I notice that you are getting this value before you open the video file, so it's likely to be undefined at that point. Try doing it after you've opened your file, and see if that fixes things. You could print the value, as well, to see if it is indeed too large (before you try the suggested change).

Categories