Simple USB Cam viewer in Windows 11, using Python + OpenCV

My scenario is I have two USB Cam deviecs:
- A Video Capture Adapter, used to convert HDMI output from Raspberry Pi, convert to USB, my PC will recognize it as a USB web cam.
- A normal USB web cam.

I use them to record Raspberry Pi operation and unit under developed, as show in the video: https://www.youtube.com/watch?v=JVnYG2-OC8w

But in Windows, only one Camera can be opened at the same time. So I make a simple Python code to display the web cam view on screen, no any capture/record control. Such that I can record screen with both my Raspberry Pi operation and the web cam view.


In the Python code, OpenCV (cv2) is used to handle the cam, so have to install it.

In my practice:
- Create a Python virtual environment in Windows 11, named envUSBCAM.
  
  Enter the command in Terminal:
  > python -m venv envUSBCAM

  
Activate the virtual environment:
  > .\\Scripts\activate

- Install OpenCV in the virtual environment:
  > pip install opencv-python

- Program the code in Thonny (have to configure the interpreter of the virtual environment).


pyUSBCAM.py
(Actually, it was provided by MicroSoft Copilot.)

import sys
import cv2

def main():
    # Default values
    default_i = 0
    default_x = 1280
    default_y = 720

    # Check command-line arguments
    if len(sys.argv) == 1:
        camera_index = default_i
        x_resolution = default_x
        y_resolution = default_y
    elif len(sys.argv) == 2:
        camera_index = int(sys.argv[1])
        x_resolution = default_x
        y_resolution = default_y
    elif len(sys.argv) == 4:
        camera_index = int(sys.argv[1])
        x_resolution = int(sys.argv[2])
        y_resolution = int(sys.argv[3])
    else:
        print("Usage: python pyUSBCAM.py [camera_index [x_resolution y_resolution]]")
        return

    cap = cv2.VideoCapture(camera_index)
    if not cap.isOpened():
        print(f"Unable to open camera {camera_index}")
        return

    cap.set(cv2.CAP_PROP_FRAME_WIDTH, x_resolution)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, y_resolution)

    while True:
        ret, frame = cap.read()
        if not ret:
            print("Unable to receive frame (stream end?)")
            break

        cv2.imshow('Camera ' + str(camera_index) + ' ' + str(x_resolution) +' x ' + str(y_resolution),
                   frame)
        if cv2.waitKey(1) == ord('q'):  # Press 'q' to exit
            break

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()




Usage in Terminal:
python pyUSBCAM.py [camera_index [x_resolution y_resolution]]
Press 'q' to exit.


Updated@25-02-14

It's found that even cv2.CAP_PROP_FRAME_WIDTH and cv2.CAP_PROP_FRAME_HEIGHT set, but the actual width and height may be changed. So I update the code to reflect the actual resolution in window title.

pyUSBCAM_25-02-14.py
"""
pyUSBCAM.py
Simple USB Cam viewer in Windows 11, using Python + OpenCV
https://coxxect.blogspot.com/2025/02/simple-usb-cam-viewer-in-windows-11.html

update:
25-02-14: set window title base on sys.argv (before ' | ')
          and actual width and height (after ' | ').
"""
import sys
import cv2

def main():
    # Default values
    default_i = 0
    default_x = 1280
    default_y = 720

    # Check command-line arguments
    if len(sys.argv) == 1:
        camera_index = default_i
        x_resolution = default_x
        y_resolution = default_y
    elif len(sys.argv) == 2:
        camera_index = int(sys.argv[1])
        x_resolution = default_x
        y_resolution = default_y
    elif len(sys.argv) == 4:
        camera_index = int(sys.argv[1])
        x_resolution = int(sys.argv[2])
        y_resolution = int(sys.argv[3])
    else:
        print("Usage: python pyUSBCAM.py [camera_index [x_resolution y_resolution]]")
        return

    cap = cv2.VideoCapture(camera_index)
    if not cap.isOpened():
        print(f"Unable to open camera {camera_index}")
        return

    cap.set(cv2.CAP_PROP_FRAME_WIDTH, x_resolution)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, y_resolution)
    
    actual_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    actual_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    
    window_title = ""
    for a in sys.argv:
        window_title = window_title + a + " "
    window_title = window_title + " | " + str(actual_width) + " x " + str(actual_height)
    
    while True:
        ret, frame = cap.read()
        if not ret:
            print("Unable to receive frame (stream end?)")
            break

        cv2.imshow(window_title,
                   frame)
        if cv2.waitKey(1) == ord('q'):  # Press 'q' to exit
            break

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()




Comments

Popular posts from this blog

480x320 TFT/ILI9488 SPI wih EP32C3 (arduino-esp32) using Arduino_GFX Library

Drive 320x240 ILI9341 SPI TFT using ESP32-S3 (NodeMCU ESP-S3-12K-Kit) using TFT_eSPI library, in Arduino Framework.