视频文件中的对象检测

在处理后的视频文件中进行对象检测是一项常见的任务。本文将介绍如何使用TensorFlowMobileNet模型来实现这一功能。将从读取视频文件开始,然后展示如何过滤检测结果,以便只显示人。

为了进行对象检测,首先创建了一个名为VideoReader的类(参见video_reader.pyPart_05文件夹中)。这个类内部使用了OpenCVVideoCapture。与之前从相机读取帧的情况类似,主要区别在于需要将文件路径传递给VideoCapture的初始化器:

def __init__(self, file_path): try: self.video_capture = opencv.VideoCapture(file_path) except Exception as e: print(e)

然后,通过调用VideoCapture类实例的read方法来读取文件中的连续帧:

def read_next_frame(self): (capture_status, frame) = self.video_capture.read() if capture_status: return frame else: return None

要使用VideoReader类,首先调用初始化器以提供输入视频文件,然后根据需要多次调用read_next_frame方法来读取帧。当方法到达文件末尾时,它将返回None

检测人

为了检测人,使用了之前创建的模块,包括InferenceImageHelper类。将在main.py中引用它们。这些模块的源代码包含在Part_03文件夹中,并在之前的文章中进行了解释。

为了引用这些模块,在main.py文件中添加了以下语句,假设主脚本是从Part_05文件夹执行的:

import sys sys.path.insert(1, '../Part_03/') from inference import Inference as model from image_helper import ImageHelper as imgHelper

因此,可以轻松地访问视频文件帧上的对象检测

model_file_path = '../Models/01_model.tflite' labels_file_path = '../Models/02_labels.txt' ai_model = model(model_file_path, labels_file_path) video_file_path = '../Videos/01.mp4' video_reader = videoReader(video_file_path) frame = video_reader.read_next_frame() score_threshold = 0.5 results = ai_model.detect_objects(frame, score_threshold)

然而,问题在于检测了模型训练的所有对象。为了只检测人,需要过滤detect_objects方法返回的结果。为此,使用检测对象的标签。过滤方法可以如下实现:

def detect_people(self, image, threshold): all_objects = self.detect_objects(image, threshold) people = filter(lambda r: r['label'] == 'person', all_objects) return list(people)

将上述方法detect_people添加到了Inference类中(参见inference.pyPart_03文件夹中)。detect_people函数内部调用detect_objects,然后使用内置的Python函数filter来过滤结果。第一个参数是过滤方法。在这里,使用了一个匿名lambda函数,它返回一个布尔值。当当前检测结果的标签是"person"时为True,否则为False

显示检测结果

为了显示检测到的人,使用了image_helper模块中的静态display_image_with_detected_objects方法。然而,display_image_with_detected_objects方法原本是为了在用户按下键之前显示图像。如果将其用于视频序列,用户将需要为每一帧按下键。为了适应视频,通过添加另一个参数delay来修改该方法。将这个参数的值传递给OpenCVwaitKey方法,以设置等待超时:

@staticmethod def display_image_with_detected_objects(image, inference_results, delay=0): opencv.namedWindow(common.WINDOW_NAME, opencv.WINDOW_GUI_NORMAL) for i in range(len(inference_results)): current_result = inference_results[i] ImageHelper.draw_rectangle_and_label(image, current_result['rectangle'], current_result['label']) opencv.imshow(common.WINDOW_NAME, image) opencv.waitKey(delay)

默认情况下,延迟为0,因此该方法仍将适用于期望它等待按键的调用。

整合所有组件

所有组件都准备好后,可以将它们整合在一起:

import sys sys.path.insert(1, '../Part_03/') from inference import Inference as model from image_helper import ImageHelper as imgHelper from video_reader import VideoReader as videoReader if __name__ == "__main__": model_file_path = '../Models/01_model.tflite' labels_file_path = '../Models/02_labels.txt' ai_model = model(model_file_path, labels_file_path) video_file_path = '../Videos/01.mp4' video_reader = videoReader(video_file_path) score_threshold = 0.4 detect_only_people = False delay_between_frames = 5 while True: frame = video_reader.read_next_frame() if frame is None: break if detect_only_people: results = ai_model.detect_people(frame, score_threshold) else: results = ai_model.detect_objects(frame, score_threshold) imgHelper.display_image_with_detected_objects(frame, results, delay_between_frames)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485