Jump to: Board index » General » Fusion

Calculate Speed/Velocity Of Tracked Object

Learn about 3D compositing, animation, broadcast design and VFX workflows.
  • Author
  • Message
Offline

haikelareff

  • Posts: 2
  • Joined: Thu May 15, 2025 11:00 pm
  • Real Name: Haikel Areff

Calculate Speed/Velocity Of Tracked Object

PostThu May 15, 2025 11:14 pm

So I've been wondering, if we can track any moving object in the frame, is it possible we can also calculate how fast its moving? And can we visualise the movement of the object in the video to a 2D plane?


Example: To analyse a football team by tracking players movement
Offline

philipbowser

  • Posts: 399
  • Joined: Tue Oct 14, 2014 11:53 pm

Re: Calculate Speed/Velocity Of Tracked Object

PostSat May 17, 2025 1:33 am

It depends on the footage, but it can technically be done in Fusion for simple scenarios. However if there is significant camera motion or the subject's motion path is very complex, then you may require some more advanced 3D reconstruction techniques which can be a bit outside of Fusion's capabilities.

I believe that in order to calculate the velocity of a subject, you'd need to either know the camera's angle of view and the distance from the camera to the subject, or you'd have to know the real world distance between two points on screen that are on the same plane that the subject travelled. This assumes the camera doesn't move (or is stabilized) and the subject's movement is fairly restricted to a single plane that is more or less perpendicular to the camera's view.

