再次修复了车牌判断的bug
This commit is contained in:
		
							
								
								
									
										103
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								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"
 | 
					                message = f"{plate_number} {int(time_diff)}sec"
 | 
				
			||||||
                    try:
 | 
					                try:
 | 
				
			||||||
                        send_command(1, message)
 | 
					                    send_command(1, message)
 | 
				
			||||||
                        print(f"发送道闸命令: {message}")
 | 
					                    print(f"发送道闸命令: {message}")
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                        # 标记该识别框ID已发送命令
 | 
					                    # 标记该识别框ID已发送命令
 | 
				
			||||||
                        self.frame_command_sent[plate_id] = {
 | 
					                    self.frame_command_sent[plate_id] = {
 | 
				
			||||||
                            'plate_number': plate_number,
 | 
					                        'plate_number': plate_number,
 | 
				
			||||||
                            'command_sent': True
 | 
					                        'command_sent': True
 | 
				
			||||||
                        }
 | 
					                    }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                        # 标记为已发送并清除记录,使第三次识别时重新按首次处理
 | 
					                    # 清除记录,使第三次识别时重新按首次处理
 | 
				
			||||||
                        del self.plate_records[plate_number]
 | 
					                    del self.plate_records[plate_number]
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    except Exception as e:
 | 
					                except Exception as e:
 | 
				
			||||||
                        print(f"发送道闸命令失败: {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