This repository has been archived on 2019-12-02. You can view files and clone it, but cannot push or open issues/pull-requests.
video-analysis/blender/csv-export.py

136 lines
4.5 KiB
Python

# ISC License
#
# Copyright 2019 Simon Bruder
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# This script is based on “aae-export.py” by Martin Herkt (lachs0r): https://gist.github.com/torque/6453947
bl_info = {
'name': 'Export: CSV Tracking Data',
'description': 'Export motion tracking data to CSV file',
'author': 'Simon Bruder',
'version': (0, 1, 0),
'blender': (2, 80, 0),
'location': 'Movie Clip Editor > Footage > CSV Tracking Data Export',
'warning': '',
'category': 'Import-Export',
}
import bpy
import csv
import math
import mathutils
def write_files(prefix, context):
scene = context.scene
fps = scene.render.fps / scene.render.fps_base
clip = context.edit_movieclip
real_scale = clip.real_length_pixels / clip.real_length_meters
for trackno, track in enumerate(clip.tracking.tracks):
with open(f'{prefix}_{trackno}.csv', 'w') as f:
writer = csv.DictWriter(
f,
fieldnames=[
'time (frames)',
'time (s)',
'x (px)',
'x (m)',
'y (px)',
'y (m)',
'rotation'
]
)
writer.writeheader()
startrot = None
for marker in [track.markers.find_frame(frameno) for frameno in range(1, clip.frame_duration + 1)]:
if not marker or marker.mute:
continue
coords = marker.co
corners = marker.pattern_corners
p1 = mathutils.Vector(corners[0])
p2 = mathutils.Vector(corners[1])
mid = (p1 + p2) / 2
diff = mid - mathutils.Vector((0,0))
rotation = math.atan2(diff[0], diff[1]) * 180 / math.pi
if startrot == None:
startrot = rotation
rotation = 0
else:
rotation -= startrot - 360
x = coords[0] * clip.size[0]
y = (1 - coords[1]) * clip.size[1]
writer.writerow({
'time (frames)': marker.frame,
'time (s)': marker.frame / fps,
'x (px)': x,
'x (m)': x / real_scale,
'y (px)': y,
'y (m)': y / real_scale,
'rotation': rotation % 360
})
return {'FINISHED'}
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty
class ExportCSVKey(bpy.types.Operator, ExportHelper):
bl_idname = 'export.csvkey'
bl_label = 'Export tracking data to CSV file'
filename_ext = ''
filter_glob: StringProperty(default='*', options={'HIDDEN'})
def execute(self, context):
return write_files(self.filepath, context)
class ExportCSVKeyPanel(bpy.types.Panel):
bl_idname = 'CLIP_PT_tracking_export'
bl_label = 'CSV Tracking Data Export'
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'UI'
bl_category = 'Footage'
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
col = self.layout.column(align = True)
col.prop(context.edit_movieclip, 'real_length_pixels')
col.prop(context.edit_movieclip, 'real_length_meters')
col.operator('export.csvkey', text='Export')
def register():
bpy.utils.register_class(ExportCSVKey)
bpy.utils.register_class(ExportCSVKeyPanel)
bpy.types.MovieClip.real_length_pixels = bpy.props.IntProperty(name='Real length (px)', default=100)
bpy.types.MovieClip.real_length_meters = bpy.props.FloatProperty(name='Real length (m)', default=0.1, precision=3)
def unregister():
bpy.utils.unregister_class(ExportCSVKey)
del bpy.types.MovieClip.real_length_pixels
del bpy.types.MovieClip.real_length_meters
if __name__ == '__main__':
register()