Max introduced the dictionary data-type a long time ago. I have had very little experience with it other than setting and recalling custom presets, which was done with the get
message. So if we have a dict storing presets with sequences of colour information:
{
"Sequence" : {
"one" : [ "G", "B", "G", "C", "B", "M", "C", "G", "Y", "G", "B", "C", "M", "B", "G", "B", "C", "Y", "M", "C", "M", "B", "G", "B", "C", "Z" ],
"two" : [ "Y", "G", "Y", "B", "G", "C", "B", "Y", "M", "Y", "G", "B", "C", "G", "Y", "G", "B", "M", "C", "B", "C", "G", "Y", "C", "B", "Z" ],
"three" : [ "M", "Y", "M", "G", "Y", "B", "G", "M", "C", "M", "Y", "G", "B", "Y", "M", "Y", "G", "C", "B", "G", "B", "Y", "M", "Y", "G", "Z" ],
"four" : [ "C", "M", "C", "Y", "M", "G", "Y", "C", "B", "C", "M", "Y", "G", "M", "C", "M", "Y", "B", "G", "Y", "G", "M", "C", "M", "Y", "Z" ],
"five" : [ "B", "C", "B", "M", "C", "Y", "M", "B", "G", "B", "C", "M", "Y", "C", "B", "C", "M", "G", "Y", "M", "Y", "C", "B", "C", "M", "Z" ]
}
}
To retrieve the first entry of “Sequence one” I can send the message: get Sequence::one[1]
. For the fourth sequence, colour 6 it would be get Sequence::four[6]
, etc.
This is easy enough and works perfectly fine. However, I am working on a project right now using PoseNet
, which outputs all its data as a dictionary, at frame rate (a low frame rate, but frame rate non-the-less).
I didn’t want to format get
messages to extract all the information and was looking for a more elegant solution.
The data is organized like this (truncated):
{
"score" : 0.299320935792125,
"keypoints" : [ {
"score" : 0.999612092971802,
"part" : "nose",
"position" : {
"x" : 282.762551208749358,
"y" : 189.991754974048433
}
}
, {
"score" : 0.999678492546082,
"part" : "leftEye",
"position" : {
"x" : 330.609080207793056,
"y" : 156.654426548307725
}
}
,
[... reduced ...]
,
{
"score" : 0.999244570732117,
"part" : "rightEye",
"position" : {
"x" : 245.198799861417285,
"y" : 149.75491428045251
}
}
,
, {
"score" : 0.005600165575743,
"part" : "leftAnkle",
"position" : {
"x" : 196.871334091756381,
"y" : 494.033982432012294
}
}
, {
"score" : 0.005325738340616,
"part" : "rightAnkle",
"position" : {
"x" : 202.849661166242555,
"y" : 494.650997175064845
}
}
]
}
We have the key score
, which returns the mean score over all tracked points and the key keypoints
, which is an array containing all the data.
It was the array of data points that tripped me up for a long time. I missed the []
surrounding the keypoints
key. Since PoseNet
is able to track multiple people (something I haven’t tried yet), I am assuming that each person gets their own array entry.
I played around a bit getting to know dict.route
, dict.unpack
, dict.slice
, etc.
I think my final solution is quite elegant:
1) dict.unpack
the “keypoints”
2) iter
through everything in the “keypoints” array
3) dict.unpack
the relevant information
4) decide what to keep
5) package it all up again to send over OSC
…
And here is the final look of it:
I am only interested in data were the score
is above a certain percentage so I needed to do some easy comparison and repackaging of the data into OSC messages. One thing I might have to do, after confirming that the external application (Unity
) receives and can use the data properly, is to create a mechanism that only sends valid messages…
A simple onebang
object, controlled by the >
object should do the trick…