【Python】曲线简化算法实现
2017-07-17 00:08
495 查看
Overview
曲线简化算法通常应用于运动捕捉数据的关键帧提取,在此基础上还演化出了更多的算法本文对基本的曲线简化算法进行了代码实现,以关键帧个数或线性重建误差作为迭代终止条件
其中,计算点i到直线n1-n2的距离公式如下[1]:
更多算法及分析可参考[2]
Code
注释中提供一些简单的说明以便于理解#!/usr/bin/env python #-*- coding: utf-8 -*- ####################### # Info : Curve Simplify # Version 1.0 # Author : Alex Pan # Date : 2017-07-11 ####################### import numpy as np from termcolor import colored import ipdb ## Data Type uintType = np.uint8 floatType = np.float32 ##----------------------------------------------------------------------------------- ## Get Distance Between point and [line_start-line_end] Line def getPoint2LineDistance(point, line_start, line_end): # Exception if not isinstance(point, np.ndarray) or not isinstance(line_start, np.ndarray) or not isinstance(line_end, np.ndarray): raise TypeError('All points MUST be numpy.ndarray!') elif point.ndim != 1 or point.shape != line_start.shape or point.shape != line_end.shape: raise ValueError('points dimensions error or NOT matched!') elif (line_start == line_end).all(): raise Exception('line_start is the SAME as line_end!') return np.sqrt(np.sum(np.square(point - line_start)) - np.square(np.sum((line_end - line_start) * (point - line_start))) / np.sum(np.square(line_end - line_start), dtype = floatType)) ##----------------------------------------------------------------------------------- ## Constrcuct np.linspace Array between raw_array[index_start] and raw_array[index_end] def getLinspaceArray(raw_array, index_start, index_end): # Exception if not isinstance(raw_array, np.ndarray): raise TypeError('raw_array MUST be numpy.ndarray!') elif index_start < 0 or index_end > raw_array.shape[0] or index_start > index_end: raise ValueError('index_start or index_end INVALID!') # Reconstruct Array by np.linspace Based on keyIndexes linspaceArray = np.linspace(raw_array[index_start][0], raw_array[index_end][0], num = index_end - index_start + 1, endpoint = True, dtype = floatType) for i in xrange(1, raw_array.shape[1]): linspaceArray = np.row_stack((linspaceArray, np.linspace(raw_array[index_start][i], raw_array[index_end][i], num = index_end - index_start + 1, endpoint = True, dtype = floatType))) return np.transpose(linspaceArray) ##----------------------------------------------------------------------------------- ## Compute Error Between 2 Arrays def computeReconstructError(array_A, array_B): # Exception if not isinstance(array_A, np.ndarray) or not isinstance(array_B, np.ndarray): raise TypeError('array_A and array_B MUST be numpy.ndarray!') elif array_A.shape != array_B.shape: raise ValueError('array_A and array_B dimensions NOT matched!') # Vector if array_A.ndim == array_B.ndim == 1: return np.sqrt(np.sum(np.square(array_A - array_B))) # Array error_array = array_A - array_B error_list = [np.sqrt(np.sum(np.square(error))) for error in error_array] return float(sum(error_list)) / len(error_list) ##----------------------------------------------------------------------------------- ## Function of Curve Simplify Algorithm def curveSimplify(poses_array, max_key = 10, error_threshold = 0.05): # Exception if not isinstance(poses_array, np.ndarray): raise TypeError('poses_array MUST be numpy.ndarray!') # Initialize N_poses, M_poses = poses_array.shape keyIndexes = [0, N_poses - 1] reconstructArray = getLinspaceArray(raw_array = poses_array, index_start = keyIndexes[0], index_end = keyIndexes[-1]) # Divide flagContinue = True while flagContinue: keyIndexes.sort() keyDeltas = [(keyIndexes[i], keyIndexes[i + 1]) for i in xrange(len(keyIndexes) - 1)] for keyStart, keyEnd in keyDeltas: distanceList = [getPoint2LineDistance(point = poses_array[i], line_start = poses_array[keyStart], line_end = poses_array[keyEnd]) for i in xrange(keyStart + 1, keyEnd)] keyNew = keyStart + distanceList.index(max(distanceList)) + 1 keyIndexes.append(keyNew) # Reconstruct [keyStart-keyNew] & [keyNew-keyEnd] reconstructArray[keyStart : keyNew + 1] = getLinspaceArray(raw_array = poses_array, index_start = keyStart, index_end = keyNew) reconstructArray[keyNew : keyEnd + 1] = getLinspaceArray(raw_array = poses_array, index_start = keyNew, index_end = keyEnd) reconstructError = computeReconstructError(poses_array, reconstructArray) # Print Screen print colored('keyNum:', 'magenta'), len(keyIndexes) print 'recError:', colored(str(reconstructError), 'white') # ipdb.set_trace() # End Condition: KeyNum or ReconstructError if len(keyIndexes) == max_key or reconstructError < error_threshold: flagContinue = False break keyIndexes.sort() return keyIndexes, reconstructError
Reference
[1] 杨涛,肖俊,吴飞,庄越挺. 基于分层曲线简化的运动捕获数据关键帧提取[2] 杨涛. 人体运动捕获数据关键帧提取算法研究
相关文章推荐
- 曲线点抽稀算法-Python实现
- 曲线点抽稀算法-Python实现
- Python实现曲线点抽稀算法的示例
- 机器学习经典算法详解及Python实现--K近邻(KNN)算法
- python机器学习---用贝叶斯算法实现垃圾邮件分类预测
- 词性标注的python实现-基于平均感知机算法
- 聚类之均值聚类(k-means)算法的python实现
- 算法基础之python实现贪心算法中圣诞老人分糖果问题和二分查找算法中烘干衣服问题
- 压缩感知重构算法之CoSaMP算法python实现
- K-近邻算法的Python实现(一)
- Python实现的选择排序算法原理与用法实例分析
- 猴王算法精简版 Python实现
- IP报头检验和算法的python实现
- KNN算法Python实现(代码来自机器学习实战)及注释
- python算法:LinkedList(双向线性链表)的实现
- 经典算法的Python实现(3)
- 经典算法的Python实现(4)
- 三种方法实现PCA算法(Python)
- 基于随机游走的社团划分算法label progation 的python实现
- 机器学习之决策树(ID3)算法与Python实现