I am writing an application that uses the Kinect photo data and compares two frames against each other in F#. I am using Rob Miles Learn the Kinect Api page 74 as a guidepost but I am not using pointers and the performance is suffering. The byte from the Kinect frame is 1,228,800 bytes. I wrote the comparison like this:
member this.differenceCount(currentImageBytes) =
if previousImageBytes |> Seq.length = 0 then
previousImageBytes <- currentImageBytes
0
else
let bytes = Seq.zip previousImageBytes currentImageBytes
let differenceCount = bytes |> Seq.mapi(fun i e -> i, e)
|> Seq.filter(fun (i,e) -> i % 4 <> 0 )
|> Seq.map snd
|> Seq.filter(fun (p,c) -> p <> c)
|> Seq.length
previousImageBytes <- currentImageBytes
differenceCount
When I run it, the screen lags because (I think) it is taking too long to process the arrays. In addition, the error rate is approaching 50%.
1) Am I approaching the problem wrong? 2) Is there a way to optimize my code to speed things up?
Your sequence mapping/filtering via tuples causes a lot of boxing overhead. The following example avoids the boxing and works in parallel, which (on my machine) is 50 times faster.
let parallelRanges =
let kinectSize = 1228800
let subSize = kinectSize / Environment.ProcessorCount
let iMax = kinectSize - 1
let steps = [| -1 .. subSize .. iMax |]
steps.[steps.Length - 1] <- iMax
steps |> Seq.pairwise |> Seq.toArray |> Array.map (fun (x, y) -> x + 1, y)
let countDiffs (prevBytes:byte[]) (curBytes:_[]) =
let count (fromI, toI) =
let rec aux i acc =
if i > toI then acc
elif i % 4 <> 0 && prevBytes.[i] <> curBytes.[i] then
aux (i + 1) (acc + 1)
else aux (i + 1) acc
aux fromI 0
parallelRanges
|> Array.Parallel.map count
|> Array.sum
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With