Here's an example that uses both of those methods in expressions on Text+ nodes. Also I think my math on this is correct, but you may want to double check.
Code: Select all
{
   Tools = ordered() {
      Ellipse1 = EllipseMask {
         Inputs = {
            Filter = Input { Value = FuID { "Fast Gaussian" }, },
            MaskWidth = Input { Value = 3840, },
            MaskHeight = Input { Value = 2160, },
            PixelAspect = Input { Value = { 1, 1 }, },
            ClippingMode = Input { Value = FuID { "None" }, },
            Center = Input {
               SourceOp = "XYPath1",
               Source = "Value",
            },
            Width = Input { Value = 0.02, },
            Height = Input { Value = 0.02, }
         },
         ViewInfo = OperatorInfo { Pos = { 275, 148.5 } },
      },
      XYPath1 = XYPath {
         ShowKeyPoints = false,
         DrawMode = "ModifyOnly",
         CtrlWZoom = false,
         Inputs = {
            X = Input {
               SourceOp = "Ellipse1CenterXYPath1X",
               Source = "Value",
            },
            Y = Input {
               SourceOp = "Ellipse1CenterXYPath1Y",
               Source = "Value",
            }
         },
      },
      Ellipse1CenterXYPath1X = BezierSpline {
         SplineColor = { Red = 255, Green = 0, Blue = 0 },
         NameSet = true,
         KeyFrames = {
            [0] = { 0.134831460674157, RH = { 8, 0.134831460674157 }, Flags = { Linear = true } },
            [24] = { 0.533911692017631, LH = { 16, 0.533911692017631 }, RH = { 31.6666666666667, 0.533911692017631 } },
            [47] = { 0.777599429284823, LH = { 39.3333333333333, 0.777599429284823 } }
         }
      },
      Ellipse1CenterXYPath1Y = BezierSpline {
         SplineColor = { Red = 0, Green = 255, Blue = 0 },
         NameSet = true,
         KeyFrames = {
            [0] = { 0.278887303851641, RH = { 8, 0.278887303851641 }, Flags = { Linear = true } },
            [24] = { 0.790236298425912, LH = { 16, 0.790236298425912 }, RH = { 31.6666666666667, 0.790236298425912 } },
            [47] = { 0.549212530536721, LH = { 39.3333333333333, 0.549212530536721 } }
         }
      },
      Background1 = Background {
         Inputs = {
            EffectMask = Input {
               SourceOp = "Ellipse1",
               Source = "Mask",
            },
            Width = Input { Value = 3840, },
            Height = Input { Value = 2160, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            TopLeftRed = Input { Value = 1, },
            TopLeftGreen = Input { Value = 1, },
            TopLeftBlue = Input { Value = 1, }
         },
         ViewInfo = OperatorInfo { Pos = { 275, 181.5 } },
      },
      Tracker1 = Tracker {
         Trackers = {
            {
               ID = 1,
               PatternTime = 0,
               PatternX = 0.134675543834933,
               PatternY = 0.279254007559605
            }
         },
         Inputs = {
            Input = Input {
               SourceOp = "Background1",
               Source = "Output",
            },
            Name2 = Input { Value = "Point 2", },
            PatternCenter2 = Input { Value = { 0.777438808808892, 0.549580975152198 }, },
            PatternWidth2 = Input { Value = 0.0230400774542027, },
            PatternHeight2 = Input { Value = 0.0408865358394174, },
            SearchWidth2 = Input { Value = 0.121829862767674, },
            SearchHeight2 = Input { Value = 0.205892448620436, },
            TrackedCenter2 = Input {
               SourceOp = "Tracker1Point2XYPath",
               Source = "Value",
            }
         },
         ViewInfo = OperatorInfo { Pos = { 275, 214.5 } },
      },
      Tracker1Point2XYPath = XYPath {
         ShowKeyPoints = false,
         DrawMode = "InsertAndModify",
         CtrlWZoom = false,
         NameSet = true,
         Inputs = {
            X = Input {
               SourceOp = "Tracker1Point2XYPathX",
               Source = "Value",
            },
            Y = Input {
               SourceOp = "Tracker1Point2XYPathY",
               Source = "Value",
            }
         },
      },
      Tracker1Point2XYPathX = BezierSpline {
         SplineColor = { Red = 255, Green = 0, Blue = 0 },
         NameSet = true,
         KeyFrames = {
            [0] = { 0.134675543834933, RH = { 0.333333333333333, 0.135348965058891 }, Flags = { Linear = true } },
            [1] = { 0.136695807506808, LH = { 0.666666666666667, 0.13602238628285 }, RH = { 1.33333333333333, 0.138638081812364 }, Flags = { Linear = true } },
            [2] = { 0.142522630423475, LH = { 1.66666666666667, 0.140580356117919 }, RH = { 2.33333333333333, 0.145622538192572 }, Flags = { Linear = true } },
            [3] = { 0.151822353730767, LH = { 2.66666666666667, 0.14872244596167 }, RH = { 3.33333333333333, 0.155959180987711 }, Flags = { Linear = true } },
            [4] = { 0.1642328355016, LH = { 3.66666666666667, 0.160096008244656 }, RH = { 4.33333333333333, 0.169295362628336 }, Flags = { Linear = true } },
            [5] = { 0.179420416881808, LH = { 4.66666666666667, 0.174357889755072 }, RH = { 5.33333333333333, 0.185289286239447 }, Flags = { Linear = true } },
            [6] = { 0.197027024954725, LH = { 5.66666666666667, 0.191158155597086 }, RH = { 6.33333333333333, 0.203591695093614 }, Flags = { Linear = true } },
            [7] = { 0.216721035371392, LH = { 6.66666666666667, 0.210156365232503 }, RH = { 7.33333333333333, 0.223859435979031 }, Flags = { Linear = true } },
            [8] = { 0.238136237194308, LH = { 7.66666666666667, 0.230997836586669 }, RH = { 8.33333333333333, 0.245739861326253 }, Flags = { Linear = true } },
            [9] = { 0.260947109590142, LH = { 8.66666666666667, 0.253343485458197 }, RH = { 9.33333333333333, 0.268893886933892 }, Flags = { Linear = true } },
            [10] = { 0.284787441621392, LH = { 9.66666666666667, 0.276840664277642 }, RH = { 10.3333333333333, 0.292967508895697 }, Flags = { Linear = true } },
            [11] = { 0.309327643444308, LH = { 10.6666666666667, 0.301147576170003 }, RH = { 11.3333333333333, 0.31762164301028 }, Flags = { Linear = true } },
            [12] = { 0.334209642142225, LH = { 11.6666666666667, 0.325915642576253 }, RH = { 12.3333333333333, 0.342505676213406 }, Flags = { Linear = true } },
            [13] = { 0.359097744355767, LH = { 12.6666666666667, 0.350801710284586 }, RH = { 13.3333333333333, 0.367278489798475 }, Flags = { Linear = true } },
            [14] = { 0.383639980683892, LH = { 13.6666666666667, 0.375459235241184 }, RH = { 14.3333333333333, 0.391586758027642 }, Flags = { Linear = true } },
            [15] = { 0.407480312715142, LH = { 14.6666666666667, 0.399533535371392 }, RH = { 15.3333333333333, 0.415082580510281 }, Flags = { Linear = true } },
            [16] = { 0.430287116100558, LH = { 15.6666666666667, 0.422684848305419 }, RH = { 16.3333333333333, 0.437426873045003 }, Flags = { Linear = true } },
            [17] = { 0.451706386933892, LH = { 16.6666666666667, 0.444566629989447 }, RH = { 17.3333333333333, 0.458271057072781 }, Flags = { Linear = true } },
            [18] = { 0.471400397350558, LH = { 17.6666666666667, 0.464835727211669 }, RH = { 18.3333333333333, 0.477269266708197 }, Flags = { Linear = true } },
            [19] = { 0.489007005423475, LH = { 18.6666666666667, 0.483138136065836 }, RH = { 19.3333333333333, 0.494069532550211 }, Flags = { Linear = true } },
            [20] = { 0.504194586803683, LH = { 19.6666666666667, 0.499132059676947 }, RH = { 20.3333333333333, 0.508330735892225 }, Flags = { Linear = true } },
            [21] = { 0.516603034069308, LH = { 20.6666666666667, 0.512466884980766 }, RH = { 21.3333333333333, 0.5197015855016 }, Flags = { Linear = true } },
            [22] = { 0.525898688366183, LH = { 21.6666666666667, 0.522800136933891 }, RH = { 22.3333333333333, 0.527842997176947 }, Flags = { Linear = true } },
            [23] = { 0.531731614798475, LH = { 22.6666666666667, 0.529787305987711 }, RH = { 23.3333333333333, 0.532405036022433 }, Flags = { Linear = true } },
            [24] = { 0.53375187847035, LH = { 23.6666666666667, 0.533078457246392 }, RH = { 24.3333333333333, 0.534199469616183 }, Flags = { Linear = true } },
            [25] = { 0.53509465190785, LH = { 24.6666666666667, 0.534647060762017 }, RH = { 25.3333333333333, 0.536382493704725 }, Flags = { Linear = true } },
            [26] = { 0.538958177298475, LH = { 25.6666666666667, 0.5376703355016 }, RH = { 26.3333333333333, 0.541008958548475 }, Flags = { Linear = true } },
            [27] = { 0.545110521048475, LH = { 26.6666666666667, 0.543059739798475 }, RH = { 27.3333333333333, 0.547840148869656 }, Flags = { Linear = true } },
            [28] = { 0.553299404512017, LH = { 27.6666666666667, 0.550569776690836 }, RH = { 28.3333333333333, 0.55663260221167 }, Flags = { Linear = true } },
            [29] = { 0.563298997610975, LH = { 28.6666666666667, 0.559965799911322 }, RH = { 29.3333333333333, 0.567148959633544 }, Flags = { Linear = true } },
            [30] = { 0.574848883678683, LH = { 29.6666666666667, 0.570998921656114 }, RH = { 30.3333333333333, 0.579142367836669 }, Flags = { Linear = true } },
            [31] = { 0.587729336152642, LH = { 30.6666666666667, 0.583435851994656 }, RH = { 31.3333333333333, 0.5923822495641 }, Flags = { Linear = true } },
            [32] = { 0.601688076387017, LH = { 31.6666666666667, 0.597035162975559 }, RH = { 32.3333333333333, 0.606621751517225 }, Flags = { Linear = true } },
            [33] = { 0.616489101777642, LH = { 32.6666666666667, 0.611555426647434 }, RH = { 33.3333333333333, 0.62162283658667 }, Flags = { Linear = true } },
            [34] = { 0.631890306204725, LH = { 33.6666666666667, 0.626756571395697 }, RH = { 34.3333333333333, 0.63714543315785 }, Flags = { Linear = true } },
            [35] = { 0.6476556870641, LH = { 34.6666666666667, 0.642400560110975 }, RH = { 35.3333333333333, 0.652950147784586 }, Flags = { Linear = true } },
            [36] = { 0.663539069225558, LH = { 35.6666666666667, 0.658244608505072 }, RH = { 36.3333333333333, 0.668792161673475 }, Flags = { Linear = true } },
            [37] = { 0.679298346569308, LH = { 36.6666666666667, 0.674045254121391 }, RH = { 37.3333333333333, 0.684432759546739 }, Flags = { Linear = true } },
            [38] = { 0.6947015855016, LH = { 37.6666666666667, 0.689567172524169 }, RH = { 38.3333333333333, 0.699635260631808 }, Flags = { Linear = true } },
            [39] = { 0.709502610892225, LH = { 38.6666666666667, 0.704568935762017 }, RH = { 39.3333333333333, 0.714156880640489 }, Flags = { Linear = true } },
            [40] = { 0.723465420137017, LH = { 39.6666666666667, 0.718811150388753 }, RH = { 40.3333333333333, 0.727756869789795 }, Flags = { Linear = true } },
            [41] = { 0.73633976909535, LH = { 40.6666666666667, 0.732048319442572 }, RH = { 41.3333333333333, 0.740192443791531 }, Flags = { Linear = true } },
            [42] = { 0.747897793183892, LH = { 41.6666666666667, 0.744045118487711 }, RH = { 42.3333333333333, 0.751228956378336 }, Flags = { Linear = true } },
            [43] = { 0.757891282767225, LH = { 42.6666666666667, 0.754560119572781 }, RH = { 43.3333333333333, 0.760622266925211 }, Flags = { Linear = true } },
            [44] = { 0.766084235241183, LH = { 43.6666666666667, 0.763353251083197 }, RH = { 44.3333333333333, 0.768133660154378 }, Flags = { Linear = true } },
            [45] = { 0.772232509980767, LH = { 44.6666666666667, 0.770183085067572 }, RH = { 45.3333333333333, 0.773521708114447 }, Flags = { Linear = true } },
            [46] = { 0.776100104381808, LH = { 45.6666666666667, 0.774810906248128 }, RH = { 46.3333333333333, 0.776546339190836 }, Flags = { Linear = true } },
            [47] = { 0.777438808808892, LH = { 46.6666666666667, 0.776992573999864 }, RH = { 47.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [48] = { 0.777438808808892, LH = { 47.6666666666667, 0.777438808808892 }, RH = { 48.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [49] = { 0.777438808808892, LH = { 48.6666666666667, 0.777438808808892 }, RH = { 49.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [50] = { 0.777438808808892, LH = { 49.6666666666667, 0.777438808808892 }, RH = { 50.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [51] = { 0.777438808808892, LH = { 50.6666666666667, 0.777438808808892 }, RH = { 51.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [52] = { 0.777438808808892, LH = { 51.6666666666667, 0.777438808808892 }, RH = { 52.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [53] = { 0.777438808808892, LH = { 52.6666666666667, 0.777438808808892 }, RH = { 53.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [54] = { 0.777438808808892, LH = { 53.6666666666667, 0.777438808808892 }, RH = { 54.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [55] = { 0.777438808808892, LH = { 54.6666666666667, 0.777438808808892 }, RH = { 55.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [56] = { 0.777438808808892, LH = { 55.6666666666667, 0.777438808808892 }, RH = { 56.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [57] = { 0.777438808808892, LH = { 56.6666666666667, 0.777438808808892 }, RH = { 57.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [58] = { 0.777438808808892, LH = { 57.6666666666667, 0.777438808808892 }, RH = { 58.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [59] = { 0.777438808808892, LH = { 58.6666666666667, 0.777438808808892 }, RH = { 59.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [60] = { 0.777438808808892, LH = { 59.6666666666667, 0.777438808808892 }, RH = { 60.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [61] = { 0.777438808808892, LH = { 60.6666666666667, 0.777438808808892 }, RH = { 61.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [62] = { 0.777438808808892, LH = { 61.6666666666667, 0.777438808808892 }, RH = { 62.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [63] = { 0.777438808808892, LH = { 62.6666666666667, 0.777438808808892 }, RH = { 63.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [64] = { 0.777438808808892, LH = { 63.6666666666667, 0.777438808808892 }, RH = { 64.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [65] = { 0.777438808808892, LH = { 64.6666666666667, 0.777438808808892 }, RH = { 65.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [66] = { 0.777438808808892, LH = { 65.6666666666667, 0.777438808808892 }, RH = { 66.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [67] = { 0.777438808808892, LH = { 66.6666666666667, 0.777438808808892 }, RH = { 67.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [68] = { 0.777438808808892, LH = { 67.6666666666667, 0.777438808808892 }, RH = { 68.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [69] = { 0.777438808808892, LH = { 68.6666666666667, 0.777438808808892 }, RH = { 69.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [70] = { 0.777438808808892, LH = { 69.6666666666667, 0.777438808808892 }, RH = { 70.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [71] = { 0.777438808808892, LH = { 70.6666666666667, 0.777438808808892 }, RH = { 71.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [72] = { 0.777438808808892, LH = { 71.6666666666667, 0.777438808808892 }, RH = { 72.3333333333333, 0.777438808808892 }, Flags = { Linear = true } },
            [73] = { 0.777438808808892, LH = { 72.6666666666667, 0.777438808808892 }, Flags = { Linear = true } }
         }
      },
      Tracker1Point2XYPathY = BezierSpline {
         SplineColor = { Red = 0, Green = 255, Blue = 0 },
         NameSet = true,
         KeyFrames = {
            [0] = { 0.279254007559605, RH = { 0.333333333333333, 0.280118446217012 }, Flags = { Linear = true } },
            [1] = { 0.281847323531827, LH = { 0.666666666666667, 0.28098288487442 }, RH = { 1.33333333333333, 0.284336955090469 }, Flags = { Linear = true } },
            [2] = { 0.289316218207753, LH = { 1.66666666666667, 0.286826586649111 }, RH = { 2.33333333333333, 0.29328757237442 }, Flags = { Linear = true } },
            [3] = { 0.301230280707753, LH = { 2.66666666666667, 0.297258926541086 }, RH = { 3.33333333333333, 0.306531447760222 }, Flags = { Linear = true } },
            [4] = { 0.317133781865161, LH = { 3.66666666666667, 0.311832614812692 }, RH = { 4.33333333333333, 0.323618880244791 }, Flags = { Linear = true } },
            [5] = { 0.33658907700405, LH = { 4.66666666666667, 0.33010397862442 }, RH = { 5.33333333333333, 0.344111019519482 }, Flags = { Linear = true } },
            [6] = { 0.359154904550346, LH = { 5.66666666666667, 0.351632962034914 }, RH = { 6.33333333333333, 0.36756419274479 }, Flags = { Linear = true } },
            [7] = { 0.384382769133679, LH = { 6.66666666666667, 0.375973480939235 }, RH = { 7.33333333333333, 0.393532315815778 }, Flags = { Linear = true } },
            [8] = { 0.411831409179976, LH = { 7.66666666666667, 0.402681862497877 }, RH = { 8.33333333333333, 0.421571715892939 }, Flags = { Linear = true } },
            [9] = { 0.441052329318864, LH = { 8.66666666666667, 0.431312022605901 }, RH = { 9.33333333333333, 0.451236308871333 }, Flags = { Linear = true } },
            [10] = { 0.471604267976272, LH = { 9.66666666666667, 0.461420288423803 }, RH = { 10.3333333333333, 0.482086038809605 }, Flags = { Linear = true } },
            [11] = { 0.503049580476272, LH = { 10.6666666666667, 0.492567809642939 }, RH = { 11.3333333333333, 0.513677232868247 }, Flags = { Linear = true } },
            [12] = { 0.534932537652198, LH = { 11.6666666666667, 0.524304885260223 }, RH = { 12.3333333333333, 0.545560190044173 }, Flags = { Linear = true } },
            [13] = { 0.566815494828124, LH = { 12.6666666666667, 0.556187842436149 }, RH = { 13.3333333333333, 0.577296060028741 }, Flags = { Linear = true } },
            [14] = { 0.598257190429975, LH = { 13.6666666666667, 0.587776625229358 }, RH = { 14.3333333333333, 0.608441169982444 }, Flags = { Linear = true } },
            [15] = { 0.628809129087383, LH = { 14.6666666666667, 0.618625149534914 }, RH = { 15.3333333333333, 0.638550641433062 }, Flags = { Linear = true } },
            [16] = { 0.65803366612442, LH = { 15.6666666666667, 0.648292153778741 }, RH = { 16.3333333333333, 0.667183212806519 }, Flags = { Linear = true } },
            [17] = { 0.685482306170716, LH = { 16.6666666666667, 0.676332759488617 }, RH = { 17.3333333333333, 0.693889183099728 }, Flags = { Linear = true } },
            [18] = { 0.710702936957753, LH = { 17.6666666666667, 0.702296060028741 }, RH = { 18.3333333333333, 0.718226085105901 }, Flags = { Linear = true } },
            [19] = { 0.733272381402198, LH = { 18.6666666666667, 0.72574923325405 }, RH = { 19.3333333333333, 0.739757479781828 }, Flags = { Linear = true } },
            [20] = { 0.752727676541087, LH = { 19.6666666666667, 0.746242578161457 }, RH = { 20.3333333333333, 0.758028843593556 }, Flags = { Linear = true } },
            [21] = { 0.768631177698494, LH = { 20.6666666666667, 0.763330010646025 }, RH = { 21.3333333333333, 0.772602531865161 }, Flags = { Linear = true } },
            [22] = { 0.780545240198494, LH = { 21.6666666666667, 0.776573886031827 }, RH = { 22.3333333333333, 0.783034871757136 }, Flags = { Linear = true } },
            [23] = { 0.78801413487442, LH = { 22.6666666666667, 0.785524503315778 }, RH = { 23.3333333333333, 0.788878573531827 }, Flags = { Linear = true } },
            [24] = { 0.790607450846642, LH = { 23.6666666666667, 0.789743012189235 }, RH = { 24.3333333333333, 0.790164983639852 }, Flags = { Linear = true } },
            [25] = { 0.789280049226272, LH = { 24.6666666666667, 0.789722516433062 }, RH = { 25.3333333333333, 0.788005695445408 }, Flags = { Linear = true } },
            [26] = { 0.785456987883679, LH = { 25.6666666666667, 0.786731341664543 }, RH = { 26.3333333333333, 0.783430319288 }, Flags = { Linear = true } },
            [27] = { 0.779376982096642, LH = { 26.6666666666667, 0.781403650692321 }, RH = { 27.3333333333333, 0.776675159179975 }, Flags = { Linear = true } },
            [28] = { 0.771271513346642, LH = { 27.6666666666667, 0.773973336263309 }, RH = { 28.3333333333333, 0.767977724766395 }, Flags = { Linear = true } },
            [29] = { 0.761390147605901, LH = { 28.6666666666667, 0.764683936186148 }, RH = { 29.3333333333333, 0.757579142590469 }, Flags = { Linear = true } },
            [30] = { 0.749957132559605, LH = { 29.6666666666667, 0.753768137575037 }, RH = { 30.3333333333333, 0.745710894133679 }, Flags = { Linear = true } },
            [31] = { 0.737218417281827, LH = { 30.6666666666667, 0.741464655707753 }, RH = { 31.3333333333333, 0.732616517204667 }, Flags = { Linear = true } },
            [32] = { 0.723412717050346, LH = { 31.6666666666667, 0.728014617127506 }, RH = { 32.3333333333333, 0.718532315815778 }, Flags = { Linear = true } },
            [33] = { 0.708771513346642, LH = { 32.6666666666667, 0.71365191458121 }, RH = { 33.3333333333333, 0.703693388346642 }, Flags = { Linear = true } },
            [34] = { 0.693537138346642, LH = { 33.6666666666667, 0.698615263346642 }, RH = { 34.3333333333333, 0.688340861340469 }, Flags = { Linear = true } },
            [35] = { 0.677948307328124, LH = { 34.6666666666667, 0.683144584334297 }, RH = { 35.3333333333333, 0.672712244442321 }, Flags = { Linear = true } },
            [36] = { 0.662240118670716, LH = { 35.6666666666667, 0.667476181556519 }, RH = { 36.3333333333333, 0.657043841664543 }, Flags = { Linear = true } },
            [37] = { 0.646651287652198, LH = { 36.6666666666667, 0.651847564658371 }, RH = { 37.3333333333333, 0.641573162652198 }, Flags = { Linear = true } },
            [38] = { 0.631416912652198, LH = { 37.6666666666667, 0.636495037652198 }, RH = { 38.3333333333333, 0.626535305784914 }, Flags = { Linear = true } },
            [39] = { 0.616772092050346, LH = { 38.6666666666667, 0.62165369891763 }, RH = { 39.3333333333333, 0.612171397605902 }, Flags = { Linear = true } },
            [40] = { 0.602970008717013, LH = { 39.6666666666667, 0.607570703161457 }, RH = { 40.3333333333333, 0.598723770291087 }, Flags = { Linear = true } },
            [41] = { 0.590231293439235, LH = { 40.6666666666667, 0.594477531865161 }, RH = { 41.3333333333333, 0.586421494056519 }, Flags = { Linear = true } },
            [42] = { 0.578801895291087, LH = { 41.6666666666667, 0.582611694673803 }, RH = { 42.3333333333333, 0.575506901078124 }, Flags = { Linear = true } },
            [43] = { 0.568916912652198, LH = { 42.6666666666667, 0.572211906865161 }, RH = { 43.3333333333333, 0.566216295368247 }, Flags = { Linear = true } },
            [44] = { 0.560815060800346, LH = { 43.6666666666667, 0.563515678084297 }, RH = { 44.3333333333333, 0.558785980939235 }, Flags = { Linear = true } },
            [45] = { 0.554727821217013, LH = { 44.6666666666667, 0.556756901078124 }, RH = { 45.3333333333333, 0.553454673068865 }, Flags = { Linear = true } },
            [46] = { 0.550908376772568, LH = { 45.6666666666667, 0.552181524920716 }, RH = { 46.3333333333333, 0.550465909565778 }, Flags = { Linear = true } },
            [47] = { 0.549580975152198, LH = { 46.6666666666667, 0.550023442358988 }, RH = { 47.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [48] = { 0.549580975152198, LH = { 47.6666666666667, 0.549580975152198 }, RH = { 48.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [49] = { 0.549580975152198, LH = { 48.6666666666667, 0.549580975152198 }, RH = { 49.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [50] = { 0.549580975152198, LH = { 49.6666666666667, 0.549580975152198 }, RH = { 50.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [51] = { 0.549580975152198, LH = { 50.6666666666667, 0.549580975152198 }, RH = { 51.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [52] = { 0.549580975152198, LH = { 51.6666666666667, 0.549580975152198 }, RH = { 52.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [53] = { 0.549580975152198, LH = { 52.6666666666667, 0.549580975152198 }, RH = { 53.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [54] = { 0.549580975152198, LH = { 53.6666666666667, 0.549580975152198 }, RH = { 54.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [55] = { 0.549580975152198, LH = { 54.6666666666667, 0.549580975152198 }, RH = { 55.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [56] = { 0.549580975152198, LH = { 55.6666666666667, 0.549580975152198 }, RH = { 56.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [57] = { 0.549580975152198, LH = { 56.6666666666667, 0.549580975152198 }, RH = { 57.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [58] = { 0.549580975152198, LH = { 57.6666666666667, 0.549580975152198 }, RH = { 58.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [59] = { 0.549580975152198, LH = { 58.6666666666667, 0.549580975152198 }, RH = { 59.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [60] = { 0.549580975152198, LH = { 59.6666666666667, 0.549580975152198 }, RH = { 60.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [61] = { 0.549580975152198, LH = { 60.6666666666667, 0.549580975152198 }, RH = { 61.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [62] = { 0.549580975152198, LH = { 61.6666666666667, 0.549580975152198 }, RH = { 62.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [63] = { 0.549580975152198, LH = { 62.6666666666667, 0.549580975152198 }, RH = { 63.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [64] = { 0.549580975152198, LH = { 63.6666666666667, 0.549580975152198 }, RH = { 64.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [65] = { 0.549580975152198, LH = { 64.6666666666667, 0.549580975152198 }, RH = { 65.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [66] = { 0.549580975152198, LH = { 65.6666666666667, 0.549580975152198 }, RH = { 66.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [67] = { 0.549580975152198, LH = { 66.6666666666667, 0.549580975152198 }, RH = { 67.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [68] = { 0.549580975152198, LH = { 67.6666666666667, 0.549580975152198 }, RH = { 68.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [69] = { 0.549580975152198, LH = { 68.6666666666667, 0.549580975152198 }, RH = { 69.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [70] = { 0.549580975152198, LH = { 69.6666666666667, 0.549580975152198 }, RH = { 70.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [71] = { 0.549580975152198, LH = { 70.6666666666667, 0.549580975152198 }, RH = { 71.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [72] = { 0.549580975152198, LH = { 71.6666666666667, 0.549580975152198 }, RH = { 72.3333333333333, 0.549580975152198 }, Flags = { Linear = true } },
            [73] = { 0.549580975152198, LH = { 72.6666666666667, 0.549580975152198 }, Flags = { Linear = true } }
         }
      },
      DistanceBased = TextPlus {
         CtrlWZoom = false,
         NameSet = true,
         Inputs = {
            Wrap = Input { Value = 1, },
            Width = Input { Value = 3840, },
            Height = Input { Value = 2160, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Center = Input { Value = { 0.0361155698234, 0.1068548387097 }, },
            LayoutRotation = Input { Value = 1, },
            TransformRotation = Input { Value = 1, },
            Softness1 = Input { Value = 1, },
            StyledText = Input { Expression = ":RealDistance = self.Distance;\nScreenDistance = sqrt((PointB.X - PointA.X)^2 + (PointB.Y - PointA.Y)^2);\nScaledDistance = RealDistance / ScreenDistance;\nX = Tracker1.TrackedCenter2.X - Tracker1:GetValue(\"TrackedCenter2\", time -1).X;\nY = Tracker1.TrackedCenter2.Y - Tracker1:GetValue(\"TrackedCenter2\", time -1).Y;\nDisplacement = sqrt(X*X + Y*Y);\nFPS = 1 / comp:GetPrefs().Comp.FrameFormat.Rate;\nVelocity = Displacement * ScaledDistance / FPS;\nreturn \"Speed = \"..floor(Velocity);", },
            Font = Input { Value = "Open Sans", },
            Style = Input { Value = "Bold", },
            VerticalJustificationNew = Input { Value = 3, },
            HorizontalLeftCenterRight = Input { Value = -1, },
            HorizontalJustificationNew = Input { Value = 3, },
            Distance = Input { Value = 10, },
            PointA = Input { Value = { 0.134426303854875, 0.274193548387097 }, },
            PointB = Input { Value = { 0.534367346938776, 0.786290322580645 }, }
         },
         ViewInfo = OperatorInfo { Pos = { 385, 280.5 } },
         UserControls = ordered() {
            Distance = {
               INP_MaxAllowed = 1000000,
               INP_Integer = false,
               INPID_InputControl = "ScrewControl",
               INP_MaxScale = 1,
               INP_MinScale = 0,
               INP_MinAllowed = -1000000,
               LINKID_DataType = "Number",
               ICS_ControlPage = "Text",
               INP_SplineType = "Default",
               LINKS_Name = "Real World Distance"
            },
            PointA = {
               INPID_PreviewControl = "CrosshairControl",
               LINKID_DataType = "Point",
               ICS_ControlPage = "Text",
               INPID_InputControl = "OffsetControl",
               CHC_Style = "NormalCross",
               LINKS_Name = "Point A",
            },
            PointB = {
               INPID_PreviewControl = "CrosshairControl",
               LINKID_DataType = "Point",
               ICS_ControlPage = "Text",
               INPID_InputControl = "OffsetControl",
               CHC_Style = "NormalCross",
               LINKS_Name = "Point B",
            }
         }
      },
      AoVBased = TextPlus {
         NameSet = true,
         Inputs = {
            Wrap = Input { Value = 1, },
            Width = Input { Value = 3840, },
            Height = Input { Value = 2160, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Center = Input { Value = { 0.036115569823435, 0.106854838709677 }, },
            LayoutRotation = Input { Value = 1, },
            TransformRotation = Input { Value = 1, },
            Softness1 = Input { Value = 1, },
            StyledText = Input { Expression = ":Aspect = Background1.Output.Width / Background1.Output.Height;\nFPS = 1 / comp:GetPrefs().Comp.FrameFormat.Rate;\nX = Tracker1.TrackedCenter2.X - Tracker1:GetValue(\"TrackedCenter2\", time -1).X;\nY = Tracker1.TrackedCenter2.Y - Tracker1:GetValue(\"TrackedCenter2\", time -1).Y;\nDisplacement = sqrt(X*X + Y*Y);\nDiagonalAoV = deg(2 * atan(tan(rad(self.AoV/2)) * sqrt(1 + 1/(Aspect * Aspect))));\nAngularMotion = rad(Displacement * DiagonalAoV);\nVelocity = self.Distance * AngularMotion / FPS;\nreturn \"Speed = \"..floor(Velocity);", },
            Font = Input { Value = "Open Sans", },
            Style = Input { Value = "Bold", },
            VerticalJustificationNew = Input { Value = 3, },
            HorizontalLeftCenterRight = Input { Value = -1, },
            HorizontalJustificationNew = Input { Value = 3, },
            AoV = Input { Value = 45, },
            Distance = Input { Value = 20, }
         },
         ViewInfo = OperatorInfo { Pos = { 165, 280.5 } },
         UserControls = ordered() {
            AoV = {
               INP_MaxAllowed = 1000000,
               INP_Integer = false,
               INPID_InputControl = "ScrewControl",
               INP_MaxScale = 1,
               INP_MinScale = 0,
               INP_MinAllowed = -1000000,
               LINKID_DataType = "Number",
               ICS_ControlPage = "Text",
               INP_SplineType = "Default",
               LINKS_Name = "Horizontal AoV"
            },
            Distance = {
               INP_MaxAllowed = 1000000,
               INP_Integer = false,
               INPID_InputControl = "ScrewControl",
               INP_MaxScale = 1,
               INP_MinScale = 0,
               INP_MinAllowed = -1000000,
               LINKID_DataType = "Number",
               ICS_ControlPage = "Text",
               INP_SplineType = "Default",
               LINKS_Name = "Distance to Subject"
            }
         }
      },
      Merge1 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "Tracker1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "AoVBased",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, }
         },
         ViewInfo = OperatorInfo { Pos = { 165, 313.5 } },
      },
      Merge2 = Merge {
         Inputs = {
            Background = Input {
               SourceOp = "Tracker1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "DistanceBased",
               Source = "Output",
            },
            PerformDepthMerge = Input { Value = 0, }
         },
         ViewInfo = OperatorInfo { Pos = { 385, 313.5 } },
      }
   }
}


The first method is the AoVBased Text+ node which has a "Horizontal AoV" and a "Distance to Subject" slider. And the second method is the DistanceBased Text+ node which has a "Real World Distance" slider to establish the real-world distance between the "Point A" and "Point B" controls.

The units are whatever you want them to be, it could be meters, feet, yards etc. So if you decide the distance slider is in meters, then the speed is meters per second.

You'll have to modify the expression for whatever tracker or point you're trying to calculate, but hopefully this provides the core concepts.
Offline

haikelareff

  • Posts: 2
  • Joined: Thu May 15, 2025 11:00 pm
  • Real Name: Haikel Areff

Re: Calculate Speed/Velocity Of Tracked Object

PostSat May 17, 2025 11:08 am

Screenshot 2025-05-16 135531.png
heatmap
Screenshot 2025-05-16 135531.png (971.25 KiB) Viewed 742 times
At the moment my camera is recorded using tripod. Its just that the wide angle lens causing the field distorted.

1. I can assume the field is 120m (L) x 90m (w)
2. I can use player height as to get relative measurement to real world?
3. And from there, how do I use the tracking data and projecting into a 2D flat view for heat map and other purpose?

Screenshot 2025-05-16 135531.png
heatmap
Screenshot 2025-05-16 135531.png (971.25 KiB) Viewed 742 times
Attachments
Screenshot 2025-05-12 232818.png
example footage
Screenshot 2025-05-12 232818.png (107.36 KiB) Viewed 742 times
Offline

philipbowser

  • Posts: 399
  • Joined: Tue Oct 14, 2014 11:53 pm

Re: Calculate Speed/Velocity Of Tracked Object

PostWed May 21, 2025 6:36 pm

If you're looking to do this for gameplay analysis or with any kind of accuracy, then Fusion isn't the tool. To do data visualizations for gameplay analysis you'd typically need wearable tracking devices on the players or an array of cameras around the field to be fed into specialized software.

You can achieve the "look" of the heat map in Fusion, but it will be a purely creative representation for entertainment purposes.
Offline
User avatar

Andrew Hazelden

  • Posts: 610
  • Joined: Sat Dec 06, 2014 12:10 pm
  • Location: West Dover, Nova Scotia, Canada

Re: Calculate Speed/Velocity Of Tracked Object

PostFri May 23, 2025 12:51 am

If you used a Python based computer vision library like "Ultralytics YOLO" you would likely get a lot closer to your goals.

The output from a computer vision library could then be imported into Resolve/Fusion using a data exchange format like JSON, and a scripting language like Lua/Python or a Fuse plugin used to drive the visuals and overlays.
Reactor.lua:933: attempt to index global 'ui' (a nil value)
Offline

Sam Steti

  • Posts: 3153
  • Joined: Tue Jun 17, 2014 7:29 am
  • Location: France

Re: Calculate Speed/Velocity Of Tracked Object

PostSun May 25, 2025 6:03 pm

Hey

Just as a basic input, I know an app called fSpy - don't know if it exists for windows - which calculates several parameters in an image (see attachment).
It exports camera parametrs as JSON files...
Attachments
Capture d’écran 2025-05-25 à 20.02.02.png
Capture d’écran 2025-05-25 à 20.02.02.png (192.68 KiB) Viewed 519 times
*MacMini M1 16 Go - Sonoma - Ext nvme SSDs on TB3 - 14 To HD in 2 x 4 disks USB3 towers
*Legacy MacPro 8core Xeons, 32 Go ram, 2 x gtx 980 ti, 3SSDs including RAID
*Resolve Studio everywhere, Fusion Studio too
*https://www.buymeacoffee.com/videorhin

Return to Fusion

Who is online

Users browsing this forum: No registered users and 35 guests