人体姿态评估中有两种常见的显示方式,分别是火柴人效果与BodyPix效果。其中火柴人效果本质就是基于关键点的深度学习模型推理以后的显示效果;Bodypix本质就就是语义分割模型,基于Deeplabv3+ 与ResNet34构建的一个人体语义分割模型。
火柴人
主要是基于关键点的人体姿态评估显示方式,基于YOLOv8等人体姿态评估的关键点模型均可以实现,演示代码运行效果如下:
BodyPix
主要是基于语义分割的人体姿态评估显示方式,支持对人体分割为10或者15个标签,演示代码运行效果如下:
实现代码
我把相关的代码使用PyQT5封装为一个线程,相关的代码如下:
class InferenceThread(QtCore.QThread):
fire_stats_signal = QtCore.pyqtSignal(dict)
def __init__(self, settings):
super(InferenceThread, self).__init__()
self.settings = settings
self.detector = None
if self.settings.model_type == 0:
self.detector = YOLOv8ORTPose(settings)
self.detector.show_skeleton = True
if self.settings.model_type == 1:
self.detector = YOLOv8ORTPose(settings)
self.detector.show_skeleton = True
if self.settings.model_type == 2:
weight_file_path = "D:/projects/body_part_best.onnx"
self.detector = BodyPixSegment(weight_file_path)
self.input_image = settings.input_image
def run(self):
if self.detector is None:
return
if self.input_image.endswith(".mp4"):
cap = cv.VideoCapture(self.input_image)
while True:
ret, frame = cap.read()
if ret is True:
dst = self.detector.infer_image(frame)
self.fire_stats_signal.emit({"result": frame, "mask":dst})
else:
break
else:
frame = cv.imread(self.input_image)
dst = self.detector.infer_image(frame)
self.fire_stats_signal.emit({"result": frame, "mask":dst})
self.fire_stats_signal.emit({"done": "done"})
return
点击【开始推理】按钮的执行代码如下:
def on_yolov8_infer(self):
image_file = self.image_file_edit.text()
label_file = self.label_file_path.text()
model_file = self.weight_file_path.text()
if len(image_file) == 0 or len(label_file) == 0 or len(model_file) == 0:
QtWidgets.QMessageBox.warning(self, "警告", "参数文件未选择...")
return
settings = DLInferSettings()
settings.weight_file_path = self.weight_file_path.text()
settings.label_map_file_path = self.label_file_path.text()
settings.score_threshold = self.conf_spinbox.value()
settings.input_image = image_file
settings.model_type = 0
if self.rbtn0.isChecked():
settings.model_type = 0
if self.rbtn1.isChecked():
settings.model_type = 1
if self.rbtn2.isChecked():
settings.model_type = 2
settings.target_deploy = 1
self.work_thread = InferenceThread(settings)
self.work_thread.fire_stats_signal.connect(self.on_update_result_image)
self.work_thread.finished.connect(self.work_thread.deleteLater)
self.work_thread.start()
self.startBtn.setStyleSheet("background-color:gray; color: white")
self.startBtn.setEnabled(False)
self.stopBtn.setStyleSheet("background-color:cyan; color: black")
self.stopBtn.setEnabled(True)
运行结果如下: