mirror of
https://github.com/storytold/storyteller-ml.git
synced 2026-10-16 00:13:07 +00:00
Add MocapNET
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
#Written by Ammar Qammaz a.k.a AmmarkoV - 2020
|
||||
# This bash script uses gnuplot and R so make sure to :
|
||||
# sudo apt-get install gnuplot r-base
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd "$DIR"
|
||||
|
||||
ORIG_DIR=`pwd`
|
||||
|
||||
function getStatistics
|
||||
{
|
||||
#use R to generate statistics
|
||||
#sudo apt-get install r-base
|
||||
R -q -e "x <- read.csv('$1', header = F); summary(x); sd(x[ , 1])" > $2
|
||||
cat $1 | wc -l >> $2
|
||||
}
|
||||
|
||||
|
||||
IN="$1"
|
||||
OUTPUT_IMAGE="AllDistancesFrequency_$2.png"
|
||||
echo "plotAllJointsDistanceFrequency.sh $IN $OUTPUT_IMAGE"
|
||||
|
||||
getStatistics $IN $IN-statsraw.txt
|
||||
cat $IN-statsraw.txt | grep -E 'Min|Qu|Median|Mean|Max' > $IN-stats.txt
|
||||
STATS=`cat $IN-stats.txt`
|
||||
MEAN=`cat $IN-stats.txt | grep "Mean" | cut -d':' -f2 `
|
||||
MEDIAN=`cat $IN-stats.txt | grep "Median" | cut -d':' -f2 `
|
||||
MAXIMUM=`cat $IN-stats.txt | grep "Max" | cut -d':' -f2 `
|
||||
PLACETEXT=`cat $IN-stats.txt | grep "3rd" | cut -d':' -f2 `
|
||||
|
||||
LOW_LIMIT="50";
|
||||
LIMIT="150";
|
||||
NUMBER_OF_RECORDS=`wc -l $1 | cut -d' ' -f1`
|
||||
|
||||
GNUPLOT_CMD="set terminal png; \
|
||||
set output \"$OUTPUT_IMAGE\"; set yrange [0:1];\
|
||||
set title \"Frequency precision diagram $IN \";\
|
||||
set xlabel \"Distance Of Joints(mm)\"; \
|
||||
set ylabel \"Frequency Of Value\"; \
|
||||
set arrow from $MEAN, graph 0 to $MEAN, graph 1 nohead; \
|
||||
set label \"Mean Value of $MEAN mm \" at $MEAN,0.40; \
|
||||
set arrow from $MEDIAN, graph 0 to $MEDIAN, graph 1 nohead; \
|
||||
set label \"Median Value of $MEDIAN mm \" at $MEDIAN,0.30; \
|
||||
set label \"$STATS\" at $PLACETEXT,0.85; \
|
||||
binwidth=3;\
|
||||
bin(x,width)=width*floor(x/width);\
|
||||
plot [0:] '$IN' using (bin(\$1,binwidth)):(1.0) smooth cnorm t 'smooth cumulative'"
|
||||
|
||||
|
||||
echo "WE WILL RUN "
|
||||
echo "gnuplot -e \"$GNUPLOT_CMD\""
|
||||
echo " "
|
||||
echo " "
|
||||
|
||||
|
||||
gnuplot -e "$GNUPLOT_CMD"
|
||||
|
||||
rm $IN-statsraw.txt
|
||||
rm $IN-stats.txt
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
#Written by Ammar Qammaz a.k.a AmmarkoV - 2020
|
||||
|
||||
|
||||
import h5py
|
||||
import numpy as np
|
||||
import csv
|
||||
import os
|
||||
import sys
|
||||
|
||||
from scipy.spatial import procrustes
|
||||
from scipy.linalg import orthogonal_procrustes
|
||||
|
||||
|
||||
#Taken from https://github.com/una-dinosauria/3d-pose-baseline/blob/master/src/procrustes.py
|
||||
def compute_similarity_transform(X, Y, compute_optimal_scale=False):
|
||||
"""
|
||||
A port of MATLAB's `procrustes` function to Numpy.
|
||||
Adapted from http://stackoverflow.com/a/18927641/1884420
|
||||
Args
|
||||
X: array NxM of targets, with N number of points and M point dimensionality
|
||||
Y: array NxM of inputs
|
||||
compute_optimal_scale: whether we compute optimal scale or force it to be 1
|
||||
Returns:
|
||||
d: squared error after transformation
|
||||
Z: transformed Y
|
||||
T: computed rotation
|
||||
b: scaling
|
||||
c: translation
|
||||
"""
|
||||
|
||||
muX = X.mean(0)
|
||||
muY = Y.mean(0)
|
||||
|
||||
X0 = X - muX
|
||||
Y0 = Y - muY
|
||||
|
||||
ssX = (X0**2.).sum()
|
||||
ssY = (Y0**2.).sum()
|
||||
|
||||
# centred Frobenius norm
|
||||
normX = np.sqrt(ssX)
|
||||
normY = np.sqrt(ssY)
|
||||
|
||||
# scale to equal (unit) norm
|
||||
X0 = X0 / normX
|
||||
Y0 = Y0 / normY
|
||||
|
||||
# optimum rotation matrix of Y
|
||||
A = np.dot(X0.T, Y0)
|
||||
U,s,Vt = np.linalg.svd(A,full_matrices=False)
|
||||
V = Vt.T
|
||||
T = np.dot(V, U.T)
|
||||
|
||||
# Make sure we have a rotation
|
||||
detT = np.linalg.det(T)
|
||||
V[:,-1] *= np.sign( detT )
|
||||
s[-1] *= np.sign( detT )
|
||||
T = np.dot(V, U.T)
|
||||
|
||||
traceTA = s.sum()
|
||||
|
||||
if compute_optimal_scale: # Compute optimum scaling of Y.
|
||||
b = traceTA * normX / normY
|
||||
d = 1 - traceTA**2
|
||||
Z = normX*traceTA*np.dot(Y0, T) + muX
|
||||
else: # If no scaling allowed
|
||||
b = 1
|
||||
d = 1 + ssY/ssX - 2 * traceTA * normY / normX
|
||||
Z = normY*np.dot(Y0, T) + muX
|
||||
|
||||
c = muX - b*np.dot(muY, T)
|
||||
|
||||
return d, Z, T, b, c
|
||||
|
||||
|
||||
|
||||
|
||||
def pointListsReturnAvgDistance(A,B):
|
||||
numberOfPoints=A.shape[0]
|
||||
if (A.shape[0]!=B.shape[0]):
|
||||
print("Error comparing point lists of different length")
|
||||
return inf
|
||||
|
||||
distance=0.0
|
||||
for i in range(0,numberOfPoints):
|
||||
#---------
|
||||
xA=A[i][0]
|
||||
yA=A[i][1]
|
||||
zA=A[i][2]
|
||||
#---------
|
||||
xB=B[i][0]
|
||||
yB=B[i][1]
|
||||
zB=B[i][2]
|
||||
#---------
|
||||
xAB=xA-xB
|
||||
yAB=yA-yB
|
||||
zAB=zA-zB
|
||||
|
||||
#Pythagorean theorem for 3 dimensions
|
||||
#distance = squareRoot( xAB^2 + yAB^2 + zAB^2 )
|
||||
distance+=np.sqrt( (xAB*xAB) + (yAB*yAB) + (zAB*zAB) )
|
||||
return distance/numberOfPoints
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,622 @@
|
||||
#!/usr/bin/env python3
|
||||
#Written by Ammar Qammaz a.k.a AmmarkoV - 2020
|
||||
|
||||
from align2DPoints import pointListsReturnAvgDistance,compute_similarity_transform
|
||||
from drawPointClouds import findJointID,get3DDistance,setupDrawing,drawLimbDimensions,drawLimbError,drawFrameError,drawAfterEndOfComparison
|
||||
from writeCSVResults import writeCSVFileResults,appendRAWResultsForGNUplot
|
||||
|
||||
import numpy as np
|
||||
import gc
|
||||
import os
|
||||
import sys
|
||||
import csv
|
||||
import time
|
||||
import array
|
||||
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.animation as animation
|
||||
from mpl_toolkits.mplot3d import axes3d, Axes3D
|
||||
|
||||
class bcolors:
|
||||
HEADER = '\033[95m'
|
||||
OKBLUE = '\033[94m'
|
||||
OKGREEN = '\033[92m'
|
||||
WARNING = '\033[93m'
|
||||
FAIL = '\033[91m'
|
||||
ENDC = '\033[0m'
|
||||
BOLD = '\033[1m'
|
||||
UNDERLINE = '\033[4m'
|
||||
|
||||
#I have added a seperate list with the joints we want to compare
|
||||
#to avoid the weird parent lists when you remove one joint
|
||||
JOINTS_TO_COMPARE=list()
|
||||
#JOINTS_TO_COMPARE.append('Nose') #0
|
||||
JOINTS_TO_COMPARE.append('Neck') #1
|
||||
JOINTS_TO_COMPARE.append('RShoulder') #2
|
||||
JOINTS_TO_COMPARE.append('RElbow') #3
|
||||
JOINTS_TO_COMPARE.append('RWrist') #4
|
||||
JOINTS_TO_COMPARE.append('LShoulder') #5
|
||||
JOINTS_TO_COMPARE.append('LElbow') #6
|
||||
JOINTS_TO_COMPARE.append('LWrist') #7
|
||||
JOINTS_TO_COMPARE.append('MidHip') #8
|
||||
JOINTS_TO_COMPARE.append('RHip') #9
|
||||
JOINTS_TO_COMPARE.append('RKnee') #10
|
||||
JOINTS_TO_COMPARE.append('RAnkle') #11
|
||||
JOINTS_TO_COMPARE.append('LHip') #12
|
||||
JOINTS_TO_COMPARE.append('LKnee') #13
|
||||
JOINTS_TO_COMPARE.append('LAnkle') #14
|
||||
|
||||
|
||||
#These are our labels they have to match what we want to process
|
||||
#If you don't want something to be part of the measurment remove it from here
|
||||
#as well as from the JOINT_PARENTS list
|
||||
#---------------------------------------------------------------------
|
||||
JOINT_LABELS=list()
|
||||
JOINT_LABELS.append('Nose') #0
|
||||
JOINT_LABELS.append('Neck') #1
|
||||
JOINT_LABELS.append('RShoulder') #2
|
||||
JOINT_LABELS.append('RElbow') #3
|
||||
JOINT_LABELS.append('RWrist') #4
|
||||
JOINT_LABELS.append('LShoulder') #5
|
||||
JOINT_LABELS.append('LElbow') #6
|
||||
JOINT_LABELS.append('LWrist') #7
|
||||
JOINT_LABELS.append('MidHip') #8
|
||||
JOINT_LABELS.append('RHip') #9
|
||||
JOINT_LABELS.append('RKnee') #10
|
||||
JOINT_LABELS.append('RAnkle') #11
|
||||
JOINT_LABELS.append('LHip') #12
|
||||
JOINT_LABELS.append('LKnee') #13
|
||||
JOINT_LABELS.append('LAnkle') #14
|
||||
JOINT_LABELS.append('REye') #15
|
||||
JOINT_LABELS.append('LEye') #16
|
||||
JOINT_LABELS.append('REar') #17
|
||||
JOINT_LABELS.append('LEar') #18
|
||||
JOINT_LABELS.append('LBigToe') #19
|
||||
JOINT_LABELS.append('LSmallToe') #20
|
||||
JOINT_LABELS.append('LHeel') #21
|
||||
JOINT_LABELS.append('RBigToe') #22
|
||||
JOINT_LABELS.append('RSmallToe') #23
|
||||
JOINT_LABELS.append('RHeel') #24
|
||||
|
||||
|
||||
|
||||
#These are our parents they have to match JOINT_LABELS
|
||||
#If you don't want something to be part of the measurment remove it from here
|
||||
#as well as from the JOINT_LABELS list
|
||||
#---------------------------------------------------------------------
|
||||
JOINT_PARENTS=list()
|
||||
JOINT_PARENTS.append(findJointID("Neck",JOINT_LABELS)) #0 Parent of Nose is Neck
|
||||
JOINT_PARENTS.append(findJointID("MidHip",JOINT_LABELS)) #1 Parent of Neck is MidHip
|
||||
JOINT_PARENTS.append(findJointID("Neck",JOINT_LABELS)) #2 Parent of RShoulder is Neck
|
||||
JOINT_PARENTS.append(findJointID("RShoulder",JOINT_LABELS)) #3 Parent of RElbow is RShoulder
|
||||
JOINT_PARENTS.append(findJointID("RElbow",JOINT_LABELS)) #4 etc ...
|
||||
JOINT_PARENTS.append(findJointID("Neck",JOINT_LABELS)) #5
|
||||
JOINT_PARENTS.append(findJointID("LShoulder",JOINT_LABELS)) #6
|
||||
JOINT_PARENTS.append(findJointID("LElbow",JOINT_LABELS)) #7
|
||||
JOINT_PARENTS.append(findJointID("MidHip",JOINT_LABELS)) #8
|
||||
JOINT_PARENTS.append(findJointID("MidHip",JOINT_LABELS)) #9
|
||||
JOINT_PARENTS.append(findJointID("RHip",JOINT_LABELS)) #10
|
||||
JOINT_PARENTS.append(findJointID("RKnee",JOINT_LABELS)) #11
|
||||
JOINT_PARENTS.append(findJointID("MidHip",JOINT_LABELS)) #12
|
||||
JOINT_PARENTS.append(findJointID("LHip",JOINT_LABELS)) #13
|
||||
JOINT_PARENTS.append(findJointID("LKnee",JOINT_LABELS)) #14
|
||||
JOINT_PARENTS.append(findJointID("Nose",JOINT_LABELS)) #15
|
||||
JOINT_PARENTS.append(findJointID("Nose",JOINT_LABELS)) #16
|
||||
JOINT_PARENTS.append(findJointID("Nose",JOINT_LABELS)) #17
|
||||
JOINT_PARENTS.append(findJointID("Nose",JOINT_LABELS)) #18
|
||||
JOINT_PARENTS.append(findJointID("LAnkle",JOINT_LABELS)) #19
|
||||
JOINT_PARENTS.append(findJointID("LAnkle",JOINT_LABELS)) #20
|
||||
JOINT_PARENTS.append(findJointID("LAnkle",JOINT_LABELS)) #21
|
||||
JOINT_PARENTS.append(findJointID("RAnkle",JOINT_LABELS)) #22
|
||||
JOINT_PARENTS.append(findJointID("RAnkle",JOINT_LABELS)) #23
|
||||
JOINT_PARENTS.append(findJointID("RAnkle",JOINT_LABELS)) #24
|
||||
|
||||
|
||||
#These are our labels that based on JOINT_PARENTS auto-create the appropriate labels
|
||||
#---------------------------------------------------------------------
|
||||
JOINT_PARENT_LABELS=list()
|
||||
for i in range(0,len(JOINT_LABELS)):
|
||||
JOINT_PARENT_LABELS.append(JOINT_LABELS[JOINT_PARENTS[i]])
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
|
||||
def checkIfFileExists(filename):
|
||||
return os.path.isfile(filename)
|
||||
|
||||
def convert_bytes(num):
|
||||
"""
|
||||
this function will convert bytes to MB.... GB... etc
|
||||
"""
|
||||
step_unit = 1000.0 #1024 bad the size
|
||||
|
||||
for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
|
||||
if num < step_unit:
|
||||
return "%3.1f %s" % (num, x)
|
||||
num /= step_unit
|
||||
|
||||
def getNumberOfLines(filename):
|
||||
print("Counting number of lines in file ",filename)
|
||||
with open(filename) as f:
|
||||
return sum(1 for line in f)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
def readCSVFile(filename,memPercentage,csvDelimiter,useHalfFloats,groupOutput):
|
||||
print("CSV file :",filename,"..\n")
|
||||
|
||||
if (not checkIfFileExists(filename)):
|
||||
print( bcolors.WARNING + "Input file "+filename+" does not exist, cannot read ground truth.." + bcolors.ENDC)
|
||||
print("Current Directory was "+os.getcwd())
|
||||
sys.exit(0)
|
||||
start = time.time()
|
||||
|
||||
dtypeSelected=np.dtype(np.float32)
|
||||
dtypeSelectedByteSize=int(dtypeSelected.itemsize)
|
||||
if (useHalfFloats):
|
||||
dtypeSelected=np.dtype(np.float16)
|
||||
dtypeSelectedByteSize=int(dtypeSelected.itemsize)
|
||||
|
||||
progress=0.0
|
||||
sampleNumber=0
|
||||
receivedHeader=0
|
||||
inputNumberOfColumns=0
|
||||
|
||||
inputLabels=list()
|
||||
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
numberOfSamplesInput=getNumberOfLines(filename)-2
|
||||
print(" Input file has ",numberOfSamplesInput," training samples\n")
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
numberOfSamples = numberOfSamplesInput
|
||||
numberOfSamplesLimit=int(numberOfSamples*memPercentage)
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
if (memPercentage==0.0):
|
||||
print("readGroundTruthFile was asked to occupy 0 memory so this probably means we just want one record")
|
||||
numberOfSamplesLimit=2
|
||||
if (memPercentage>1.0):
|
||||
print("Memory Limit will be interpreted as a raw value..")
|
||||
numberOfSamplesLimit=int(memPercentage)
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
thisInput = array.array('f')
|
||||
#---------------------------------
|
||||
|
||||
fi = open(filename, "r")
|
||||
readerIn = csv.reader( fi , delimiter=csvDelimiter, skipinitialspace=True)
|
||||
for rowIn in readerIn:
|
||||
#------------------------------------------------------
|
||||
if (not receivedHeader): #use header to get labels
|
||||
#------------------------------------------------------
|
||||
inputNumberOfColumns=len(rowIn)
|
||||
|
||||
#Make sure CSV files that end with delimiter are correctly handled..
|
||||
if (inputNumberOfColumns>0):
|
||||
if (rowIn[inputNumberOfColumns-1]==''):
|
||||
inputNumberOfColumns=inputNumberOfColumns-1
|
||||
#-----------------------------------------------------
|
||||
inputLabels = list(rowIn[i] for i in range(0,inputNumberOfColumns) )
|
||||
print("Number of Input elements : ",len(inputLabels))
|
||||
#------------------------------------------------------
|
||||
|
||||
if (memPercentage==0):
|
||||
print("Will only return labels\n")
|
||||
return {'labels':inputLabels};
|
||||
|
||||
|
||||
#i=0
|
||||
#print("class Input(Enum):")
|
||||
#for label in inputLabels:
|
||||
# print(" ",label," = ",i," #",int(i/3))
|
||||
# print(" ",label,"=",int(i/3))
|
||||
# i=i+1
|
||||
|
||||
#---------------------------------
|
||||
# Allocate Lists
|
||||
#---------------------------------
|
||||
for i in range(inputNumberOfColumns):
|
||||
thisInput.append(0.0)
|
||||
#---------------------------------
|
||||
|
||||
|
||||
#---------------------------------
|
||||
# Allocate Numpy Arrays
|
||||
#---------------------------------
|
||||
inputSize=0
|
||||
startCompressed=0
|
||||
|
||||
inputSize=inputSize+inputNumberOfColumns
|
||||
startCompressed=inputNumberOfColumns
|
||||
|
||||
npInputBytesize=0+numberOfSamplesLimit * inputSize * dtypeSelectedByteSize
|
||||
print(" Input file on disk has a shape of [",numberOfSamples,",",inputSize,"]")
|
||||
print(" Input we will read has a shape of [",numberOfSamplesLimit,",",inputSize,"]")
|
||||
print(" Input will occupy ",convert_bytes(npInputBytesize)," of RAM\n")
|
||||
npInput = np.full([numberOfSamplesLimit,inputSize],fill_value=0,dtype=dtypeSelected,order='C')
|
||||
#----------------------------------------------------------------------------------------------------------
|
||||
receivedHeader=1
|
||||
#sys.exit(0)
|
||||
else:
|
||||
#-------------------------------------------
|
||||
# First convert our string INPUT to floats
|
||||
#-------------------------------------------
|
||||
for i in range(inputNumberOfColumns):
|
||||
thisInput[i]=float(rowIn[i])
|
||||
#-------------------------------------------
|
||||
for num in range(0,inputNumberOfColumns):
|
||||
npInput[sampleNumber,num]=float(thisInput[num]);
|
||||
#-------------------------------------------
|
||||
sampleNumber=sampleNumber+1
|
||||
|
||||
if (numberOfSamples>0):
|
||||
progress=sampleNumber/numberOfSamplesLimit
|
||||
|
||||
if (sampleNumber%1000==0) :
|
||||
progressString = "%0.2f"%float(100*progress)
|
||||
print("\rReading from disk (",sampleNumber,") - ",progressString," % \r", end="", flush=True)
|
||||
|
||||
if (numberOfSamplesLimit<=sampleNumber):
|
||||
print("\rStopping reading file to obey memory limit given by parameter --mem ",memPercentage,"\n")
|
||||
break
|
||||
#-------------------------------------------
|
||||
fi.close()
|
||||
del readerIn
|
||||
gc.collect()
|
||||
|
||||
|
||||
print("\n read, Samples: ",sampleNumber,", was expecting ",numberOfSamples," samples\n")
|
||||
print(npInput.shape)
|
||||
|
||||
totalNumberOfBytes=npInput.nbytes;
|
||||
totalNumberOfGigaBytes=totalNumberOfBytes/1073741824;
|
||||
print("Size Occupied by data = ",totalNumberOfGigaBytes," GB \n")
|
||||
|
||||
end = time.time()
|
||||
print("Time elapsed : ",(end-start)/60," mins")
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
if (groupOutput==0):
|
||||
#New better dictionary
|
||||
output = dict()
|
||||
for i in range(0,len(inputLabels)):
|
||||
lowerCaseName = inputLabels[i].lower()
|
||||
#print("Joint ",lowerCaseName)
|
||||
output[lowerCaseName]=list()
|
||||
for frameID in range(0,len(npInput)):
|
||||
output[lowerCaseName].append(npInput[frameID][i])
|
||||
return output
|
||||
else:
|
||||
#This is the old dictionary way (better for tensorflow training)
|
||||
return {'label':inputLabels, 'body':npInput };
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#Main() program
|
||||
#-------------------------------------
|
||||
averageErrorDistances=list()
|
||||
averageMotionEstimationDistancesBetweenFrames=list()
|
||||
|
||||
|
||||
#These are labeling infos
|
||||
#Used to correctly pack the results
|
||||
#-------------------------
|
||||
subject="S?"
|
||||
action="Unknown"
|
||||
subaction="?"
|
||||
camera="?"
|
||||
actionLabel="?"
|
||||
addedPixelNoise=0
|
||||
|
||||
#These are configuration parameters
|
||||
#-------------------------------------------------------------------
|
||||
everyNFrames=0 # Run on every frame of the CSV files by default
|
||||
drawPlot=0 # Don't Draw plot by default
|
||||
doProcrustes=1 # Do procrustes analysis
|
||||
procrustesScale=1 # Let procrustes also scale the point clouds
|
||||
ground="h36.csv" # A default h36.csv filename
|
||||
groundDelim=',' # By default the h36.csv has a ',' delimiter
|
||||
output="out.csv" # A default output filename
|
||||
outputDelim=';' # Damien's output has ';' delimiters, mine has ','
|
||||
ourScaleX=1.0
|
||||
ourScaleY=1.0
|
||||
ourScaleZ=1.0
|
||||
|
||||
|
||||
#Modifiers on comparisons..
|
||||
#------------------------------------------------------------------------------------------------
|
||||
if (len(sys.argv)>1):
|
||||
#print('Argument List:', str(sys.argv))
|
||||
for i in range(0, len(sys.argv)):
|
||||
if (sys.argv[i]=="--ourscale"):
|
||||
ourScaleX=float(sys.argv[i+1])
|
||||
ourScaleY=float(sys.argv[i+2])
|
||||
ourScaleZ=float(sys.argv[i+3])
|
||||
if (sys.argv[i]=="--draw"):
|
||||
drawPlot=1
|
||||
if (sys.argv[i]=="--from"):
|
||||
output=sys.argv[i+1]
|
||||
outputDelim=sys.argv[i+2]
|
||||
if (sys.argv[i]=="--ground"):
|
||||
ground=sys.argv[i+1]
|
||||
groundDelim=sys.argv[i+2]
|
||||
if (sys.argv[i]=="--noprocrustes"):
|
||||
doProcrustes=0
|
||||
if (sys.argv[i]=="--every"):
|
||||
everyNFrames=int(sys.argv[i+1])
|
||||
if (sys.argv[i]=="--info"):
|
||||
subject=sys.argv[i+1]
|
||||
action=sys.argv[i+2]
|
||||
camera=sys.argv[i+3]
|
||||
addedPixelNoise=float(sys.argv[i+4])
|
||||
print("\n Infos Set ",sys.argv[i+1])
|
||||
actionLabel=action
|
||||
s=actionLabel.split("-")
|
||||
subaction=s[1]
|
||||
action=s[0]
|
||||
action=action.replace('/','')
|
||||
subaction=subaction.replace('/','')
|
||||
actionLabel=actionLabel.replace('/','')
|
||||
camera=camera.replace('/','')
|
||||
|
||||
print("Subject ",subject," Action ",action," Subaction ",subaction," Camera ",camera)
|
||||
#------------------------------------------------------------------------------------------------
|
||||
|
||||
if (drawPlot):
|
||||
print("Using matplotlib:",matplotlib.__version__)
|
||||
# === Plot and animate ===
|
||||
fig = plt.figure()
|
||||
fig.set_size_inches(19.2, 10.8, forward=True)
|
||||
|
||||
ax = fig.add_subplot(2, 2, 1, projection='3d')
|
||||
ax2 = fig.add_subplot(2, 2, 2)
|
||||
ax3 = fig.add_subplot(2, 2, 3)
|
||||
ax4 = fig.add_subplot(2, 2, 4)
|
||||
fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95)
|
||||
|
||||
ax.set_xlabel('X Axis')
|
||||
ax.set_ylabel('Y Axis')
|
||||
ax.set_zlabel('Z Axis')
|
||||
ax.view_init(90, 90)
|
||||
|
||||
|
||||
|
||||
out=readCSVFile(output,1.0,outputDelim,0,0)
|
||||
ground=readCSVFile(ground,1.0,groundDelim,0,0)
|
||||
|
||||
print("Output number of keys : %u " % len(out.keys()) )
|
||||
print("GroundTruth number of keys : %u " % len(ground.keys()) )
|
||||
|
||||
if ( len(out.keys()) != len(ground.keys()) ):
|
||||
print(bcolors.WARNING,"Inconsistent keys",bcolors.ENDC)
|
||||
#sys.exit(0)
|
||||
|
||||
|
||||
totalError=0.0
|
||||
totalSamples=0
|
||||
numberOfJointsToCompare = len(JOINTS_TO_COMPARE)
|
||||
numberOfFrames = len(out['3dx_nose'])
|
||||
|
||||
|
||||
#-----------------------
|
||||
alljointDistances=list()
|
||||
#-----------------------
|
||||
jointDistance=list()
|
||||
for jointID in range(0,numberOfJointsToCompare):
|
||||
jointDistance.append(list())
|
||||
#-----------------------
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------------------------
|
||||
if (len(sys.argv)>1):
|
||||
#print('Argument List:', str(sys.argv))
|
||||
for i in range(0, len(sys.argv)):
|
||||
if (sys.argv[i]=="--frames"):
|
||||
numberOfFrames=int(sys.argv[i+1])
|
||||
#------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#We want to loop over every frame that we loaded..
|
||||
for frameID in range(0,numberOfFrames):
|
||||
#In many papers they run the comparison ever N frames
|
||||
#So depending on this setting you can actually execute
|
||||
#the comparison computation everyNFrames
|
||||
#-----------------------------------------------------
|
||||
if ( (everyNFrames==0) or (frameID%everyNFrames==0) ):
|
||||
executeComputations=1
|
||||
else:
|
||||
executeComputations=0
|
||||
#-----------------------------------------------------
|
||||
|
||||
if (executeComputations==1):
|
||||
ourPointCloud=list()
|
||||
h36PointCloud=list()
|
||||
xlineStart=list()
|
||||
xlineEnd=list()
|
||||
ylineStart=list()
|
||||
ylineEnd=list()
|
||||
zlineStart=list()
|
||||
zlineEnd=list()
|
||||
|
||||
#Align midhip to make sure we start from a sane position
|
||||
offsetX=(ourScaleX*out['3dx_midhip'][frameID])-ground['3dx_midhip'][frameID]
|
||||
offsetY=(ourScaleY*out['3dy_midhip'][frameID])-ground['3dy_midhip'][frameID]
|
||||
offsetZ=(ourScaleZ*out['3dz_midhip'][frameID])-ground['3dz_midhip'][frameID]
|
||||
|
||||
for jointIDUnresolved in range(0,numberOfJointsToCompare):
|
||||
#------------------------------------------------------------------
|
||||
#Our Joints to compare list has a different indexing
|
||||
jointID = findJointID(JOINTS_TO_COMPARE[jointIDUnresolved],JOINT_LABELS)
|
||||
if (jointID==-1):
|
||||
print(bcolors.WARNING,"Failed to resolve joint: ",JOINTS_TO_COMPARE[jointIDUnresolved],bcolors.ENDC)
|
||||
sys.exit(0)
|
||||
#-----------------------------------------------------------
|
||||
jointKey = JOINT_LABELS[jointID].lower()
|
||||
parentKey = JOINT_PARENT_LABELS[jointID].lower()
|
||||
#print("Frame %u / Key %s ( prev %s ) "% (frameID,jointKey,parentKey) )
|
||||
|
||||
#------------------------------------------------------------------
|
||||
#We select the joint and push it to the point cloud for this particular frame
|
||||
xM=(ourScaleX*out['3dx_%s' % jointKey][frameID])-offsetX
|
||||
yM=(ourScaleY*out['3dy_%s' % jointKey][frameID])-offsetY
|
||||
zM=(ourScaleZ*out['3dz_%s' % jointKey][frameID])-offsetZ
|
||||
ourPointCloud.append([xM,yM,zM])
|
||||
|
||||
#These lineStarts/lineEnds and parentKeys help draw lines connecting
|
||||
#the dots in skeletons
|
||||
xParentM=(ourScaleX*out['3dx_%s' % parentKey][frameID])-offsetX
|
||||
yParentM=(ourScaleY*out['3dy_%s' % parentKey][frameID])-offsetY
|
||||
zParentM=(ourScaleZ*out['3dz_%s' % parentKey][frameID])-offsetZ
|
||||
xlineStart.append(xM)
|
||||
ylineStart.append(yM)
|
||||
zlineStart.append(zM)
|
||||
xlineEnd.append(xParentM)
|
||||
ylineEnd.append(yParentM)
|
||||
zlineEnd.append(zParentM)
|
||||
#------------------------------------------------------------------
|
||||
#We select the h36 joint and push it to the point cloud for this particular frame
|
||||
xH=ground['3dx_%s' % jointKey][frameID]
|
||||
yH=ground['3dy_%s' % jointKey][frameID]
|
||||
zH=ground['3dz_%s' % jointKey][frameID]
|
||||
h36PointCloud.append([xH,yH,zH])
|
||||
|
||||
#These lineStarts/lineEnds and parentKeys help draw lines connecting
|
||||
#the dots in skeletons
|
||||
xParentH=ground['3dx_%s' % parentKey][frameID]
|
||||
yParentH=ground['3dy_%s' % parentKey][frameID]
|
||||
zParentH=ground['3dz_%s' % parentKey][frameID]
|
||||
xlineStart.append(xH)
|
||||
ylineStart.append(yH)
|
||||
zlineStart.append(zH)
|
||||
xlineEnd.append(xParentH)
|
||||
ylineEnd.append(yParentH)
|
||||
zlineEnd.append(zParentH)
|
||||
#------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------
|
||||
|
||||
#We package our lists in numpy to be able to easily manipulate them
|
||||
#------------------------------------------------------------------
|
||||
np_h36PointCloud = np.asarray(h36PointCloud,dtype=np.float32)
|
||||
np_ourPointCloud = np.asarray(ourPointCloud,dtype=np.float32)
|
||||
|
||||
|
||||
#This is the main comparison after using procrustes and transforming the pointcloud
|
||||
#to align it or when just doing plain old euclidean distance
|
||||
#--------------------------------------------------------------------------------
|
||||
if (doProcrustes):
|
||||
d, Z, T, b, c = compute_similarity_transform(np_h36PointCloud,np_ourPointCloud,compute_optimal_scale=procrustesScale)
|
||||
#disparity=np.sqrt(d) #d: squared error after transformation
|
||||
#print("compute_similarity_transform : ",disparity)
|
||||
|
||||
#Our point cloud is brought to the same translation and rotation as h36 point cloud
|
||||
np_ourPointCloud = (b*np_ourPointCloud.dot(T))+c
|
||||
disparity = pointListsReturnAvgDistance(np_ourPointCloud,np_h36PointCloud)
|
||||
else:
|
||||
disparity = pointListsReturnAvgDistance(np_ourPointCloud,np_h36PointCloud)
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
#We want to calculate Mean Per Joint Position Error (MPJPE)
|
||||
#to do so we have to calculate the position error of each of the joints in our point cloud
|
||||
#sum it up and then divide it through the number of samples
|
||||
for jID in range(0,numberOfJointsToCompare):
|
||||
#------------------------------------------------------------------
|
||||
#We use the np_ourPointCloud and np_h36PointCloud so that if procrustes analysis is enabled it will be used..
|
||||
perJointDisparity=get3DDistance(
|
||||
np_ourPointCloud[jID][0],np_ourPointCloud[jID][1],np_ourPointCloud[jID][2],
|
||||
np_h36PointCloud[jID][0],np_h36PointCloud[jID][1],np_h36PointCloud[jID][2]
|
||||
)
|
||||
totalError+=perJointDisparity
|
||||
totalSamples+=1
|
||||
#We also keep every sample on a list to do an analysis in the end
|
||||
alljointDistances.append(perJointDisparity)
|
||||
jointDistance[jID].append(perJointDisparity)
|
||||
#------------------------------------------------------------------
|
||||
|
||||
print("Frame %u / Disparity %f " % (frameID,disparity))
|
||||
averageErrorDistances.append(disparity)
|
||||
|
||||
#Draw the plot that summarizes what is happening if --draw is given
|
||||
if (drawPlot):
|
||||
drawAfterEndOfComparison(
|
||||
JOINTS_TO_COMPARE,
|
||||
JOINT_LABELS,
|
||||
JOINT_PARENTS,
|
||||
JOINT_PARENT_LABELS,
|
||||
plt,ax,ax2,ax3,ax4,
|
||||
xlineStart,xlineEnd,
|
||||
ylineStart,ylineEnd,
|
||||
zlineStart,zlineEnd,
|
||||
np_ourPointCloud,
|
||||
np_h36PointCloud,
|
||||
frameID,
|
||||
numberOfFrames,
|
||||
everyNFrames,
|
||||
disparity,
|
||||
averageErrorDistances,
|
||||
averageMotionEstimationDistancesBetweenFrames
|
||||
)
|
||||
|
||||
#Since this always appends results be sure to remove the gnuplot.raw
|
||||
#file before starting a new session..
|
||||
appendRAWResultsForGNUplot("gnuplot.raw",alljointDistances)
|
||||
|
||||
#Final results we want is Mean Per Joint Position Error (MPJPE) so we rely on the perJointDisparities etc..
|
||||
#The result unit depends on the input to the script but it should be in millimeters for MocapNET output
|
||||
#to change units you can use the --ourscale X Y Z commandline parameter, however millimeters of accuracy
|
||||
#is the norm for 3D pose estimation work..
|
||||
|
||||
print("\nMean Per Joint Error for ",totalSamples," samples is ",totalError/totalSamples)
|
||||
median = np.median(alljointDistances)
|
||||
mean = np.mean(alljointDistances)
|
||||
average = np.average(alljointDistances)
|
||||
std = np.std(alljointDistances)
|
||||
var = np.var(alljointDistances)
|
||||
print("Mean is ",mean," Std is ",std," Var is ",var)
|
||||
|
||||
|
||||
|
||||
writeHeader=0
|
||||
if not os.path.exists("results.csv"):
|
||||
writeHeader=1
|
||||
writeCSVFileResults(
|
||||
JOINTS_TO_COMPARE,
|
||||
"results.csv",
|
||||
writeHeader,
|
||||
alljointDistances,
|
||||
jointDistance,
|
||||
numberOfJointsToCompare,
|
||||
subject,
|
||||
action,
|
||||
subaction,
|
||||
camera,
|
||||
actionLabel,
|
||||
addedPixelNoise
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
if (drawPlot):
|
||||
os.system("ffmpeg -framerate 25 -i p%05d.png -s 1920x1080 -y -r 30 -pix_fmt yuv420p -threads 8 lastcomp.mp4 && rm ./p*.png") #
|
||||
sys.exit(0)
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/env python3
|
||||
#Written by Ammar Qammaz a.k.a AmmarkoV - 2020
|
||||
|
||||
import numpy as np
|
||||
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.animation as animation
|
||||
|
||||
from mpl_toolkits.mplot3d import axes3d, Axes3D
|
||||
print("Using matplotlib:",matplotlib.__version__)
|
||||
|
||||
|
||||
def pointListReturnXYZListForScatterPlot(A):
|
||||
numberOfPoints=A.shape[0]
|
||||
xs=list()
|
||||
ys=list()
|
||||
zs=list()
|
||||
for i in range(0,numberOfPoints):
|
||||
xs.append(A[i][0])
|
||||
ys.append(A[i][1])
|
||||
zs.append(A[i][2])
|
||||
return xs,ys,zs
|
||||
|
||||
|
||||
def setupDrawing(fig,ax,ax2,ax3,ax4):
|
||||
# === Plot and animate ===
|
||||
fig = plt.figure()
|
||||
fig.set_size_inches(19.2, 10.8, forward=True)
|
||||
|
||||
ax = fig.add_subplot(2, 2, 1, projection='3d')
|
||||
ax2 = fig.add_subplot(2, 2, 2)
|
||||
ax3 = fig.add_subplot(2, 2, 3)
|
||||
ax4 = fig.add_subplot(2, 2, 4)
|
||||
fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95)
|
||||
|
||||
ax.set_xlabel('X Axis')
|
||||
ax.set_ylabel('Y Axis')
|
||||
ax.set_zlabel('Z Axis')
|
||||
ax.view_init(90, 90)
|
||||
|
||||
|
||||
def get3DDistance(jX,jY,jZ,pX,pY,pZ):
|
||||
return np.sqrt( ((jX-pX)*(jX-pX)) + ((jY-pY)*(jY-pY)) + ((jZ-pZ)*(jZ-pZ)) )
|
||||
|
||||
def findJointID(jointName,labels):
|
||||
for i in range(0,len(labels)):
|
||||
if (jointName==labels[i]):
|
||||
return i
|
||||
print("Cannot find joint ",jointName," !")
|
||||
return -1
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
def drawLimbDimensions(JOINTS_TO_COMPARE,JOINT_LABELS,JOINT_PARENTS,JOINT_PARENT_LABELS,h36mPoints,ourPoints,numberOfJoints,ax2):
|
||||
labels = list()
|
||||
h36m_distances = list()
|
||||
mnet_distances = list()
|
||||
|
||||
for jointID in range(0,len(JOINTS_TO_COMPARE)):
|
||||
#---------------------------------------
|
||||
jointIDGlobal = findJointID(JOINTS_TO_COMPARE[jointID],JOINT_LABELS)
|
||||
jointParentID=findJointID(JOINT_PARENT_LABELS[JOINT_PARENTS[jointIDGlobal]],JOINTS_TO_COMPARE)
|
||||
#---------------------------------------
|
||||
if (jointParentID!=-1) and (jointIDGlobal!=-1):
|
||||
labels.append(JOINT_LABELS[jointIDGlobal])
|
||||
jX=h36mPoints[jointID][0]
|
||||
jY=h36mPoints[jointID][1]
|
||||
jZ=h36mPoints[jointID][2]
|
||||
pX=h36mPoints[jointParentID][0]
|
||||
pY=h36mPoints[jointParentID][1]
|
||||
pZ=h36mPoints[jointParentID][2]
|
||||
distances=get3DDistance(jX,jY,jZ,pX,pY,pZ)
|
||||
h36m_distances.append(distances)
|
||||
#---------------------------------------
|
||||
jX=ourPoints[jointID][0]
|
||||
jY=ourPoints[jointID][1]
|
||||
jZ=ourPoints[jointID][2]
|
||||
pX=ourPoints[jointParentID][0]
|
||||
pY=ourPoints[jointParentID][1]
|
||||
pZ=ourPoints[jointParentID][2]
|
||||
distances=get3DDistance(jX,jY,jZ,pX,pY,pZ)
|
||||
mnet_distances.append(distances)
|
||||
#---------------------------------------
|
||||
|
||||
#-------------------------------------------------
|
||||
x = np.arange(len(labels)) # the label locations
|
||||
width = 0.35 # the width of the bars
|
||||
|
||||
rects1 = ax2.bar(x - width/2, h36m_distances, width, label='H36M')
|
||||
rects2 = ax2.bar(x + width/2, mnet_distances, width, label='Our Method')
|
||||
|
||||
# Add some text for labels, title and custom x-axis tick labels, etc.
|
||||
ax2.set_ylim(auto=False,bottom=0,top=800)
|
||||
ax2.set_ylabel('Limb dimensions in millimeters')
|
||||
ax2.set_title('Comparison of H36M limb dimensions')
|
||||
ax2.set_xticks(x)
|
||||
ax2.set_xticklabels(labels, rotation=45, rotation_mode="anchor")
|
||||
ax2.legend()
|
||||
|
||||
#autolabel(rects1)
|
||||
#autolabel(rects2)
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
def drawLimbError(JOINTS_TO_COMPARE,JOINT_LABELS,JOINT_PARENTS,JOINT_PARENT_LABELS,h36mPoints,ourPoints,numberOfJoints,ax3):
|
||||
labels = list()
|
||||
error_distances = list()
|
||||
for jointID in range(0,len(JOINTS_TO_COMPARE)):
|
||||
#---------------------------------------
|
||||
jointIDGlobal = findJointID(JOINTS_TO_COMPARE[jointID],JOINT_LABELS)
|
||||
#---------------------------------------
|
||||
if (jointIDGlobal!=-1):
|
||||
labels.append(JOINT_LABELS[jointIDGlobal])
|
||||
jX=h36mPoints[jointID][0]
|
||||
jY=h36mPoints[jointID][1]
|
||||
jZ=h36mPoints[jointID][2]
|
||||
pX=ourPoints[jointID][0]
|
||||
pY=ourPoints[jointID][1]
|
||||
pZ=ourPoints[jointID][2]
|
||||
distances=get3DDistance(jX,jY,jZ,pX,pY,pZ)
|
||||
error_distances.append(distances)
|
||||
#---------------------------------------
|
||||
|
||||
#-------------------------------------------------
|
||||
x = np.arange(len(labels)) # the label locations
|
||||
width = 0.35 # the width of the bars
|
||||
|
||||
rects1 = ax3.bar(x - width/2, error_distances, width, label='Error in millimeters')
|
||||
|
||||
# Add some text for labels, title and custom x-axis tick labels, etc.
|
||||
ax3.set_ylim(auto=False,bottom=0,top=250)
|
||||
ax3.set_ylabel('Error in millimeters')
|
||||
ax3.set_title('Comparison of 3D estimation error')
|
||||
ax3.set_xticks(x)
|
||||
ax3.set_xticklabels(labels, rotation=45, rotation_mode="anchor")
|
||||
ax3.legend()
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
def drawFrameError(averageErrorDistances,averageMotionEstimationDistancesBetweenFrames,ax4):
|
||||
|
||||
#minimum=np.min(averageErrorDistances)
|
||||
#ax4.plot((0,len(averageErrorDistances)), (minimum,minimum),label='Minimum Error')
|
||||
|
||||
#maximum=np.max(averageErrorDistances)
|
||||
#ax4.plot((0,len(averageErrorDistances)), (maximum,maximum),label='Maximum Error')
|
||||
|
||||
#median=np.median(averageErrorDistances)
|
||||
#ax4.plot((0,len(averageErrorDistances)), (median,median),label='Median Error (%0.2f mm)'% median)
|
||||
|
||||
average=np.average(averageErrorDistances)
|
||||
ax4.plot((0,len(averageErrorDistances)), (average,average),label='Average of average errors (%0.2f mm)' % average)
|
||||
|
||||
ax4.plot(averageErrorDistances, label='Our method average error in millimeters')
|
||||
ax4.plot(averageMotionEstimationDistancesBetweenFrames, label='Distance of average joint from previous frame')
|
||||
|
||||
#ax4.set_ylim(auto=False,bottom=0,top=250)
|
||||
ax4.set_xlabel('Experiment frame number')
|
||||
ax4.set_ylabel('Millimeters')
|
||||
ax4.set_title('Average 3D estimation error per frame')
|
||||
#ax4.set_xticklabels(labels, rotation=45, rotation_mode="anchor")
|
||||
ax4.legend()
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def drawAfterEndOfComparison(
|
||||
JOINTS_TO_COMPARE,
|
||||
JOINT_LABELS,
|
||||
JOINT_PARENTS,
|
||||
JOINT_PARENT_LABELS,
|
||||
plt,ax,ax2,ax3,ax4,
|
||||
xlineStart,xlineEnd,
|
||||
ylineStart,ylineEnd,
|
||||
zlineStart,zlineEnd,
|
||||
ourPointCloud,
|
||||
h36PointCloud,
|
||||
frameID,
|
||||
numberOfFrames,
|
||||
everyNFrames,
|
||||
disparity,
|
||||
averageErrorDistances,
|
||||
averageMotionEstimationDistancesBetweenFrames
|
||||
):
|
||||
plt.cla()
|
||||
ax.cla()
|
||||
ax2.cla()
|
||||
ax3.cla()
|
||||
ax4.cla()
|
||||
|
||||
#Print Skeletons and their connected lines..
|
||||
#for i in range(0,len(xlineStart)):
|
||||
# ax.plot([xlineStart[i],xlineEnd[i]],[ylineStart[i],ylineEnd[i]],zs=[zlineStart[i],zlineEnd[i]])
|
||||
#--------------------------------------------
|
||||
xs, ys, zs = pointListReturnXYZListForScatterPlot(ourPointCloud)
|
||||
ax.scatter(xs, ys, zs)
|
||||
xs, ys, zs = pointListReturnXYZListForScatterPlot(h36PointCloud)
|
||||
ax.scatter(xs, ys, zs)
|
||||
|
||||
#Secondary plots for limb lengths etc..
|
||||
numberOfJoints = len(ourPointCloud)
|
||||
drawLimbDimensions(JOINTS_TO_COMPARE,JOINT_LABELS,JOINT_PARENTS,JOINT_PARENT_LABELS,h36PointCloud,ourPointCloud,numberOfJoints,ax2)
|
||||
drawLimbError(JOINTS_TO_COMPARE,JOINT_LABELS,JOINT_PARENTS,JOINT_PARENT_LABELS,h36PointCloud,ourPointCloud,numberOfJoints,ax3)
|
||||
drawFrameError(averageErrorDistances,averageMotionEstimationDistancesBetweenFrames,ax4)
|
||||
|
||||
#-------------------------
|
||||
ax.text2D(0.05, 0.95, "Frame %u/%u - Increment %u - Procrustes Average Error %0.2f mm"%(frameID,numberOfFrames,everyNFrames,disparity) , transform=ax.transAxes)
|
||||
#ax.text2D(0.05, 0.05, "RHand %0.2f mm / LHand %0.2f mm / RFoot %0.2f mm / LFoot %0.2f mm "%(currentDistances[4],currentDistances[7],currentDistances[11],currentDistances[14]) , transform=ax.transAxes)
|
||||
#-------------------------
|
||||
ax.set_xlim(auto=False,left=-600,right=300)
|
||||
ax.set_ylim(auto=False,bottom=-1600,top=200)
|
||||
ax.set_zlim(auto=False,bottom=2000,top=6000)
|
||||
ax.set_xlabel('X Axis')
|
||||
ax.set_ylabel('Y Axis')
|
||||
ax.set_zlabel('Z Axis')
|
||||
#-------------------------
|
||||
plt.show(block=False)
|
||||
plt.savefig('p%05u.png'%frameID)
|
||||
#fig.canvas.draw()
|
||||
plt.pause(0.001)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
#Written by Ammar Qammaz a.k.a AmmarkoV - 2020
|
||||
|
||||
import numpy as np
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
def writeCSVFileResults(
|
||||
JOINT_LABELS,
|
||||
outputFile,
|
||||
addHeader,
|
||||
globalJointDistances,
|
||||
perJointDistance,
|
||||
numberOfJoints,
|
||||
subject,
|
||||
action,
|
||||
subaction,
|
||||
camera,
|
||||
actionLabel,
|
||||
addedPixelNoise
|
||||
):
|
||||
#Write header----------------
|
||||
if (addHeader):
|
||||
file = open(outputFile,"w")
|
||||
file.write("Subject,")
|
||||
file.write("Action,")
|
||||
file.write("ActionLabel,")
|
||||
file.write("Subaction,")
|
||||
file.write("Camera,")
|
||||
file.write("Noise,")
|
||||
file.write("Global_Median,")
|
||||
#file.write("Global_Mean,")
|
||||
file.write("Global_Average,")
|
||||
file.write("Global_Std,")
|
||||
file.write("Global_Var,")
|
||||
for jointID in range(0,numberOfJoints):
|
||||
file.write("%s_Median,"%JOINT_LABELS[jointID])
|
||||
#file.write("%s_Mean,"%JOINT_LABELS[jointID])
|
||||
file.write("%s_Average,"%JOINT_LABELS[jointID])
|
||||
file.write("%s_Std,"%JOINT_LABELS[jointID])
|
||||
file.write("%s_Var"%JOINT_LABELS[jointID])
|
||||
if (jointID!=numberOfJoints-1):
|
||||
file.write(",")
|
||||
else:
|
||||
file.write("\n")
|
||||
else:
|
||||
file = open(outputFile,"a")
|
||||
#----------------------------
|
||||
|
||||
median=np.median(globalJointDistances)
|
||||
mean=np.mean(globalJointDistances)
|
||||
average=np.average(globalJointDistances)
|
||||
std=np.std(globalJointDistances)
|
||||
var=np.var(globalJointDistances)
|
||||
print("\nGlobal Median:",median," Average:",average," Std:",std,"Var:",var) #file.write(subject)
|
||||
file.write(subject)
|
||||
file.write(",")
|
||||
file.write(action)
|
||||
file.write(",")
|
||||
file.write(actionLabel)
|
||||
file.write(",")
|
||||
file.write(subaction)
|
||||
file.write(",")
|
||||
file.write(camera)
|
||||
file.write(",")
|
||||
file.write(str(addedPixelNoise))
|
||||
file.write(",")
|
||||
file.write(str(median))
|
||||
file.write(",")
|
||||
#file.write(str(mean))
|
||||
#file.write(",")
|
||||
file.write(str(average))
|
||||
file.write(",")
|
||||
file.write(str(std))
|
||||
file.write(",")
|
||||
file.write(str(var))
|
||||
file.write(",")
|
||||
|
||||
for jointID in range(0,numberOfJoints):
|
||||
median=np.median(perJointDistance[jointID])
|
||||
mean=np.mean(perJointDistance[jointID])
|
||||
average=np.average(perJointDistance[jointID])
|
||||
std=np.std(perJointDistance[jointID])
|
||||
var=np.var(perJointDistance[jointID])
|
||||
print("Joint ",JOINT_LABELS[jointID]," Median:",median," Mean:",mean," Average:",average," Std:",std,"Var:",var)
|
||||
file.write(str(median))
|
||||
file.write(",")
|
||||
#file.write(str(mean))
|
||||
#file.write(",")
|
||||
file.write(str(average))
|
||||
file.write(",")
|
||||
file.write(str(std))
|
||||
file.write(",")
|
||||
file.write(str(var))
|
||||
if (jointID!=numberOfJoints-1):
|
||||
file.write(",")
|
||||
else:
|
||||
file.write("\n")
|
||||
|
||||
file.close()
|
||||
#--------------------------------------------
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------------------------------------------------
|
||||
def appendRAWResultsForGNUplot(outputFile,globalJointDistances):
|
||||
fileHandler = open(outputFile, "a")
|
||||
for measurement in globalJointDistances:
|
||||
fileHandler.write(str(measurement))
|
||||
fileHandler.write("\n")
|
||||
fileHandler.close()
|
||||
Reference in New Issue
Block a user