分享一篇原作者写于2016.10的aegisub+blender进行画面追踪的文章
原文章地址:https://subarashii-no-fansub.github.io/Subbing-Tutorial/Tracking-Motion/
你需要准备的:
Aegisub本体
aegisub-motion的插件
blender(开源且免费的软件) 或者 mocha pro (win版)
在阅读本篇之前,请先熟悉aeg的具体操作
观看本篇前请观看以下教程:
通过以上两篇了解aeg+mocha如何进行追踪。
---如果你已经拥有win版的mocha pro,请按照以上视频步骤进行操作,两位up主都是非常好的大佬,足以让你学会这个插件的使用。
---如果你像我一样因为某些原因只能使用Blender,那么还请继续看下去。
总的来说就是,你按照无悠和IHKK的教程,安装好自动化脚本,在使用Mocha那步换成Blender,在Blender里进行运动追踪。在blender导出追踪数据的时候用到了下面的.py脚本插件,把数据转换成txt文本。再复制粘贴到aeg里,继续按照教程操作。
简单翻译一下下面这篇:
在Blender中进行运动追踪
有很多在用TypeSetting的人在用Mocha进行运动追踪
但由于我是Linux系统,上面这种方法不是最优解
所有我写了一篇教程教大家如何在免费而且开源的Blender里进行追踪。你也可以在Windows系统里用这种方法。
安装 Aegisub Motion 插件
在github里下载,并且解压。把autoload和include里的文件放到你aeg的automation的对应文件夹里。
安装Blender和x264
进行追踪
在Aegisub里
-你需要在aeg里加载一个视频
1.确定你要追踪的对象的第一帧和最后一帧,并且记录下相应的起始帧和结束帧。
2.结束第一步之后,第二步要配置一下Aegisub-Motion。
选好你在aeg里要进行追踪的那一行,在自动化里找到插件,选择trim setting。确认第一行是?video,第二行是x264。然后保存。最后打开trim,把你要追踪的这一小段剪下来。
3.在Blender里
打开运动跟踪界面进行跟踪(就不翻译了,请观看这个教程《IanHubert教你使用Blender进行运动跟踪和实景合成》网页链接)
4.做完上面这些,我们需要装一个插件把运动数据输出到aegisub-motion里。只需要一次
-保存/下载 aae-exort.py (脚本信息我会扔在最后)
-在Blender里 编辑->设置->插件->安装->找到aae-exort.py的位置并且安装它。最后激活名为Import-Export:Export:AE 6.0 Keyframe Data的插件(在插件界面点一下勾选的小方框)
5.现在可以导出了,选择导出里的AE 6.0 Keyframe Data。他会导出一个txt,复制粘贴txt里的内容到aeg自动化里motion插件的“应用”界面,粘贴数据到文本框里,运行之后你就可以得到你想要的了。(具体“应用”界面设置还请看无悠和IHKK的教程)

1p

