Actual combat | Use Python and OpenCV to build an intelligent monitoring system for the elderly's falls (steps + source code)

An unknown college student, known as Caigou by Jiang Hu
original author: jacky Li
Email : [email protected]

 Time of completion:2023.2.4
Last edited: 2023.2.4

guide

This article will use Python, OpenCV and MediaPipe to build an intelligent monitoring system for falls of the elderly. In order to prevent a quiet fall in the future, no one will take care of it.

Table of contents

background introduction

Implementation steps

[1] Import the necessary modules:

[2] Define a function to calculate the angle:

【3】Find coordinates:

【4】How to know whether the subject (elderly person) is safe or has fallen?

【5】How to distinguish the bed from the floor?

[6] Let's print the result on the screen:

[7] Add GUI:

The author has something to say


background introduction

    The elderly monitoring system is an intelligent detection system that can detect whether the elderly are lying on the bed or falling to the ground. This is a real problem solving program that can be used to monitor the elderly at home while you are away at work or away so that you can be notified if any problems arise.

Implementation steps

[1] Import the necessary modules:

    Import Numpy, MediaPipe and opencv in python

import cv2
import mediapipe as mp
import numpy as np

[2] Define a function to calculate the angle:

    Since we will assume whether a person is walking or falling on the ground based on the angle and coordinates we get using OpenCV, we have to calculate the angle, the easiest way is to define a function and call it in the program.

def calculate_angle(a,b,c):
    a = np.array(a) # First
    b = np.array(b) # Mid
    c = np.array(c) # End
    
    radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0])
    angle = np.abs(radians*180.0/np.pi)
    
    if angle >180.0:
        angle = 360-angle
        
    return angle 

【3】Find coordinates:

    We also have to find the coordinates so we can use them in conditions and also use them with the calculate_angle function.

            left_eye = [landmarks[mp_pose.PoseLandmark.LEFT_EYE.value].x,landmarks[mp_pose.PoseLandmark.LEFT_EYE.value].y]
            left_hip= [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x,landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y]
            left_heel = [landmarks[mp_pose.PoseLandmark.LEFT_HEEL.value].x,landmarks[mp_pose.PoseLandmark.LEFT_HEEL.value].y]
            right_eye = [landmarks[mp_pose.PoseLandmark.RIGHT_EYE.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_EYE.value].y]
            right_hip = [landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value].y]
            right_heel = [landmarks[mp_pose.PoseLandmark.RIGHT_HEEL.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_HEEL.value].y]
            right_index = [landmarks[mp_pose.PoseLandmark.RIGHT_INDEX.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_INDEX.value].y] 
            left_index = [landmarks[mp_pose.PoseLandmark.LEFT_INDEX.value].x,landmarks[mp_pose.PoseLandmark.LEFT_INDEX.value].y]
            # Calculate angle

【4】How to know whether the subject (elderly person) is safe or has fallen?

    We'll find this with the help of coordinates obtained from cv2 and mediapipe and angles using the functions defined above.

    Since we're getting the coordinates of the eyes, hips, and ankles, we know that when a person is lying flat (falling down), the angle between their eyes, hips, and ankles is in the range of 170 to 180 degrees. So we can simply put a condition where we can say a person fell down when the angle is between 170 -180 degrees.

                if angle1 != angle2 and (angle1>170 and angle2>170):
                    if (((right_index[0]<0.70 and right_index[0]>0.20) and (right_index[1]<0.56 and right_index[1]>0.15)) or ((left_index[0]<0.55 and left_index[0]>0.18) and (left_index[1]<0.56 and left_index[1]>0.15))):
                        stage="Hanging on !!"
                    else:
                        stage = "fallen :("    

                elif angle1 != angle2 and (angle1<140 or angle2<140) :
                    stage = "Trying to Walk"
                elif angle1!=angle2 and ((angle1<168 and angle1>140) and (angle2<168 and angle2>140)):
                    stage="Barely Walking"
                else:
                    pass

 Now the question that might be in your mind is how to determine if the person really fell or if he was just laying on the bed since in both cases the angles are in the same range.

