This commit is contained in:
2021-11-12 13:12:40 -06:00
commit 7976f1a1c5
7 changed files with 230 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.tsv

BIN
data/curl.mp4 Normal file

Binary file not shown.

BIN
data/press.mp4 Normal file

Binary file not shown.

BIN
data/situp.mp4 Normal file

Binary file not shown.

110
main.py Normal file
View File

@@ -0,0 +1,110 @@
import numpy as np
import cv2
import datetime
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('WebAgg')
scale = 2
max_count = 1088*1920*255
def processVideo(path):
prev_gray = None
data = []
cap = cv2.VideoCapture(path)
alpha = 0.90
posx = 0.0
posy = 0.0
posxs = []
posys = []
counts = []
while True:
ret, src = cap.read()
if not ret:
print(ret)
break
else:
smol = cv2.resize(
src, (int(src.shape[1]/scale), int(src.shape[0]/scale)))
gray = cv2.cvtColor(smol, cv2.COLOR_BGR2GRAY)
if prev_gray is not None:
diff = cv2.absdiff(gray, prev_gray)
blur = cv2.GaussianBlur(diff, (5,5),0)
retval, thresh = cv2.threshold(blur, 50, 255, cv2.THRESH_TOZERO)
cv2.imshow("thresh", thresh)
count = np.sum(thresh)/max_count * 100.0
if count > 0.001 and count < 0.1:
moments = cv2.moments(thresh)
cX = int(moments["m10"] / moments["m00"])
cY = int(moments["m01"] / moments["m00"])
posx = posx * alpha + cX * (1.0-alpha)
posy = posy * alpha + cY * (1.0-alpha)
posxs.append(posx)
posys.append(posy)
counts.append(count)
cv2.putText(smol, "{:.2}".format(count), (20, 50),
cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 2)
i = 0
while i < len(posxs):
blue_color = 0
if counts[i] > 0.01:
blue_color = 255
else:
blue_color = counts[i]/0.01 * 255
cv2.circle(smol, (int(posxs[i]), int(posys[i])), 10, (blue_color,0,0),6)
i+= 1
if count > 0.1:
count = 0.1
data.append(count)
cv2.imshow("src", smol)
prev_gray = np.copy(gray)
key = cv2.waitKey(10)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
return data
out = open("data.tsv", "w+")
data1 = processVideo("data/curl.mp4")
data2 = processVideo("data/press.mp4")
data3 = processVideo("data/situp.mp4")
i = 0
max_length = 0
if len(data1) > max_length:
max_length = len(data1)
if len(data2) > max_length:
max_length = len(data2)
if len(data3) > max_length:
max_length = len(data3)
while i < max_length:
d1 = 0
try:
d1 = data1[i]
except:
print("")
d2 = 0
try:
d2 = data2[i]
except:
print("")
d3 = 0
try:
d3 = data3[i]
except:
print("")
out.write("{}\t{}\t{}\n".format(d1, d2, d3))
i += 1
out.close()

33
plot.py Normal file
View File

@@ -0,0 +1,33 @@
import matplotlib.pyplot as plt
import matplotlib
import pandas as pd
import numpy as np
from scipy.signal import savgol_filter
import scipy.signal as signal
import sys
df = pd.read_csv(sys.argv[1],delimiter="\t")
target = sys.argv[2]
time_size = 5
window = time_size * 30 + 1
def reject_outliers(data,indicies, m = 2.):
d = np.abs(data - np.median(data))
mdev = np.median(d)
s = d/mdev if mdev else 0.
return (data[s<m],indicies[s<m])
xhat = savgol_filter(df[target].array.to_numpy(),window,3)
indexs = np.arange(len(xhat))
xhat,xs = reject_outliers(xhat,indexs,m=1.5)
indicies = signal.argrelextrema(xhat, np.less,order=int(window/2))[0]
plt.plot(df[target])
plt.plot(xs,xhat,color="green")
plt.plot(xs[indicies],xhat[indicies],marker="o", ls="", ms=3 )
value1 = np.median(xhat)
print(np.median(xhat))
# value2 = np.percentile(xhat, 75)
plt.plot([0,len(df[target])],[value1,value1],color="purple")
#plt.plot([0,len(xhat)],[value2,value2])
plt.show()

86
process.py Normal file
View File

@@ -0,0 +1,86 @@
import numpy as np
import cv2
import math
import sys
# Init
target = sys.argv[1]
cap = cv2.VideoCapture("data/{}.mp4".format(target))
cap.set(cv2.CAP_PROP_FPS,240)
out = open("{}.tsv".format(target),"w+")
out.write("Time\tX\tY\tCount\tVelocity\n")
# Image Processing
scale = 16.0
diff_thresh = 50
blur_kernel = (7,7)
# Background
bg_alpha = 0.99
bg = None
bg_float = None
# Position
pos_alpha = 0.99
posx = 0.0
posy = 0.0
# Count
running_count = 0.0
# Main Loop
frame_number = 0
while True:
# Grab Frame
ret, src = cap.read()
if not ret:
break
# Ensmallen and grayen
blur = cv2.GaussianBlur(src, blur_kernel,0)
smol = cv2.resize(blur, (int(src.shape[1]/scale), int(src.shape[0]/scale)))
gray = cv2.cvtColor(smol, cv2.COLOR_BGR2GRAY)
if bg is None:
bg = gray
bg_float = np.zeros(gray.shape,dtype=np.float32)
# Get Difference
diff = cv2.absdiff(gray, bg)
retval, thresh = cv2.threshold(diff, diff_thresh, 255, cv2.THRESH_TOZERO)
# Normalize Count
count = np.sum(thresh)/(smol.shape[0]*smol.shape[1]*255)
# Process Count
if count > 0.0:
moments = cv2.moments(thresh)
cX = (moments["m10"] / moments["m00"])/smol.shape[1]
cY = (moments["m01"] / moments["m00"])/smol.shape[0]
prevx = posx
prevy = posy
posx = posx * pos_alpha + cX * (1.0-pos_alpha)
posy = posy * pos_alpha + cY * (1.0-pos_alpha)
velocity = math.sqrt((prevx-posx) * (prevx-posx) + (prevy - posy) * (prevy - posy))
running_count = running_count * pos_alpha + count * (1.0 - pos_alpha)
out.write("{}\t{}\t{}\t{}\t{}\n".format(frame_number/30.0,posx,posy,running_count,velocity))
# Calculate new BG
bg_float = bg_float * bg_alpha + gray * (1.0 - bg_alpha)
bg = bg_float.astype(np.uint8)
# Draw
#cv2.circle(smol, (int(posx*smol.shape[1]), int(posy*smol.shape[0])), 3, (255,0,0),6)
# Show Results
# cv2.imshow("thresh", cv2.resize(thresh, (int(src.shape[1]/2.0), int(src.shape[0]/2.0))))
# cv2.imshow("smol", cv2.resize(smol, (int(src.shape[1]/2.0), int(src.shape[0]/2.0))))
# key = cv2.waitKey(1)
# if key == 27:
# break
frame_number += 1
print(frame_number)
cap.release()
cv2.destroyAllWindows()