主要改进点:
使用 ThreadPoolExecutor 管理多线程:
使用 concurrent.futures.ThreadPoolExecutor 来管理多线程,这样可以更高效地处理图像。
在 main 函数中创建一个 ThreadPoolExecutor,并在每个循环中提交图像处理任务。
减少不必要的图像转换:
尽量减少图像格式之间的转换,以减少计算开销。
使用更高效的算法:
选择了更高效的滤波器和对焦方法,例如 cv2.fastNlMeansDenoisingColored 和 cv2.Laplacian。
import cv2
import os
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import datetime
import webbrowser
import logging
import concurrent.futures
import queue
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 检查并创建保存照片和视频的文件夹
def create_folder(folder_name):
if not os.path.exists(folder_name):
os.makedirs(folder_name)
return folder_name
# 获取文件夹中的最大编号
def get_next_file_number(folder_name, file_extension):
files = os.listdir(folder_name)
files = [f for f in files if f.endswith(file_extension)]
if files:
numbers = [int(f.split('.')[0]) for f in files]
return max(numbers) + 1
else:
return 1
# 将PIL图像转换为OpenCV图像
def pil_to_cv(image):
return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
# 自动曝光调整
def auto_exposure(frame, exposure_value):
frame = cv2.convertScaleAbs(frame, alpha=exposure_value, beta=0)
return frame
# 自动对焦
def auto_focus(frame):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
laplacian = cv2.Laplacian(gray, cv2.CV_64F).var()
if laplacian < 100: # 如果图像模糊,进行对焦
frame = cv2.fastNlMeansDenoisingColored(frame, None, 10, 10, 7, 21)
return frame
# 鼠标回调函数
def mouse_callback(event, x, y, flags, param):
global next_photo_number, next_video_number, running, recording, out, frame, scale_factor, cam_index, roi, button_hints, show_buttons, show_help, frame_width, frame_height
button_width = int(frame_width * 0.05) # 按钮区域宽度占界面宽度的1/20
button_height = 40 # 每个按钮的高度
if event == cv2.EVENT_LBUTTONDOWN:
if 10 <= x <= button_width and 10 <= y <= 50: # 关闭按钮区域
running = False
elif 10 <= x <= button_width and 70 <= y <= 70 + button_height: # 拍照按钮区域
threading.Thread(target=save_photo, args=(frame.copy(), next_photo_number)).start()
next_photo_number += 1
elif 10 <= x <= button_width and 120 <= y <= 120 + button_height: # 开始/停止录像按钮区域
if not recording:
start_recording()
else:
stop_recording()
elif 10 <= x <= button_width and 170 <= y <= 170 + button_height: # 放大按钮区域
scale_factor = min(3.0, scale_factor * 2)
elif 10 <= x <= button_width and 220 <= y <= 220 + button_height: # 缩小按钮区域
scale_factor = max(1.0, scale_factor / 2)
elif 10 <= x <= button_width and 270 <= y <= 270 + button_height: # 切换摄像头按钮区域
switch_camera()
elif 10 <= x <= button_width and 320 <= y <= 320 + button_height: # 查看照片按钮区域
open_photo_folder()
elif 10 <= x <= button_width and 370 <= y <= 370 + button_height: # 查看视频按钮区域
open_video_folder()
elif 10 <= x <= button_width and 420 <= y <= 420 + button_height: # 去除噪点按钮区域
apply_denoise()
elif 10 <= x <= button_width and 470 <= y <= 470 + button_height: # 功能菜单按钮区域
show_buttons = not show_buttons
elif 10 <= x <= button_width and 520 <= y <= 520 + button_height: # 功能说明按钮区域
show_help = not show_help
elif event == cv2.EVENT_RBUTTONDOWN:
roi[0], roi[1]