Home > Back-end >  How to create a meter based on model's probability in Python OpenCV
How to create a meter based on model's probability in Python OpenCV

Time:10-14

I have this simple Python code that makes predictions on the emotions of the face (refer to enter image description here

cap = cv2.VideoCapture(1)

canvasImage = cv2.imread("fg2.png")

x0, x1 = 330, 1290
y0, y1 = 155, 700


prediction_history = []
LOOKBACK = 5 # how far you want to look back

counter = 0
while True:
    # Find haar cascade to draw bounding box around face
    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)

    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)
        
        maxindex = int(np.argmax(prediction))
        text = emotion_dict[maxindex]
        prob = round(prediction[0][3]*100, 2)
        
        prediction_history.append(maxindex)
        most_common_index = max(set(prediction_history[-LOOKBACK:][::-1]), key = prediction_history.count)
        text = emotion_dict[most_common_index]
        
        #if ("Sad" in text) or ("Angry" in text) or ("Disgusted" in text):
        #    text = "Sad"
        if ("Happy" in text) or ("Sad" in text) :
            cv2.putText(frame, text ": " str(prob), (x 20, y-60), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
  

    dim = (800,480)
    frame_shrunk = cv2.resize(frame, (x1 - x0, y1 - y0))
    canvasImage[y0:y1, x0:x1] = frame_shrunk
    #cv2.imshow('Video', cv2.resize(frame,dim,interpolation = cv2.INTER_CUBIC))
    cv2.imshow('Demo', canvasImage)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

CodePudding user response:

There is no built in function in OpenCV for drawing meters, here is a helper function that you can use to draw a meter over an image:

def draw_indicator(img, percentage):

    def percentage_to_color(p):
        return 0, 255 * p, 255 - (255 * p)

    # config
    levels = 10
    indicator_width = 80
    indicator_height = 220
    level_width = indicator_width - 20
    level_height = int((indicator_height - 20) / levels - 5)
    # draw
    img_levels = int(percentage * levels)
    cv2.rectangle(img, (10, img.shape[0] - (indicator_height   10)), (10   indicator_width, img.shape[0] - 10), (0, 0, 0), cv2.FILLED)

    for i in range(img_levels):
        level_y_b = int(img.shape[0] - (20   i * (level_height   5)))
        cv2.rectangle(img, (20, level_y_b - level_height), (20   level_width, level_y_b), percentage_to_color(i / levels), cv2.FILLED)

# test code
img = cv2.imread('a.jpg')
draw_indicator(img, 0.7)
cv2.imshow("test", img)
cv2.waitKey(10000)
  • Related