Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjy Cook <benjycook@hotmail.com>2011-07-05 14:55:35 +0400
committerBenjy Cook <benjycook@hotmail.com>2011-07-05 14:55:35 +0400
commit90e8b83b45893619e4a666913afe6ea871a7d9d4 (patch)
treefe990e3099bf4b8632a5d85d419ad8b265d150b7 /release/scripts
parentceabc6d119caa8132182697bf655f595c468dc2e (diff)
Added denoising function. Uses a type of median filter to smooth out spikes, typical of sensor noise in motion capture data
Diffstat (limited to 'release/scripts')
-rw-r--r--release/scripts/modules/mocap_tools.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/release/scripts/modules/mocap_tools.py b/release/scripts/modules/mocap_tools.py
index dfb8aaf0eec..e9891bbf498 100644
--- a/release/scripts/modules/mocap_tools.py
+++ b/release/scripts/modules/mocap_tools.py
@@ -513,3 +513,37 @@ def fcurves_simplify(sel_opt="all", error=0.002, group_mode=True):
print(str(totalt)[:5] + " seconds, total time elapsed")
return
+
+# Implementation of non-linear median filter, with variable kernel size
+# Double pass - one marks spikes, the other smooths one
+# Expects sampled keyframes on everyframe
+
+
+def denoise_median():
+ context = bpy.context
+ obj = context.active_object
+ fcurves = obj.animation_data.action.fcurves
+ medKernel = 1 # actually *2+1... since it this is offset
+ flagKernel = 4
+ highThres = (flagKernel * 2) - 1
+ lowThres = 0
+ for fcurve in fcurves:
+ orgPts = fcurve.keyframe_points[:]
+ flaggedFrames = []
+ # mark frames that are spikes by sorting a large kernel
+ for i in range(flagKernel, len(fcurve.keyframe_points) - flagKernel):
+ center = orgPts[i]
+ neighborhood = orgPts[i - flagKernel: i + flagKernel]
+ neighborhood.sort(key=lambda pt: pt.co[1])
+ weight = neighborhood.index(center)
+ if weight >= highThres or weight <= lowThres:
+ flaggedFrames.append((i, center))
+ # clean marked frames with a simple median filter
+ # averages all frames in the kernel equally, except center which has no weight
+ for i, pt in flaggedFrames:
+ newValue = 0
+ sumWeights = 0
+ neighborhood = [neighpt.co[1] for neighpt in orgPts[i - medKernel: i + medKernel + 1] if neighpt != pt]
+ newValue = sum(neighborhood) / len(neighborhood)
+ pt.co[1] = newValue
+ return