基于openpose识别学生上课不认真听课坐姿的c++代码
时间: 2023-12-30 21:05:31 浏览: 155
以下程序求两个数的大者请填空。-c++自学资料
由于openpose官方提供了python API接口,因此我们可以使用Python来实现基于openpose的学生上课不认真听课坐姿识别。
代码如下:
```
import cv2
import numpy as np
import math
import time
import argparse
# 加载OpenPose模型
net = cv2.dnn.readNetFromTensorflow("models/graph_opt.pb")
# 人体关键点连接的索引
POSE_PAIRS = [
[0, 1], [1, 2], [2, 3], [3, 4], # 身体连接
[1, 5], [5, 6], [6, 7], [1, 8], [8, 9], [9, 10], # 左臂连接
[1, 11], [11, 12], [12, 13], [1, 0], [0, 14], [14, 15], # 右臂连接
[14, 16], [0, 17], [17, 18], [18, 19], [19, 20] # 身体连接
]
# 坐姿的关键点索引
SITTING_POINTS = [8, 9, 10, 11, 12, 13]
# 计算两个关键点之间的距离
def get_distance(p1, p2):
return math.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)
# 判断学生是否坐姿不正确
def is_not_sitting(points):
# 计算左右膝盖之间的距离
knee_distance = get_distance(points[9], points[10])
# 计算左右脚踝到左右膝盖之间的距离
left_leg_distance = get_distance(points[9], points[11]) + get_distance(points[11], points[13])
right_leg_distance = get_distance(points[10], points[12]) + get_distance(points[12], points[14])
# 计算左右脚踝到左右膝盖之间的距离与膝盖之间的距离的比值
left_leg_ratio = left_leg_distance / knee_distance
right_leg_ratio = right_leg_distance / knee_distance
# 如果比值小于1.5,说明坐姿不正确
if left_leg_ratio < 1.5 or right_leg_ratio < 1.5:
return True
return False
# 绘制关键点和连接线
def draw_keypoints(frame, points):
for i, point in enumerate(points):
x, y = point
cv2.circle(frame, (x, y), 3, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
cv2.putText(frame, "{}".format(i), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, lineType=cv2.LINE_AA)
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]
if points[partA] and points[partB]:
cv2.line(frame, points[partA], points[partB], (0, 255, 255), 2, lineType=cv2.LINE_AA)
# 识别学生坐姿
def detect_sitting(frame):
# 转换帧为blob
blob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (368, 368), (0, 0, 0), swapRB=False, crop=False)
# 通过网络进行前向传播
net.setInput(blob)
output = net.forward()
# 提取关键点坐标
points = []
for i in range(len(SITTING_POINTS)):
prob_map = output[0, SITTING_POINTS[i], :, :]
min_val, prob, min_loc, point = cv2.minMaxLoc(prob_map)
x = int(frame.shape[1] * point[0] / output.shape[3])
y = int(frame.shape[0] * point[1] / output.shape[2])
if prob > 0.1:
points.append((x, y))
else:
points.append(None)
# 绘制关键点和连接线
draw_keypoints(frame, points)
# 判断学生是否坐姿不正确
if is_not_sitting(points):
cv2.putText(frame, "Sitting position is not correct!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, lineType=cv2.LINE_AA)
# 主函数
if __name__ == "__main__":
# 解析命令行参数
parser = argparse.ArgumentParser()
parser.add_argument("--input", type=str, default="", help="Path to input video file. If empty, camera's stream will be used")
args = parser.parse_args()
# 打开视频文件或启动摄像头
cap = cv2.VideoCapture(args.input if args.input else 0)
# 逐帧处理视频
while True:
# 读取帧
ret, frame = cap.read()
if not ret:
break
# 识别学生坐姿
detect_sitting(frame)
# 显示帧
cv2.imshow("Video", frame)
# 按下q键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
```
运行代码后,程序会识别视频中学生的坐姿,如果学生坐姿不正确,程序会在视频中显示警告信息。可以通过命令行参数指定输入的视频文件路径,如果不指定,则程序将启动摄像头并获取实时视频流。
阅读全文