树莓派4B基于TensorFlow Lite的车辆碰撞检测速度显示故障排查
车辆碰撞检测系统速度检测功能无法显示的问题修复
核心问题分析
你的代码存在两个关键逻辑错误,导致速度检测功能完全无法运行:
- 每次循环都将
tracked_objects初始化为空列表,遍历该列表的速度计算代码根本不会执行 tracked_objects_info在循环内重复初始化,无法保留物体的历史位置和时间数据,无法完成速度计算
修复后的完整代码
# Copyright 2021 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Main script to run the object detection routine.""" import argparse import sys import time import cv2 from tflite_support.task import core from tflite_support.task import processor from tflite_support.task import vision import utils def run(model: str, camera_id: int, width: int, height: int, num_threads: int, enable_edgetpu: bool) -> None: """Continuously run inference on images acquired from the camera. Args: model: Name of the TFLite object detection model. camera_id: The camera id to be passed to OpenCV. width: The width of the frame captured from the camera. height: The height of the frame captured from the camera. num_threads: The number of CPU threads to run the model. enable_edgetpu: True/False whether the model is a EdgeTPU model. """ # Variables to calculate FPS counter, fps = 0, 0 start_time = time.time() # Start capturing video input from the camera #cap = cv2.VideoCapture('/home/secret/Desktop/Design1/input_video.mp4') cap = cv2.VideoCapture(1) cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) # Visualization parameters row_size = 20 # pixels left_margin = 24 # pixels text_color = (0, 0, 255) # red font_size = 1 font_thickness = 1 fps_avg_frame_count = 10 # Initialize the object detection model base_options = core.BaseOptions( file_name=model, use_coral=enable_edgetpu, num_threads=num_threads) detection_options = processor.DetectionOptions( max_results=3, score_threshold=0.3) options = vision.ObjectDetectorOptions( base_options=base_options, detection_options=detection_options) detector = vision.ObjectDetector.create_from_options(options) # 将跟踪相关变量移到循环外,保留跨帧数据 tracked_objects_info = {} tracked_objects = [] # Continuously capture images from the camera and run inference while cap.isOpened(): success, image = cap.read() if not success: sys.exit( 'ERROR: Unable to read from webcam. Please verify your webcam settings.' ) counter += 1 image = cv2.flip(image, 1) # Convert the image from BGR to RGB as required by the TFLite model. rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # Create a TensorImage object from the RGB image. input_tensor = vision.TensorImage.create_from_array(rgb_image) # Run object detection estimation using the model. detection_result = detector.detect(input_tensor) # Draw keypoints and edges on input image image = utils.visualize(image, detection_result) # 从检测结果中提取bounding box到tracked_objects tracked_objects = [] for detection in detection_result.detections: bbox = detection.bounding_box # 转换为[x, y, width, height]格式 x = bbox.origin_x y = bbox.origin_y w = bbox.width h = bbox.height tracked_objects.append((x, y, w, h)) # Calculate the FPS if counter % fps_avg_frame_count == 0: end_time = time.time() fps = fps_avg_frame_count / (end_time - start_time) start_time = time.time() # Show the FPS fps_text = 'FPS = {:.1f}'.format(fps) text_location = (left_margin, row_size) cv2.putText(image, fps_text, text_location, cv2.FONT_HERSHEY_PLAIN, font_size, text_color, font_thickness) current_time = time.time() # 遍历检测到的物体计算速度 for i, bbox in enumerate(tracked_objects): if i not in tracked_objects_info: tracked_objects_info[i] = { "previous_position": None, "previous_time": None, "speed": None, } # 计算 bounding box 中心坐标 x, y, w, h = bbox center_x = x + w // 2 center_y = y + h // 2 # 计算位移 previous_position = tracked_objects_info[i]["previous_position"] displacement = ((center_x - previous_position[0]) ** 2 + (center_y - previous_position[1]) ** 2) ** 0.5 if previous_position else 0 # 计算时间差 previous_time = tracked_objects_info[i]["previous_time"] time_difference = current_time - previous_time if previous_time else 0 # 计算速度(像素/秒) speed = displacement / time_difference if time_difference > 0 else 0 # 更新物体历史信息 tracked_objects_info[i]["previous_position"] = (center_x, center_y) tracked_objects_info[i]["previous_time"] = current_time tracked_objects_info[i]["speed"] = speed # 在画面上显示速度 speed_text = f'Speed {i+1}: {speed:.2f} pixels/sec' text_location = (left_margin, row_size * (i + 2)) cv2.putText(image, speed_text, text_location, cv2.FONT_HERSHEY_PLAIN, font_size, text_color, font_thickness) # 按下ESC键退出程序 if cv2.waitKey(1) == 27: break cv2.imshow('object_detector', image) cap.release() cv2.destroyAllWindows() def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--model', help='Path of the object detection model.', required=False, default='efficientdet_lite0.tflite') parser.add_argument( '--cameraId', help='Id of camera.', required=False, type=int, default=0) parser.add_argument( '--frameWidth', help='Width of frame to capture from camera.', required=False, type=int, default=640) parser.add_argument( '--frameHeight', help='Height of frame to capture from camera.', required=False, type=int, default=480) parser.add_argument( '--numThreads', help='Number of CPU threads to run the model.', required=False, type=int, default=4) parser.add_argument( '--enableEdgeTPU', help='Whether to run the model on EdgeTPU.', action='store_true', required=False, default=False) args = parser.parse_args() run(args.model, int(args.cameraId), args.frameWidth, args.frameHeight, int(args.numThreads), bool(args.enableEdgeTPU)) if __name__ == '__main__':
关键修改说明
- 跟踪变量移至循环外:将
tracked_objects_info和tracked_objects的初始化放在while循环之前,确保每帧的历史数据不会被重置,能够保留物体的位置和时间信息用于速度计算。 - 填充检测到的物体数据:在每帧检测完成后,从
detection_result中提取每个物体的bounding box,转换为[x, y, width, height]格式后存入tracked_objects,这样速度计算的遍历循环才有数据可处理。 - 优化时间变量:将
current_time的提取移到遍历之前,避免在循环内重复调用time.time(),保证时间计算的一致性。
内容的提问来源于stack exchange,提问作者Lre
相关产品推荐
相关产品推荐

