如何在Python OpenCV中基于模型预测概率绘制情绪识别仪表盘
人脸情绪识别添加概率仪表盘实现方案
直接通过OpenCV内置绘图接口即可实现你要的半圆仪表盘效果,无需引入额外依赖,可直接调整参数适配你的画布尺寸,修改后的完整代码如下:
import cv2 import numpy as np # 此处保留你原本的模型加载、emotion_dict定义逻辑 # emotion_dict = {0: 'Angry', 1: 'Disgusted', 2: 'Fear', 3: 'Happy', 4: 'Sad', 5: 'Surprised', 6: 'Neutral'} # model = 你训练好的情绪识别模型 # 仪表盘参数配置,可自行调整位置、大小 GAUGE_CENTER = (200, 400) # 仪表盘在canvasImage上的中心坐标 GAUGE_RADIUS = 150 # 仪表盘半径 GAUGE_START_ANGLE = 180 # 半圆起始角度,对应0%概率 GAUGE_END_ANGLE = 360 # 半圆结束角度,对应100%概率 cap = cv2.VideoCapture(1) canvasImage = cv2.imread("fg2.png") x0, x1 = 330, 1290 y0, y1 = 155, 700 prediction_history = [] LOOKBACK = 5 # 历史预测帧回溯长度 while True: ret, frame = cap.read() frame=cv2.flip(frame,3) if not ret: break facecasc = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = facecasc.detectMultiScale(gray,scaleFactor=1.3, minNeighbors=5) current_prob = 0 current_text = "No face detected" for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y-50), (x+w, y+h+10), (255, 0, 0), 2) roi_gray = gray[y:y + h, x:x + w] cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray, (48, 48)), -1), 0) prediction = model.predict(cropped_img, verbose=0) # 加verbose=0关闭预测日志输出 maxindex = int(np.argmax(prediction)) current_prob = round(prediction[0][3]*100, 2) prediction_history.append(maxindex) most_common_index = max(set(prediction_history[-LOOKBACK:][::-1]), key = prediction_history.count) current_text = emotion_dict[most_common_index] if ("Happy" in current_text) or ("Sad" in current_text): cv2.putText(frame, current_text+": "+str(current_prob), (x+20, y-60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA) frame_shrunk = cv2.resize(frame, (x1 - x0, y1 - y0)) canvasImage[y0:y1, x0:x1] = frame_shrunk # --------------- 新增仪表盘绘制逻辑 --------------- # 1. 绘制半圆仪表盘底座 cv2.ellipse(canvasImage, GAUGE_CENTER, (GAUGE_RADIUS, GAUGE_RADIUS), 0, GAUGE_START_ANGLE, GAUGE_END_ANGLE, (200,200,200), 3) # 2. 绘制刻度标记(0%、50%、100%) for percent in [0, 50, 100]: angle = GAUGE_START_ANGLE + (percent/100)*(GAUGE_END_ANGLE - GAUGE_START_ANGLE) rad = np.deg2rad(angle) # 刻度线外端点 outer_x = int(GAUGE_CENTER[0] + GAUGE_RADIUS * np.cos(rad)) outer_y = int(GAUGE_CENTER[1] + GAUGE_RADIUS * np.sin(rad)) # 刻度线内端点 inner_x = int(GAUGE_CENTER[0] + GAUGE_RADIUS * 0.85 * np.cos(rad)) inner_y = int(GAUGE_CENTER[1] + GAUGE_RADIUS * 0.85 * np.sin(rad)) cv2.line(canvasImage, (outer_x, outer_y), (inner_x, inner_y), (200,200,200), 2) # 刻度数值 text_x = int(GAUGE_CENTER[0] + GAUGE_RADIUS * 1.1 * np.cos(rad)) - 15 text_y = int(GAUGE_CENTER[1] + GAUGE_RADIUS * 1.1 * np.sin(rad)) + 5 cv2.putText(canvasImage, f"{percent}%", (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 2) # 3. 绘制指针 pointer_angle = GAUGE_START_ANGLE + (current_prob/100)*(GAUGE_END_ANGLE - GAUGE_START_ANGLE) pointer_rad = np.deg2rad(pointer_angle) pointer_end_x = int(GAUGE_CENTER[0] + GAUGE_RADIUS * 0.8 * np.cos(pointer_rad)) pointer_end_y = int(GAUGE_CENTER[1] + GAUGE_RADIUS * 0.8 * np.sin(pointer_rad)) cv2.line(canvasImage, GAUGE_CENTER, (pointer_end_x, pointer_end_y), (0,0,255), 3) # 4. 绘制仪表盘中心圆点和当前情绪+概率文字 cv2.circle(canvasImage, GAUGE_CENTER, 8, (0,0,255), -1) cv2.putText(canvasImage, f"{current_text}: {current_prob}%", (GAUGE_CENTER[0] - 80, GAUGE_CENTER[1] + 50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2) # ------------------------------------------------- cv2.imshow('Demo', canvasImage) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
你可以根据自己的画布布局调整GAUGE_CENTER和GAUGE_RADIUS参数修改仪表盘的位置和大小,也可以修改绘图时的颜色参数自定义样式。
内容的提问来源于stack exchange,提问作者angel_30
相关产品推荐
相关产品推荐

