113 lines
3.9 KiB
Python
113 lines
3.9 KiB
Python
|
#!/usr/bin/env python3
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
"""
|
|||
|
测试OpenCV VideoCapture的行为
|
|||
|
验证当设备索引不存在时VideoCapture的表现
|
|||
|
"""
|
|||
|
|
|||
|
import cv2
|
|||
|
import time
|
|||
|
|
|||
|
def test_video_capture_behavior():
|
|||
|
"""
|
|||
|
测试不同设备索引的VideoCapture行为
|
|||
|
"""
|
|||
|
print("=== OpenCV VideoCapture 行为测试 ===")
|
|||
|
print(f"OpenCV版本: {cv2.__version__}")
|
|||
|
print()
|
|||
|
|
|||
|
# 测试不同的设备索引
|
|||
|
test_indices = [0, 1, 2, 3, -1]
|
|||
|
backends = [cv2.CAP_DSHOW, cv2.CAP_MSMF, cv2.CAP_ANY]
|
|||
|
backend_names = ['CAP_DSHOW', 'CAP_MSMF', 'CAP_ANY']
|
|||
|
|
|||
|
for device_index in test_indices:
|
|||
|
print(f"\n--- 测试设备索引 {device_index} ---")
|
|||
|
|
|||
|
for backend, backend_name in zip(backends, backend_names):
|
|||
|
print(f"\n后端: {backend_name}")
|
|||
|
|
|||
|
try:
|
|||
|
start_time = time.time()
|
|||
|
cap = cv2.VideoCapture(device_index, backend)
|
|||
|
open_time = (time.time() - start_time) * 1000
|
|||
|
|
|||
|
print(f" VideoCapture创建: 成功 (耗时: {open_time:.1f}ms)")
|
|||
|
print(f" isOpened(): {cap.isOpened()}")
|
|||
|
|
|||
|
if cap.isOpened():
|
|||
|
# 尝试读取帧
|
|||
|
start_time = time.time()
|
|||
|
ret, frame = cap.read()
|
|||
|
read_time = (time.time() - start_time) * 1000
|
|||
|
|
|||
|
print(f" read()返回值: ret={ret}")
|
|||
|
if ret and frame is not None:
|
|||
|
print(f" 帧形状: {frame.shape}")
|
|||
|
print(f" 读取耗时: {read_time:.1f}ms")
|
|||
|
else:
|
|||
|
print(f" 读取失败 (耗时: {read_time:.1f}ms)")
|
|||
|
|
|||
|
# 获取一些属性
|
|||
|
try:
|
|||
|
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
|
|||
|
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
|
|||
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|||
|
print(f" 分辨率: {int(width)}x{int(height)}")
|
|||
|
print(f" 帧率: {fps}")
|
|||
|
except Exception as e:
|
|||
|
print(f" 获取属性失败: {e}")
|
|||
|
else:
|
|||
|
print(" 相机未打开")
|
|||
|
|
|||
|
cap.release()
|
|||
|
|
|||
|
except Exception as e:
|
|||
|
print(f" 异常: {e}")
|
|||
|
|
|||
|
print("\n=== 测试完成 ===")
|
|||
|
|
|||
|
def test_specific_case():
|
|||
|
"""
|
|||
|
专门测试device_index=1的情况
|
|||
|
"""
|
|||
|
print("\n=== 专门测试 device_index=1 ===")
|
|||
|
|
|||
|
try:
|
|||
|
# 使用DSHOW后端(Windows默认)
|
|||
|
cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
|
|||
|
print(f"VideoCapture(1, CAP_DSHOW) 创建成功")
|
|||
|
print(f"isOpened(): {cap.isOpened()}")
|
|||
|
|
|||
|
if cap.isOpened():
|
|||
|
print("相机显示为已打开,但这可能是虚假的")
|
|||
|
|
|||
|
# 尝试多次读取
|
|||
|
for i in range(3):
|
|||
|
print(f"\n第{i+1}次读取:")
|
|||
|
start_time = time.time()
|
|||
|
ret, frame = cap.read()
|
|||
|
read_time = (time.time() - start_time) * 1000
|
|||
|
|
|||
|
print(f" ret: {ret}")
|
|||
|
print(f" frame is None: {frame is None}")
|
|||
|
print(f" 耗时: {read_time:.1f}ms")
|
|||
|
|
|||
|
if ret and frame is not None:
|
|||
|
print(f" 帧形状: {frame.shape}")
|
|||
|
print(f" 帧数据类型: {frame.dtype}")
|
|||
|
print(f" 帧数据范围: {frame.min()} - {frame.max()}")
|
|||
|
else:
|
|||
|
print(" 读取失败或帧为空")
|
|||
|
break
|
|||
|
else:
|
|||
|
print("相机未打开")
|
|||
|
|
|||
|
cap.release()
|
|||
|
|
|||
|
except Exception as e:
|
|||
|
print(f"异常: {e}")
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
test_video_capture_behavior()
|
|||
|
test_specific_case()
|