2p
以上就是aeg+blender进行运动追踪的过程了。
aae-exort.py的脚本信息如下
# Copyright (c) 2013, Martin Herkt
#
# 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.
bl_info = {
"name": "Export: Adobe After Effects 6.0 Keyframe Data",
"description": "Export motion tracking markers to Adobe After Effects 6.0 compatible files",
"author": "Martin Herkt",
"version": (0, 1, 4),
"blender": (2, 80, 0),
"location": "File > Export > Adobe After Effects 6.0 Keyframe Data",
"warning": "",
"category": "Import-Export",
}
import bpy, mathutils, math
def write_files(prefix, context):
scene = context.scene
fps = scene.render.fps / scene.render.fps_base
clipno = 0
for clip in bpy.data.movieclips:
trackno = 0
for track in clip.tracking.tracks:
with open("{0}_c{1:02d}_t{2:02d}.txt".format(prefix, clipno, trackno), "w") as f:
frameno = clip.frame_start
startarea = None
startwidth = None
startheight = None
startrot = None
data = []
f.write("Adobe After Effects 6.0 Keyframe Data\r\n\r\n")
f.write("\tUnits Per Second\t{0:.3f}\r\n".format(fps))
f.write("\tSource Width\t{0}\r\n".format(clip.size[0]))
f.write("\tSource Height\t{0}\r\n".format(clip.size[1]))
f.write("\tSource Pixel Aspect Ratio\t1\r\n")
f.write("\tComp Pixel Aspect Ratio\t1\r\n\r\n")
while frameno <= clip.frame_duration:
marker = track.markers.find_frame(frameno)
frameno += 1
if not marker or marker.mute:
continue
coords = marker.co
corners = marker.pattern_corners
area = 0
width = math.sqrt((corners[1][0] - corners[0][0]) * (corners[1][0] - corners[0][0]) + (corners[1][1] - corners[0][1]) * (corners[1][1] - corners[0][1]))
height = math.sqrt((corners[3][0] - corners[0][0]) * (corners[3][0] - corners[0][0]) + (corners[3][1] - corners[0][1]) * (corners[3][1] - corners[0][1]))
for i in range(1,3):
x1 = corners[i][0] - corners[0][0]
y1 = corners[i][1] - corners[0][1]
x2 = corners[i+1][0] - corners[0][0]
y2 = corners[i+1][1] - corners[0][1]
area += x1 * y2 - x2 * y1
area = abs(area / 2)
if startarea == None:
startarea = area
if startwidth == None:
startwidth = width
if startheight == None:
startheight = height
zoom = math.sqrt(area / startarea) * 100
xscale = width / startwidth * 100
yscale = height / startheight * 100
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]
data.append([marker.frame, x, y, xscale, yscale, rotation])
posline = "\t{0}\t{1:.3f}\t{2:.3f}\t0"
scaleline = "\t{0}\t{1:.3f}\t{2:.3f}\t100"
rotline = "\t{0}\t{1:.3f}"
positions = "\r\n".join([posline.format(d[0], d[1], d[2]) for d in data]) + "\r\n\r\n"
scales = "\r\n".join([scaleline.format(d[0], d[3], d[4]) for d in data]) + "\r\n\r\n"
rotations = "\r\n".join([rotline.format(d[0], d[5]) for d in data]) + "\r\n\r\n"
f.write("Anchor Point\r\n")
f.write("\tFrame\tX pixels\tY pixels\tZ pixels\r\n")
f.write(positions)
f.write("Position\r\n")
f.write("\tFrame\tX pixels\tY pixels\tZ pixels\r\n")
f.write(positions)
f.write("Scale\r\n")
f.write("\tFrame\tX percent\tY percent\tZ percent\r\n")
f.write(scales)
f.write("Rotation\r\n")
f.write("\tFrame Degrees\r\n")
f.write(rotations)
f.write("End of Keyframe Data\r\n")
trackno += 1
clipno += 1
return {'FINISHED'}
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty
class ExportAFXKey(bpy.types.Operator, ExportHelper):
"""Export motion tracking markers to Adobe After Effects 6.0 compatible files"""
bl_idname = "export.afxkey"
bl_label = "Export to Adobe After Effects 6.0 Keyframe Data"
filename_ext = ""
filter_glob = StringProperty(default="*", options={'HIDDEN'})
def execute(self, context):
return write_files(self.filepath, context)
classes = (
ExportAFXKey,
)
def menu_func_export(self, context):
self.layout.operator(ExportAFXKey.bl_idname, text="Adobe After Effects 6.0 Keyframe Data")
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
写在最后:
aeg终究只是一个字幕软件,尽管开源让它变得十分强壮,但仍不足以替代任何专业性极强的视频制作软件。aeg的学习,只是让我比普通人多会那么一点点,无法和写脚本的大佬,以及和专业视频制作的大佬去“比较”。
我对Aeg、Mocha、Blender都了解不多,有任何问题我也无法解决,还请自行寻找答案。
软件、插件的下载地址,还请在上面三篇教程里自行寻找。
希望这篇专栏对你有帮助。
2023.3.27