Video capture using opencv-python on Pop!_OS 22.04

Introduction

In a previous post I documented my installation of opencv-python using pip and a virtual environment on Pop!_OS 22.04 . Pop!_OS is based on Ubuntu and the code discussed here should work on any Ubuntu-related OS. In this post I'll assume that opencv-python is installed as described above and test out a simple script to grab video frames from a (laptop) video camera.

The script

Let's start with the full script, given below. This is almost exactly the same as the documentation at opencv.org . I have changed some of the variable names, added some comments, and fixed some of the indentation.

#! /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.

"""
Testing video capture 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

# pass argument 0 for device index (hopefully laptop cam)
vcap = cv2.VideoCapture(0);
if not vcap.isOpened():
print("Can't open camera!")
exit()

# 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)

# listen for 'q' press to exit
if cv2.waitKey(1) == ord('q'):
break

# everything done
# - release capture
# - destroy all windows
vcap.release()
cv2.destroyAllWindows()

setup

The sections of the script are pretty simple to understand. Let's start with importing the modules and selecting the video camera:

  • numpy and opencv-python are imported,
  • the camera is opened using cv2.VideoCapture(0),
  • the number 0 selects the first camera (0-indexed), and
  • the if-statements tests for a working camera and exits is none is found.

import numpy as np
import cv2

# pass argument 0 for device index (hopefully laptop cam)
vcap = cv2.VideoCapture(0);
if not vcap.isOpened():
print("Can't open camera!")
exit()

main loop

The main processing in the script happend in the while True loop:

  • First, a frame of video is read using vcap.read(). If this is successful, ret will be set to true and the script will continue. If not, the script breaks and exits.
  • Second, the frame of video is converted to grayscale using cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY).
  • Third, the grayscale frame is shown in a pop-up window using cv2.imshow('frame', gray_frame).
  • Finally, the script listens for the "q" key to be pressed. If the key is pressed, the loop breaks and script exits.

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)

# listen for 'q' press to exit
if cv2.waitKey(1) == ord('q'):
break

cleaning up and exit

The last lines of the script close (release) the camera and close all open windows. In this case, the window showing the video feed is closed.

vcap.release()
cv2.destroyAllWindows()

running the script

The complete script is provided at the top of the post and can be placed in a single file, let's call it script01.py. This script has a shebang at the top ( #! /usr/bin/env python3 ) that tells bash how to run it. To do this, make sure the file is executable:

$ chmod u+x script01.py

Before running the script, make sure the virtual environment is active using ( see this post if you don't have this setup):

$ workon opencv
(opencv) $

With the virtual environment active, opencv-python and numpy are available. Finally, the script can be run using

(opencv) $ ./script01.py

assuming the script is in the local directory. That's it-- everything worked for me on Pop!_OS 22.04 on this date (Apr 23, 2024).