143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
深入分析相机设备的行为
|
||
"""
|
||
|
||
import cv2
|
||
import numpy as np
|
||
import time
|
||
|
||
def analyze_camera_frame(frame, device_index):
|
||
"""
|
||
分析相机帧的特征
|
||
"""
|
||
print(f"\n=== 设备 {device_index} 帧分析 ===")
|
||
print(f"帧形状: {frame.shape}")
|
||
print(f"数据类型: {frame.dtype}")
|
||
print(f"数据范围: {frame.min()} - {frame.max()}")
|
||
|
||
# 检查是否是纯色帧(可能是虚拟设备)
|
||
unique_colors = len(np.unique(frame.reshape(-1, frame.shape[-1]), axis=0))
|
||
print(f"唯一颜色数量: {unique_colors}")
|
||
|
||
# 检查帧的统计信息
|
||
mean_values = np.mean(frame, axis=(0, 1))
|
||
std_values = np.std(frame, axis=(0, 1))
|
||
print(f"各通道均值: {mean_values}")
|
||
print(f"各通道标准差: {std_values}")
|
||
|
||
# 检查是否是静态帧
|
||
if np.all(std_values < 1.0):
|
||
print("⚠️ 这可能是一个静态/虚拟帧(标准差很小)")
|
||
|
||
# 检查是否是纯黑帧
|
||
if np.all(mean_values < 10):
|
||
print("⚠️ 这可能是一个黑色帧")
|
||
|
||
# 检查帧的变化
|
||
return frame
|
||
|
||
def test_camera_devices():
|
||
"""
|
||
测试多个相机设备并比较帧内容
|
||
"""
|
||
print("=== 相机设备详细分析 ===")
|
||
|
||
devices_to_test = [0, 1]
|
||
frames = {}
|
||
|
||
for device_index in devices_to_test:
|
||
print(f"\n--- 测试设备 {device_index} ---")
|
||
|
||
try:
|
||
cap = cv2.VideoCapture(device_index, cv2.CAP_DSHOW)
|
||
|
||
if cap.isOpened():
|
||
print(f"设备 {device_index}: 成功打开")
|
||
|
||
# 获取设备属性
|
||
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||
fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
|
||
|
||
print(f"分辨率: {width}x{height}")
|
||
print(f"帧率: {fps}")
|
||
print(f"编码: {fourcc}")
|
||
|
||
# 读取多帧进行分析
|
||
frames_list = []
|
||
for i in range(5):
|
||
ret, frame = cap.read()
|
||
if ret and frame is not None:
|
||
frames_list.append(frame.copy())
|
||
if i == 0: # 只分析第一帧
|
||
frames[device_index] = analyze_camera_frame(frame, device_index)
|
||
else:
|
||
print(f"第{i+1}帧读取失败")
|
||
break
|
||
|
||
# 检查帧间变化
|
||
if len(frames_list) > 1:
|
||
diff = cv2.absdiff(frames_list[0], frames_list[-1])
|
||
total_diff = np.sum(diff)
|
||
print(f"首末帧差异总和: {total_diff}")
|
||
|
||
if total_diff < 1000: # 阈值可调整
|
||
print("⚠️ 帧内容几乎没有变化,可能是虚拟设备")
|
||
else:
|
||
print("✓ 帧内容有变化,可能是真实相机")
|
||
|
||
else:
|
||
print(f"设备 {device_index}: 无法打开")
|
||
|
||
cap.release()
|
||
|
||
except Exception as e:
|
||
print(f"设备 {device_index} 测试异常: {e}")
|
||
|
||
# 比较不同设备的帧
|
||
if 0 in frames and 1 in frames:
|
||
print("\n=== 设备间帧比较 ===")
|
||
diff = cv2.absdiff(frames[0], frames[1])
|
||
total_diff = np.sum(diff)
|
||
print(f"设备0和设备1帧差异总和: {total_diff}")
|
||
|
||
if total_diff < 1000:
|
||
print("⚠️ 两个设备的帧几乎相同,设备1可能是设备0的镜像或虚拟设备")
|
||
else:
|
||
print("✓ 两个设备的帧不同,可能是独立的相机")
|
||
|
||
def check_system_cameras():
|
||
"""
|
||
检查系统中可用的相机设备
|
||
"""
|
||
print("\n=== 系统相机设备检查 ===")
|
||
|
||
available_cameras = []
|
||
|
||
# 测试前10个设备索引
|
||
for i in range(10):
|
||
cap = cv2.VideoCapture(i, cv2.CAP_DSHOW)
|
||
if cap.isOpened():
|
||
ret, _ = cap.read()
|
||
if ret:
|
||
available_cameras.append(i)
|
||
print(f"设备 {i}: 可用")
|
||
else:
|
||
print(f"设备 {i}: 打开但无法读取")
|
||
else:
|
||
print(f"设备 {i}: 不可用")
|
||
cap.release()
|
||
|
||
# 避免测试太多设备
|
||
if len(available_cameras) >= 3:
|
||
break
|
||
|
||
print(f"\n发现 {len(available_cameras)} 个可用相机设备: {available_cameras}")
|
||
return available_cameras
|
||
|
||
if __name__ == "__main__":
|
||
check_system_cameras()
|
||
test_camera_devices() |