Opencv-python script with argparse
May 2, 2024
Introduction
In previous posts:
I documented my installation of opencv-python , showed how to get video capture going, and covered saving video streams to mp4. In this post, I'll focus on addding command line arguments to the previous script using argparse. As before, this post focuses on using these scripts on Pop!_OS (Ubuntu) 22.04 (not MAC/Windows).
The script
Let's start with the full script, given below (also available at this
github repo
). This is almost exactly the
same as the
the script in the previous post
because all of the same things need to be done. The changes here focus on
using argparse
to add command line options
and help.
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2024 Christopher C. Strelioff <chris.strelioff@gmail.com>
#
# Distributed under terms of the MIT license.
"""
script03.py
Adding command line argprase to script that does video capture and writing
video files on Pop_OS! (Ubuntu) 22.04 operating system.
Following documentation at:
https://docs.opencv.org/4.x/dd/d43/tutorial_py_video_display.html
"""
import numpy as np
import cv2
#
# command line argument processing
#
import argparse
parser = argparse.ArgumentParser(prog='./script03.py')
# save a video file?
parser.add_argument('-s', '--save', help='save a video file', dest='save', action='store_true')
# assign a file name, default is video.mp4
parser.add_argument('-f', '--file', help='filename for video, should be mp4', dest='file', default='video.mp4')
# parse arguments & provide message at terminal
args = parser.parse_args()
if (args.save == True):
print(f'...saving video to {args.file}.')
else:
print('...not saving video to file.')
print('Hit "q" to quit.')
# pass argument 0 for device index (1st camera)
vcap = cv2.VideoCapture(0);
if not vcap.isOpened():
print("Can't open camera!")
exit()
# get height and width of capture
width = int(vcap.get(3))
height = int(vcap.get(4))
# bool for isColor is optional, BUT defaults to True!
# - doing grayscale in the loop, so have to set to false!
isColor = False
# create VideoWrite if -s or --save flags passed
if (args.save):
# create VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# using file name in args.file
output = cv2.VideoWriter(args.file, fourcc, 20.0, (width, height), isColor)
# loop until
# - error reading frame from camera
# - or, user hits 'q'
while True:
# read a frame
ret, frame = vcap.read();
# ret == True if frame read correctly
if not ret:
print("Can't read frame, exiting...")
break
# process frame
# - change BGR -> GRAY (video should be grayscale)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# display resulting fram
cv2.imshow('frame', gray_frame)
if (args.save):
# write to the output is -s or --save flag passed
output.write(gray_frame)
# listen for 'q' press to exit
if cv2.waitKey(1) == ord('q'):
break
# everything done
# - release capture
# - release video writer
# - destroy all windows
vcap.release()
if (args.save):
# run is -s or --save flags passed
output.release()
cv2.destroyAllWindows()
setup
The first addition to the script from the previous post is importing
and setting up the options for argparse
:
-
Import
argparse
and set the name of the "program" using:import argparse
parser = argparse.ArgumentParser(prog='./script03.py') -
Add an argument to save the video stream as a file using
-s
or--save
(defaults toFalse
):# save a video file?
parser.add_argument('-s', '--save', help='save a video file', dest='save', action='store_true') -
Add an argument to set the file name
-f
or--file
(defaults tovideo.mp4
):# assign a file name, default is video.mp4
parser.add_argument('-f', '--file', help='filename for video, should be mp4', dest='file', default='video.mp4') -
Parse the passed arguments using:
args = parser.parse_args()
-
Finally, for this first part, check the "save" argument and print info to
the terminal for the user:
if (args.save == True):
print(f'...saving video to {args.file}.')
else:
print('...not saving video to file.')
print('Hit "q" to quit.')
All together, this looks like:
#
# command line argument processing
#
import argparse
parser = argparse.ArgumentParser(prog='./script03.py')
# save a video file?
parser.add_argument('-s', '--save', help='save a video file', dest='save', action='store_true')
# assign a file name, default is video.mp4
parser.add_argument('-f', '--file', help='filename for video, should be mp4', dest='file', default='video.mp4')
# parse arguments & provide message at terminal
args = parser.parse_args()
if (args.save == True):
print(f'...saving video to {args.file}.')
else:
print('...not saving video to file.')
print('Hit "q" to quit.')
saving a file?
There are parts of the script that only needed to run if a video file is is being written to disk. This affects the script in a few places:
-
Before the
while True:
loop there is a section of the script that initializes aVideoWriter
. This only needs to happen if the-s
, or--save
flag was used:# create VideoWrite if -s or --save flags passed
if (args.save):
# create VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# using file name in args.file
output = cv2.VideoWriter(args.file, fourcc, 20.0, (width, height), isColor) -
Inside the
while True:
loop, output only needs to be written if requested:if (args.save):
# write to the output is -s or --save flag passed
output.write(gray_frame) -
Finally, after the
while True:
loop, cleanup needs to happen if a video file was written:if (args.save):
# run is -s or --save flags passed
output.release()
using the script
Because this script uses opencv-python
, the virtual environment
created in an early post needs to be active before we can run the script with
the new argparse abilties. For example, to show the help, try:
$ workon opencv
(opencv) $ ./script03.py --help
usage: ./script03.py [-h] [-s] [-f FILE]
options:
-h, --help show this help message and exit
-s, --save save a video file
-f FILE, --file FILE filename for video, should be mp4
(opencv) $
Finally, an example of running the script and choosing a file name would look like:
(opencv) $ ./script03.py -s -f my-video.mp4
...saving video to my-video.mp4.
Hit "q" to quit.
(opencv) $ l
my-video.mp4 script03.py
(opencv) $
That's it! Listing the directory contents, it is clear that
my-video.mp4
was created.