前言

算法仿真的方法主要有两种,python和MATLAB
由于需要对设备进行移植,opencv更加方便。同时MATLAB是收费软件,公司没有买licence。最终选择Python+OpenCV

新手不建议安装anaconda,经常会出现模块导入问题,我还出现过matplotlib模块缺失的问题,所以建议直接在系统中安装python程序。

实现

我把它分为三个部分
第一个部分,数据的读取与校准
第二个部分,数据的处理
第三个部分,视频的处理

数据的读取和校准

定义一个陀螺仪数据读取与校准的类,将有关陀螺仪数据的读取和校准方法包含进来,有利于梳理代码结构。

数据的读取

定义一个陀螺仪数据读取与校准的类,这个类初始化的输入就是文件的路径

class GyroscopeDataFile(object):
# the file path to read
# a dictionary of angular velocities
# This dictionary will store mappings between the timestamp
# and the angular velocity at that instant.
def __init__(self, filepath):
self.filepath = filepath
self.omega = {}

def _getfile_object(self):
return open(self.filepath)

# read the file and populate the Omega dictionary.
def parse(self):
with self._getfile_object() as fp:
# We validate that the first line of the csv file matches our
# expectation. If not, the csv file was probably not compatible
# and will error out over the next few lines.
firstline = fp.readline().strip()
if not firstline == "gyro":
raise Exception("The first line isn't valid")

# The strip function removed any additional whitespace
# (tabs, spaces, newline characters, among others)
# that might be stored in the file.
for line in fp.readlines():
line = line.strip()
parts = line.split(",")
# convert strings into numetric type
timestamp = int(parts[3])
ox = float(parts[0])
oy = float(parts[1])
oz = float(parts[2])
'''
if timestamp < 100000000:
timestamp = timestamp * 10
if timestamp < 100000000:
timestamp = timestamp * 10
'''
print("%s: %s, %s, %s" % (timestamp, ox, oy, oz))
self.omega[timestamp] = (ox, oy, oz)
return

# return a sorted list of timestamps from small to large num
def get_timestamps(self):
return sorted(self.omega.keys())

数据的序列化

有些中间生成的数据,调试的时候需要经常使用。如果每次都重新运行程序生成的话,会浪费很多的时间。
这里利用pickle模块进行数据的序列化
python文件的打开尽量用with的方法,防止忘记关闭文件,保证安全

def read_gyro_data(self):
if not os.path.exists(self.gyrofilename):
print("start creating "+self.gyrofilename)
with open(self.gyrofilename, "wb") as fp:
pickle.dump(self.omega, fp)
return self.omega
else:
with open(self.gyrofilename, "rb") as fp:
return pickle.load(fp)

镜头参数校准

class LenParametersFromMatlab(object):
"""
get opencv camera parameters from matlab parameters
"""
def __init__(self,
radialDistortion,
tangentialDistortion,
intrinsicMatrix,
focalLength,
principalPoint
):
"""
radialDistortion: 1 x 2 matrix
tangentialDistortion: 1 x 2 matrix
intrinsicMatrix: 3 x 3 matrix
"""
self.kc1 = radialDistortion[0]
self.kc2 = radialDistortion[1]
self.kc3 = tangentialDistortion[0]
self.kc4 = tangentialDistortion[1]
self.fc1 = intrinsicMatrix[0][0]
self.fc2 = intrinsicMatrix[1][1]
self.cc1 = intrinsicMatrix[2][0]
self.cc2 = intrinsicMatrix[2][1]
self.focalLength = focalLength
self.principalPoint = principalPoint

def getCameraMatrix(self):
return np.array([
[self.fc1, 0, self.cc1],
[0, self.fc2, self.cc2],
[0, 0, 1]
])

def getdistCoeffs(self):
return np.array([self.kc1, self.kc2, self.kc3, self.kc4])