We'll answer it too, so read on :)

【5】How to distinguish the bed from the floor?

    We will again use the coordinates obtained from OpenCV, and then use it to find the coordinates of the bed, and then introduce a new condition when checking for the fall condition, that when the subject's coordinates coincide with the bed coordinates, it means that a person is on the bed Naturally it is safe. This condition will rule out a fall and the program will show safe. The fall condition and other walk and attempt walk conditions are checked only if this condition becomes false.

            if ((left_eye[0]>=0.41 and left_eye[0]<=0.43) and (left_hip[0]>=0.44 and left_hip[0]<=0.46) and (left_heel[0]>=0.41 and left_heel[0]<=0.43) or (right_eye[0]>=0.41 and right_eye[0]<=0.43) and (right_hip[0]<=0.43 and right_hip[0]>=0.41) and (right_heel[0]>=0.37 and right_heel[0]<=0.39)):

                if ((left_eye[1]>=0.24 and left_eye[1]<=0.33) and (left_hip[1]<=0.35 and left_hip[1]>=0.45) and (left_heel[1]<=0.74 and left_heel[1]>=0.72) or (right_eye[1]<=0.30 and right_eye[1]>=0.24) and (right_hip[1]<=0.50 and right_hip[1]>=0.32) and (right_heel[1]>=0.71 and right_heel[0]<=0.73)):
                    stage = "safe :)"
            # Curl counter logic

Therefore, by introducing a single condition with bed coordinates, we also solve the above problem.

[6] Let's print the result on the screen:

    Now print the results of fall and safety etc; we can easily use the putText function in cv2 to display the text saved in the variable stage.

    An example usage of the function is as follows:

cv2.putText(image, ‘Condition: ‘, (15,12), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1, cv2.LINE_AA)

[7] Add GUI:

    We can also add a little GUI to further enhance the overall program's appearance and make it more user-friendly. An example code snippet to implement the simplest GUI is as follows:

root = Tk()
root.geometry("1920x1080+0+0")
root.state("zoomed")
root.config(bg="#3a3b3c")
root.title("Eldering Monitring")

def path_select():
    global video_path,cap
    video_path = filedialog.askopenfilename()
    cap = cv2.VideoCapture(video_path)
    text = Label(root,text="Recorded Video  ",bg="#3a3b3c",fg="#ffffff",font=("Calibri",20))
    text.place(x=250,y=150)
# For Live feed
def video_live():
    global video_path,cap
    video_path = 0
    cap = cv2.VideoCapture(video_path)
    text = Label(root,text="Live Video Feed",bg="#3a3b3c",fg="#ffffff",font=("Calibri",20))
    text.place(x=250,y=150)
    
    
live_btn = Button(root, height =1,text='LIVE', width=8, fg='magenta', font=("Calibri", 14, "bold"), command=lambda:video_live())
live_btn.place(x=1200,y=20)
text = Label(root,text="  For Live Video",bg="#3a3b3c",fg="#ffffff",font=("Calibri",20))
text.place(x=1000,y=30)

browse_btn = Button(root, height = 1, width=8 ,text='VIDEO',fg='magenta', font=("Calibri", 14, "bold"), command=lambda:path_select())
browse_btn.place(x=1200,y=90)
text = Label(root,text="To Browse Video",bg="#3a3b3c",fg="#ffffff",font=("Calibri",20))
text.place(x=1000,y=90)


ttl = Label(root,text="ELDERING MONITERING ",bg="#4f4d4a",fg="#fffbbb",font=("Calibri",40))
ttl.place(x=100,y=50)

Video_frame = Frame(root, height=720, width=1080, bg="#3a3b3c")
Video_Label = Label(root)
Video_frame.place(x=15,y=200)
Video_Label.place(x=15,y=200)

The author has something to say

If you need the code, please chat with the blogger privately, and the blogger will see back.
If you feel that what the blogger said is useful to you, please click to support it, and will continue to update such issues...

Guess you like

Origin blog.csdn.net/weixin_62075168/article/details/128885743