#!/usr/bin/env python3 """ Quick utility to measure the actual frame rate obtainable from a USB/IP camera. Usage: python test_camera_fps.py --input 0 --frames 300 --width 640 --height 480 --fps 30 It attempts to set the desired resolution/FPS, reads the specified number of frames, and prints the achieved FPS along with any read failures. """ import argparse import time import cv2 def parse_args(): parser = argparse.ArgumentParser(description="Measure camera FPS with OpenCV") parser.add_argument("--input", type=str, default="0", help="Camera index or URL") parser.add_argument("--frames", type=int, default=200, help="How many frames to capture") parser.add_argument("--width", type=int, default=640, help="Requested frame width") parser.add_argument("--height", type=int, default=480, help="Requested frame height") parser.add_argument("--fps", type=float, default=30.0, help="Requested FPS (hint to driver)") parser.add_argument("--backend", type=str, default="", help="Optional OpenCV backend name (e.g., 'dshow')") return parser.parse_args() def open_capture(source, backend): if backend: backend_map = { "dshow": cv2.CAP_DSHOW, "msmf": cv2.CAP_MSMF, "ffmpeg": cv2.CAP_FFMPEG, } backend_flag = backend_map.get(backend.lower()) if backend_flag is None: raise ValueError(f"Unsupported backend '{backend}'. Choose from {list(backend_map)}") return cv2.VideoCapture(source, backend_flag) return cv2.VideoCapture(source) def main(): opt = parse_args() source = int(opt.input) if opt.input.isdigit() else opt.input cap = open_capture(source, opt.backend) if not cap.isOpened(): raise RuntimeError(f"Failed to open camera source: {opt.input}") # Try to set desired properties (may be ignored by some drivers) cap.set(cv2.CAP_PROP_FRAME_WIDTH, opt.width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, opt.height) cap.set(cv2.CAP_PROP_FPS, opt.fps) actual_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) actual_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) actual_fps = cap.get(cv2.CAP_PROP_FPS) print(f"Requested: {opt.width}x{opt.height} @{opt.fps:.1f} FPS") print(f"Driver reports: {actual_width:.0f}x{actual_height:.0f} @{actual_fps:.1f} FPS") total = 0 failures = 0 start = time.time() while total < opt.frames: ok, _ = cap.read() if not ok: failures += 1 continue total += 1 elapsed = time.time() - start cap.release() achieved_fps = total / elapsed if elapsed > 0 else 0.0 print(f"Captured {total} frames in {elapsed:.2f} s => {achieved_fps:.2f} FPS") if failures: print(f"Read failures: {failures}") if __name__ == "__main__": main()