Files
huojv/utils/get_image.py
2025-10-29 16:28:06 +08:00

180 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
from PIL import Image
import cv2
# class GetImage:
# def __init__(self, cam_index=0, width=1920, height=1080):
# self.cap = cv2.VideoCapture(cam_index,cv2.CAP_DSHOW)
#
# if not self.cap.isOpened():
# raise RuntimeError(f"无法打开摄像头 {cam_index}")
# self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
# self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# print(f"✅ 摄像头 {cam_index} 打开成功,分辨率 {width}x{height}")
# def get_frame(self):
# ret, im_opencv = self.cap.read()
# im_opencv = cv2.cvtColor(im_opencv, cv2.COLOR_BGR2RGB) # rgb 修改通道数并转换图像
# im_opencv = im_opencv[30:30+720, 0:1280]#裁剪尺寸
# im_PIL = Image.fromarray(im_opencv) # 图像改成对象类型
#
# return [im_opencv, im_PIL]
# def release(self):
# self.cap.release()
# cv2.destroyAllWindows()
# print("🔚 摄像头已释放")
# def __del__(self):
# # 以防忘记手动释放
# if hasattr(self, "cap") and self.cap.isOpened():
# self.release()
#
# get_image = GetImage()
#
# if __name__ == '__main__':
# while True:
# if cv2.waitKey(1) & 0xFF == ord('q'):
# break
# a=get_image.get_frame()
# cv2.imshow('image',a[0])
# print(a[0].shape)
#
#
# cv2.destroyAllWindows()
import threading
import warnings
# 抑制OpenCV的警告信息兼容不同版本
import os
import sys
import io
os.environ['OPENCV_LOG_LEVEL'] = 'SILENT'
os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '0'
try:
if hasattr(cv2, 'setLogLevel'):
if hasattr(cv2, 'LOG_LEVEL_SILENT'):
cv2.setLogLevel(cv2.LOG_LEVEL_SILENT)
elif hasattr(cv2, 'LOG_LEVEL_ERROR'):
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
elif hasattr(cv2, 'utils'):
cv2.utils.setLogLevel(0)
except Exception:
pass
class GetImage:
def __init__(self, cam_index=0, width=1920, height=1080):
print(f"🔧 正在初始化采集卡 {cam_index}...")
self.cap = None
self.frame = None
self.running = True
self.cam_index = cam_index
# 尝试多种方式打开采集卡
backends_to_try = [
(cam_index, cv2.CAP_DSHOW),
(cam_index, cv2.CAP_ANY),
(cam_index, None), # 默认后端
]
# 重定向stderr来抑制OpenCV的错误输出
old_stderr = sys.stderr
suppressed_output = io.StringIO()
try:
sys.stderr = suppressed_output
for idx, backend in backends_to_try:
try:
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=UserWarning)
if backend is not None:
self.cap = cv2.VideoCapture(idx, backend)
else:
self.cap = cv2.VideoCapture(idx)
if self.cap.isOpened():
# 测试读取一帧
ret, test_frame = self.cap.read()
if ret and test_frame is not None:
print(f"✅ 采集卡 {cam_index} 打开成功")
break
else:
self.cap.release()
self.cap = None
except Exception as e:
if self.cap:
try:
self.cap.release()
except:
pass
self.cap = None
continue
finally:
# 恢复stderr
sys.stderr = old_stderr
if self.cap is None or not self.cap.isOpened():
print(f"❌ 无法打开采集卡 {cam_index}")
print("请检查:")
print(" 1. 采集卡是否正确连接")
print(" 2. 采集卡索引是否正确(尝试扫描采集卡)")
print(" 3. 采集卡驱动是否安装")
print(" 4. 采集卡是否被其他程序占用")
self.cap = None
return
# 设置分辨率
try:
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# 实际获取设置后的分辨率
actual_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
actual_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f" 分辨率设置: {width}x{height} -> 实际: {actual_width}x{actual_height}")
except Exception as e:
print(f"⚠️ 设置分辨率失败: {e}")
# 启动更新线程
threading.Thread(target=self.update, daemon=True).start()
# 等待几帧确保采集卡正常工作
import time
time.sleep(1.0)
print(f"✅ 采集卡 {cam_index} 初始化完成")
def update(self):
while self.running and self.cap is not None:
try:
ret, frame = self.cap.read()
if ret and frame is not None:
self.frame = frame
else:
# 读取失败时不打印,避免刷屏
pass
except Exception as e:
# 只在异常时打印错误
print(f"⚠️ 采集卡 {self.cam_index} 读取异常: {e}")
import time
time.sleep(0.1) # 出错时短暂延迟
def get_frame(self):
if self.cap is None or self.frame is None:
return None
try:
im_opencv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
im_opencv = im_opencv[30:30+720, 0:1280]
im_PIL = Image.fromarray(im_opencv)
return [im_opencv, im_PIL]
except Exception as e:
print(f"⚠️ 图像处理错误: {e}")
return None
def release(self):
self.running = False
time.sleep(0.2)
if self.cap is not None:
self.cap.release()
cv2.destroyAllWindows()
# get_image 将在main.py中初始化
get_image = None