再次修复了车牌判断的bug
This commit is contained in:
111
main.py
111
main.py
@@ -42,6 +42,8 @@ class PlateStabilizer:
|
|||||||
self.plate_last_seen = {}
|
self.plate_last_seen = {}
|
||||||
# 车牌帧计数器,用于跟踪每个车牌被检测的帧数
|
# 车牌帧计数器,用于跟踪每个车牌被检测的帧数
|
||||||
self.plate_frame_count = {}
|
self.plate_frame_count = {}
|
||||||
|
# 车牌首次检测时间戳,用于基于时间的帧计数
|
||||||
|
self.plate_first_seen = {}
|
||||||
|
|
||||||
def calculate_plate_distance(self, pos1, pos2):
|
def calculate_plate_distance(self, pos1, pos2):
|
||||||
"""计算两个车牌位置的距离"""
|
"""计算两个车牌位置的距离"""
|
||||||
@@ -95,11 +97,22 @@ class PlateStabilizer:
|
|||||||
matched_plates[new_id] = detection
|
matched_plates[new_id] = detection
|
||||||
self.plate_positions[new_id] = bbox
|
self.plate_positions[new_id] = bbox
|
||||||
self.plate_last_seen[new_id] = current_time # 设置时间戳
|
self.plate_last_seen[new_id] = current_time # 设置时间戳
|
||||||
# 初始化帧计数
|
# 初始化帧计数和首次检测时间
|
||||||
self.plate_frame_count[new_id] = 1
|
self.plate_frame_count[new_id] = 1
|
||||||
|
self.plate_first_seen[new_id] = current_time
|
||||||
|
|
||||||
return matched_plates
|
return matched_plates
|
||||||
|
|
||||||
|
def is_plate_ready_for_processing(self, plate_id, delay_seconds=0.7):
|
||||||
|
"""检查车牌是否已经过了指定的延迟时间,可以进行处理"""
|
||||||
|
import time
|
||||||
|
if plate_id not in self.plate_first_seen:
|
||||||
|
return False
|
||||||
|
|
||||||
|
current_time = time.time()
|
||||||
|
first_seen_time = self.plate_first_seen[plate_id]
|
||||||
|
return (current_time - first_seen_time) >= delay_seconds
|
||||||
|
|
||||||
def calculate_confidence(self, plate_text, detection_quality=1.0):
|
def calculate_confidence(self, plate_text, detection_quality=1.0):
|
||||||
"""计算识别结果的置信度"""
|
"""计算识别结果的置信度"""
|
||||||
if not plate_text or plate_text == "识别失败":
|
if not plate_text or plate_text == "识别失败":
|
||||||
@@ -240,6 +253,8 @@ class PlateStabilizer:
|
|||||||
del self.plate_last_seen[plate_id]
|
del self.plate_last_seen[plate_id]
|
||||||
if plate_id in self.plate_frame_count:
|
if plate_id in self.plate_frame_count:
|
||||||
del self.plate_frame_count[plate_id]
|
del self.plate_frame_count[plate_id]
|
||||||
|
if plate_id in self.plate_first_seen:
|
||||||
|
del self.plate_first_seen[plate_id]
|
||||||
|
|
||||||
class CameraThread(QThread):
|
class CameraThread(QThread):
|
||||||
"""摄像头线程类"""
|
"""摄像头线程类"""
|
||||||
@@ -496,6 +511,11 @@ class MainWindow(QMainWindow):
|
|||||||
# 白名单存储
|
# 白名单存储
|
||||||
self.whitelist = set() # 存储白名单车牌号
|
self.whitelist = set() # 存储白名单车牌号
|
||||||
|
|
||||||
|
# 帧率检测相关
|
||||||
|
self.frame_times = deque(maxlen=30) # 存储最近30帧的时间戳
|
||||||
|
self.current_fps = 30.0 # 默认帧率
|
||||||
|
self.skip_frames_count = 21 # 默认跳过帧数 (0.7秒 * 30fps)
|
||||||
|
|
||||||
self.init_ui()
|
self.init_ui()
|
||||||
self.init_detector()
|
self.init_detector()
|
||||||
self.init_camera()
|
self.init_camera()
|
||||||
@@ -1056,6 +1076,9 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
self.current_frame = frame.copy()
|
self.current_frame = frame.copy()
|
||||||
|
|
||||||
|
# 更新帧率计算
|
||||||
|
self.update_fps()
|
||||||
|
|
||||||
# 先显示原始帧,保证视频流畅播放
|
# 先显示原始帧,保证视频流畅播放
|
||||||
self.display_frame(frame)
|
self.display_frame(frame)
|
||||||
|
|
||||||
@@ -1092,6 +1115,19 @@ class MainWindow(QMainWindow):
|
|||||||
# 无论成功或失败,都要重置标志位
|
# 无论成功或失败,都要重置标志位
|
||||||
self.is_processing = False
|
self.is_processing = False
|
||||||
|
|
||||||
|
def update_fps(self):
|
||||||
|
"""更新帧率计算"""
|
||||||
|
current_time = time.time()
|
||||||
|
self.frame_times.append(current_time)
|
||||||
|
|
||||||
|
# 如果有足够的帧时间数据,计算帧率
|
||||||
|
if len(self.frame_times) >= 2:
|
||||||
|
time_span = self.frame_times[-1] - self.frame_times[0]
|
||||||
|
if time_span > 0:
|
||||||
|
self.current_fps = (len(self.frame_times) - 1) / time_span
|
||||||
|
# 根据当前帧率计算需要跳过的帧数 (0.7秒)
|
||||||
|
self.skip_frames_count = max(1, int(self.current_fps * 0.7))
|
||||||
|
|
||||||
def draw_detections(self, frame):
|
def draw_detections(self, frame):
|
||||||
"""在图像上绘制检测结果"""
|
"""在图像上绘制检测结果"""
|
||||||
# 获取车牌号列表
|
# 获取车牌号列表
|
||||||
@@ -1232,11 +1268,9 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# 更新车牌数量显示
|
# 更新车牌数量显示
|
||||||
self.count_label.setText(f"识别到的车牌数量: {len(stable_results)}")
|
self.count_label.setText(f"识别到的车牌数量: {len(stable_results)}")
|
||||||
print(f"稳定结果数量: {len(stable_results)}")
|
|
||||||
|
|
||||||
# 检查结果是否发生变化
|
# 检查结果是否发生变化
|
||||||
results_changed = self.check_results_changed(stable_results)
|
results_changed = self.check_results_changed(stable_results)
|
||||||
print(f"结果是否变化: {results_changed}")
|
|
||||||
|
|
||||||
if results_changed:
|
if results_changed:
|
||||||
# 清除之前的结果
|
# 清除之前的结果
|
||||||
@@ -1272,20 +1306,7 @@ class MainWindow(QMainWindow):
|
|||||||
for frame_id in expired_frame_ids:
|
for frame_id in expired_frame_ids:
|
||||||
del self.frame_command_sent[frame_id]
|
del self.frame_command_sent[frame_id]
|
||||||
|
|
||||||
# 清理过期的车牌记录 - 获取当前所有稳定车牌号
|
|
||||||
current_plate_numbers = set()
|
|
||||||
for result in stable_results:
|
|
||||||
plate_number = result.get('plate_number', '')
|
|
||||||
if plate_number and plate_number != "识别失败":
|
|
||||||
current_plate_numbers.add(plate_number)
|
|
||||||
|
|
||||||
# 清理不再出现的车牌记录
|
|
||||||
expired_plate_numbers = [plate_number for plate_number in self.plate_records.keys()
|
|
||||||
if plate_number not in current_plate_numbers]
|
|
||||||
for plate_number in expired_plate_numbers:
|
|
||||||
del self.plate_records[plate_number]
|
|
||||||
|
|
||||||
print("结果显示更新完成")
|
|
||||||
|
|
||||||
def check_results_changed(self, new_results):
|
def check_results_changed(self, new_results):
|
||||||
"""检查识别结果是否发生变化"""
|
"""检查识别结果是否发生变化"""
|
||||||
@@ -1379,7 +1400,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.process_frame(self.current_frame)
|
self.process_frame(self.current_frame)
|
||||||
|
|
||||||
def handle_gate_control(self, stable_results):
|
def handle_gate_control(self, stable_results):
|
||||||
|
|
||||||
"""处理道闸控制逻辑"""
|
"""处理道闸控制逻辑"""
|
||||||
current_time = datetime.now()
|
current_time = datetime.now()
|
||||||
|
|
||||||
@@ -1393,13 +1413,12 @@ class MainWindow(QMainWindow):
|
|||||||
if not plate_number or plate_number == "识别失败":
|
if not plate_number or plate_number == "识别失败":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 获取该车牌的帧计数,忽略最早的两帧结果
|
# 使用基于时间的延迟检查,确保车牌检测到0.7秒后才处理
|
||||||
frame_count = self.plate_stabilizer.plate_frame_count.get(plate_id, 0)
|
if not self.plate_stabilizer.is_plate_ready_for_processing(plate_id, 0.7):
|
||||||
if frame_count <= 2:
|
print(f"车牌ID: {plate_id} 尚未达到0.7秒延迟,跳过处理")
|
||||||
print(f"车牌ID: {plate_id} 帧数: {frame_count}, 忽略前两帧")
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 检查该识别框ID是否已经发送过命令
|
# 检查该识别框ID是否已经发送过命令(防止同一识别框重复发送)
|
||||||
if plate_id in self.frame_command_sent:
|
if plate_id in self.frame_command_sent:
|
||||||
print(f"识别框ID: {plate_id} 已发送过命令,跳过")
|
print(f"识别框ID: {plate_id} 已发送过命令,跳过")
|
||||||
continue
|
continue
|
||||||
@@ -1422,32 +1441,32 @@ class MainWindow(QMainWindow):
|
|||||||
print(f"发送道闸命令失败: {e}")
|
print(f"发送道闸命令失败: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# 白名单车牌的处理逻辑:基于车牌号判断首次/二次识别
|
||||||
if plate_number in self.plate_records:
|
if plate_number in self.plate_records:
|
||||||
# 二次识别到同一车牌
|
# 二次识别到同一车牌号(出库)
|
||||||
record = self.plate_records[plate_number]
|
record = self.plate_records[plate_number]
|
||||||
if not record['sent']:
|
# 计算时间间隔
|
||||||
# 计算时间间隔
|
time_diff = (current_time - record['first_time']).total_seconds()
|
||||||
time_diff = (current_time - record['first_time']).total_seconds()
|
|
||||||
|
# 发送时间间隔命令
|
||||||
|
message = f"{plate_number} {int(time_diff)}sec"
|
||||||
|
try:
|
||||||
|
send_command(1, message)
|
||||||
|
print(f"发送道闸命令: {message}")
|
||||||
|
|
||||||
# 发送时间间隔命令
|
# 标记该识别框ID已发送命令
|
||||||
message = f"{plate_number} {int(time_diff)}sec"
|
self.frame_command_sent[plate_id] = {
|
||||||
try:
|
'plate_number': plate_number,
|
||||||
send_command(1, message)
|
'command_sent': True
|
||||||
print(f"发送道闸命令: {message}")
|
}
|
||||||
|
|
||||||
# 标记该识别框ID已发送命令
|
# 清除记录,使第三次识别时重新按首次处理
|
||||||
self.frame_command_sent[plate_id] = {
|
del self.plate_records[plate_number]
|
||||||
'plate_number': plate_number,
|
|
||||||
'command_sent': True
|
except Exception as e:
|
||||||
}
|
print(f"发送道闸命令失败: {e}")
|
||||||
|
|
||||||
# 标记为已发送并清除记录,使第三次识别时重新按首次处理
|
|
||||||
del self.plate_records[plate_number]
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"发送道闸命令失败: {e}")
|
|
||||||
else:
|
else:
|
||||||
# 首次识别到车牌
|
# 首次识别到车牌号(入库)
|
||||||
try:
|
try:
|
||||||
message = f"{plate_number} 通行"
|
message = f"{plate_number} 通行"
|
||||||
send_command(1, message)
|
send_command(1, message)
|
||||||
@@ -1459,7 +1478,7 @@ class MainWindow(QMainWindow):
|
|||||||
'command_sent': True
|
'command_sent': True
|
||||||
}
|
}
|
||||||
|
|
||||||
# 记录车牌信息
|
# 记录车牌信息,等待二次识别
|
||||||
self.plate_records[plate_number] = {
|
self.plate_records[plate_number] = {
|
||||||
'first_time': current_time,
|
'first_time': current_time,
|
||||||
'sent': False
|
'sent': False
|
||||||
|
|||||||
Reference in New Issue
Block a user