使用Moco工具生成人体蹲起运动并分析辅助器械作用

本文主要是介绍使用Moco工具生成人体蹲起运动并分析辅助器械作用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 思路和解释

2. 代码逻辑

3. 代码注释

4. 关节扭矩驱动与肌肉驱动的模型处理方法

1. 思路和解释

Moco可以通过轨迹优化生成预测的运动,并用来进行优化模型参数。本篇文章以蹲起运动为例子进行说明。优化目标为最小化肌肉激活度平方和(权重:1.0)与动作持续时间(权重:1.0)。初始状态被设定为蹲姿[74],最终状态被设定为直立站姿。没有使用动捕的运动数据。该模型包含了躯干和9块肌肉驱动的单右腿,其中6块肌肉设置有顺应性肌腱动力学(腘绳肌、股直肌、股外侧肌、腓肠肌、比目鱼肌和胫骨前肌)。为了简化将模拟双腿合为一腿,力量加倍。足部与地面设定为焊接接触,进行了简化。模型中包含了先前mocoInverse相同的髌骨的运动学约束,初始猜测值是变量界限的中点,肌肉激励和激活的初始猜测值是0.05。起立过程中,臀大肌、腘绳肌和股外侧肌等伸肌表现出了显著的活动性。

关节扭矩驱动与肌肉驱动的模型处理方法中,关节扭矩驱动会移除模型中的肌肉并添加致动器,肌肉驱动中,会对肌肉参数进行配置。

2. 代码逻辑

study(study.solve)_关节扭矩驱动的轨迹优化,或者说是运动预测

1. 导入.osim肌肉骨骼模型,创建MocoStudy和problem

2. 设置状态量和时间的边界条件,addGoal设置最小力为cost

3. 配置solver参数

4. study.solve()求解结果,并.write保存.sto运动轨迹数据predictSolution.sto,包含以下关节角度和速度状态量等条目/jointset/ankle_r/ankle_angle_r/value    /jointset/knee_r/knee_angle_r/value    /jointset/patellofemoral_r/knee_angle_r_beta/value    /jointset/hip_r/hip_flexion_r/value    /jointset/ankle_r/ankle_angle_r/speed    /jointset/knee_r/knee_angle_r/speed    /jointset/patellofemoral_r/knee_angle_r_beta/speed    /jointset/hip_r/hip_flexion_r/speed    /tau_hip_flexion_r    /tau_knee_angle_r    /tau_ankle_angle_r    lambda_cid4_p0    gamma_cid4_p0

track(MocoStateTrackingGoal)_关节扭矩驱动的追踪问题,以上面生成运动轨迹为参考

1.TableProcessor加载predictSolution.sto数据并滤波

2. MocoStateTrackingGoal载入TableProcessor数据并添加到addGoal,.setWeight设置cost项的权重

3. 配置study的solver,使用setGuessFile()载入生成的predictSolution.sto运动轨迹数据,作为初始猜测值,生成trackingSolution.sto数据。包含条目与predictSolution相同,都是关节坐标状态。

inverse(.MocoInverse)_肌肉驱动的逆动力问题,求解肌肉力量

1. 创建MocoInverse实例化

2. ModelProcessor加载模型,模型的自由度提供额外的驱动力,并加载到inverse中

3. setKinematics加载TableProcessor 作为运动参考

4. 配置inverse时间点,网格数等边界条件,以及肌肉激活度为目标

5. solve,并将运动数据保存到inverseSolution.sto中,包含以下条目内容# activation,# normalized_tendon_force,# joint angle,joint speed,# muscle force,reserve jointset force,# implicitderiv_normalized_tendon_force,包含状态量,tendon_force,muscle_force。inverseSolution.sto条目如下

/forceset/bifemsh_r/activation    /forceset/bifemsh_r/normalized_tendon_force    /forceset/med_gas_r/activation    /forceset/med_gas_r/normalized_tendon_force    /forceset/glut_max2_r/activation    /forceset/glut_max2_r/normalized_tendon_force    /forceset/psoas_r/activation    /forceset/psoas_r/normalized_tendon_force    /forceset/rect_fem_r/activation    /forceset/rect_fem_r/normalized_tendon_force    /forceset/semimem_r/activation    /forceset/semimem_r/normalized_tendon_force    /forceset/soleus_r/activation    /forceset/soleus_r/normalized_tendon_force    /forceset/tib_ant_r/activation    /forceset/tib_ant_r/normalized_tendon_force    /forceset/vas_int_r/activation    /forceset/vas_int_r/normalized_tendon_force    /jointset/ankle_r/ankle_angle_r/value    /jointset/ankle_r/ankle_angle_r/speed    /jointset/knee_r/knee_angle_r/value    /jointset/knee_r/knee_angle_r/speed    /jointset/patellofemoral_r/knee_angle_r_beta/value    /jointset/patellofemoral_r/knee_angle_r_beta/speed    /jointset/hip_r/hip_flexion_r/value    /jointset/hip_r/hip_flexion_r/speed    /forceset/bifemsh_r    /forceset/med_gas_r    /forceset/glut_max2_r    /forceset/psoas_r    /forceset/rect_fem_r    /forceset/semimem_r    /forceset/soleus_r    /forceset/tib_ant_r    /forceset/vas_int_r    /forceset/reserve_jointset_knee_r_knee_angle_r    /forceset/reserve_jointset_ankle_r_ankle_angle_r    /forceset/reserve_jointset_hip_r_hip_flexion_r    lambda_cid4_p0    /forceset/bifemsh_r/implicitderiv_normalized_tendon_force    /forceset/med_gas_r/implicitderiv_normalized_tendon_force    /forceset/glut_max2_r/implicitderiv_normalized_tendon_force    /forceset/psoas_r/implicitderiv_normalized_tendon_force    /forceset/rect_fem_r/implicitderiv_normalized_tendon_force    /forceset/semimem_r/implicitderiv_normalized_tendon_force    /forceset/soleus_r/implicitderiv_normalized_tendon_force    /forceset/tib_ant_r/implicitderiv_normalized_tendon_force    /forceset/vas_int_r/implicitderiv_normalized_tendon_force

6. 使用STOFileAdapter工具,将inverseSolution导出到muscleOutputs.sto。muscleOutputs.sto文件包含以下每条肌肉的fiber_length和passive_force条目,单纯与肌肉相关。

/forceset/bifemsh_r|normalized_fiber_length    /forceset/bifemsh_r|passive_force_multiplier    /forceset/med_gas_r|normalized_fiber_length    /forceset/med_gas_r|passive_force_multiplier    /forceset/glut_max2_r|normalized_fiber_length    /forceset/glut_max2_r|passive_force_multiplier    /forceset/psoas_r|normalized_fiber_length    /forceset/psoas_r|passive_force_multiplier    /forceset/rect_fem_r|normalized_fiber_length    /forceset/rect_fem_r|passive_force_multiplier    /forceset/semimem_r|normalized_fiber_length    /forceset/semimem_r|passive_force_multiplier    /forceset/soleus_r|normalized_fiber_length    /forceset/soleus_r|passive_force_multiplier    /forceset/tib_ant_r|normalized_fiber_length    /forceset/tib_ant_r|passive_force_multiplier    /forceset/vas_int_r|normalized_fiber_length    /forceset/vas_int_r|passive_force_multiplier

inverse_器械辅助下的肌肉驱动逆问题,求解器械辅助力

主要是修改模型,在膝盖坐标添加一个SpringGeneralizedForce弹簧阻尼模型。

1. 在knee_angle_r关节添弹簧元件,并添加到模型中

2. 模型中添加1个reserve actuators

3. inverse.solve求解,并保存inverseDeviceSolution.sto运动数据结果

4. getObjective获取最终cost,并画图,inverseSolution对比inverseDeviceSolution,观察肌肉激活度,肌腱力tendon_force的对比

/forceset/bifemsh_r/activation    /forceset/bifemsh_r/normalized_tendon_force    /forceset/med_gas_r/activation    /forceset/med_gas_r/normalized_tendon_force    /forceset/glut_max2_r/activation    /forceset/glut_max2_r/normalized_tendon_force    /forceset/psoas_r/activation    /forceset/psoas_r/normalized_tendon_force    /forceset/rect_fem_r/activation    /forceset/rect_fem_r/normalized_tendon_force    /forceset/semimem_r/activation    /forceset/semimem_r/normalized_tendon_force    /forceset/soleus_r/activation    /forceset/soleus_r/normalized_tendon_force    /forceset/tib_ant_r/activation    /forceset/tib_ant_r/normalized_tendon_force    /forceset/vas_int_r/activation    /forceset/vas_int_r/normalized_tendon_force    /jointset/ankle_r/ankle_angle_r/value    /jointset/ankle_r/ankle_angle_r/speed    /jointset/knee_r/knee_angle_r/value    /jointset/knee_r/knee_angle_r/speed    /jointset/patellofemoral_r/knee_angle_r_beta/value    /jointset/patellofemoral_r/knee_angle_r_beta/speed    /jointset/hip_r/hip_flexion_r/value    /jointset/hip_r/hip_flexion_r/speed    /forceset/bifemsh_r    /forceset/med_gas_r    /forceset/glut_max2_r    /forceset/psoas_r    /forceset/rect_fem_r    /forceset/semimem_r    /forceset/soleus_r    /forceset/tib_ant_r    /forceset/vas_int_r    /forceset/reserve_jointset_knee_r_knee_angle_r    /forceset/reserve_jointset_ankle_r_ankle_angle_r    /forceset/reserve_jointset_hip_r_hip_flexion_r    lambda_cid4_p0    /forceset/bifemsh_r/implicitderiv_normalized_tendon_force    /forceset/med_gas_r/implicitderiv_normalized_tendon_force    /forceset/glut_max2_r/implicitderiv_normalized_tendon_force    /forceset/psoas_r/implicitderiv_normalized_tendon_force    /forceset/rect_fem_r/implicitderiv_normalized_tendon_force    /forceset/semimem_r/implicitderiv_normalized_tendon_force    /forceset/soleus_r/implicitderiv_normalized_tendon_force    /forceset/tib_ant_r/implicitderiv_normalized_tendon_force    /forceset/vas_int_r/implicitderiv_normalized_tendon_force

# 第0部分:加载Moco库和opensim内置模型
import opensim as osim
import exampleSquatToStand_helpers as helpers
import mocoPlotTrajectory as plot
import os
import numpy as np
# 导入扭矩驱动模型和肌肉驱动模型
torqueDrivenModel = helpers.getTorqueDrivenModel()
muscleDrivenModel = helpers.getMuscleDrivenModel()## Part 1: 求解关节扭矩驱动的预测问题,即由起始位置生成中间运动
# Part 1a: 创建MocoStudy类
study = osim.MocoStudy()# Part 1b: 获取problem引用并加载模型
problem = study.updProblem()
problem.setModel(torqueDrivenModel)# Part 1c: 边界设置
#
# 时间边界输入参数格式problem.setTimeBounds(initial_bounds, final_bounds)
# 状态量边界输出参数格式problem.setStateInfo(path, trajectory_bounds, inital_bounds, final_bounds)
#
# 所有边界参数可以设置为一个范围, [lower upper]; 或一个数值,表示上下界相等,或空的符号[],表示默认值;
# 可以同时设置多个状态setStateInfoPattern(),格式如下:
# problem.setStateInfoPattern(pattern, trajectory_bounds, inital_bounds, ...
#       final_bounds)
#
# setStateInfoPattern函数支持“pattern”参数中的正则表达式;
# 使用'.*'匹配状态/控制路径的任何子字符串,例如,以下将设置所有坐标值状态信息:
# problem.setStateInfoPattern('/path/to/states/.*/value', ...)# 时间边界设置[0, 1],1秒之内从蹲到站起
problem.setTimeBounds(0, 1)# 位置约束: 模型需要从蹲姿开始并以站姿结束
# 设定了了三个关节角度,
# 髋关节屈曲角度,膝关节角度,踝关节角度
# 关节角度上下界,初始位置上下界,和结束位置的上下界
# 髋关节屈曲角度,关节角度上下界[-114.59°, 28.65°],初始值-114.59°,结束0°
problem.setStateInfo('/jointset/hip_r/hip_flexion_r/value', [-2, 0.5], -2, 0)
problem.setStateInfo('/jointset/knee_r/knee_angle_r/value', [-2, 0], -2, 0)
problem.setStateInfo('/jointset/ankle_r/ankle_angle_r/value', [-0.5, 0.7], -0.5, -0.1)# 速度界限:所有坐标 在开始和结束是都是静止
problem.setStateInfoPattern('/jointset/.*/speed', [], 0, 0)# 添加控制量作为cost项,命名为myeffort
problem.addGoal(osim.MocoControlGoal('myeffort'))# 配置求解器
# 前两行是必须的
solver = study.initCasADiSolver()
solver.set_num_mesh_intervals(25)
# 后面的选择项,可以不设置
solver.set_optim_convergence_tolerance(1e-4)
solver.set_optim_constraint_tolerance(1e-4)# 如果'predictSolution.sto'这个文件不存在,执行求解并保存新的
if not os.path.isfile('predictSolution.sto'):# Part 1f: Solve! Write the solution to file, and visualize.predictSolution = study.solve()predictSolution.write('predictSolution.sto')# study.visualize(predictSolution)## Part 2: 扭矩驱动的追踪问题,即给出运动轨迹参考
# 使用上述预测结果,使用TableProcessor加载数据,并低通滤波
# 将滤波数据,追加到tableProcessor中
tableProcessor = osim.TableProcessor('predictSolution.sto')
tableProcessor.append(osim.TabOpLowPassFilter(6))# 使用MocoStateTrackingGoal将状态量作为Cost
# 生成的预测的TableProcessor作为参考轨迹
# 启用setAllowUnusedReference忽略不需要的列数据
tracking = osim.MocoStateTrackingGoal()
tracking.setName('mytracking')
tracking.setReference(tableProcessor)
tracking.setAllowUnusedReferences(True)
problem.addGoal(tracking)# Part 2c: 使用track时,为了追踪轨迹的误差更小,一般会减小控制量惩罚项的权重
problem.updGoal('myeffort').setWeight(0.001)# Part 2d: 使用predictSolution.sto作为初始猜测值
solver.setGuessFile('predictSolution.sto')
# 减小收敛公差,以确保平稳控制。
solver.set_optim_convergence_tolerance(1e-6)# 如果'trackingSolution.sto'这个文件不存在,执行求解并保存新的
if not os.path.isfile('trackingSolution.sto'):# Part 2e: Solve! Write the solution to file, and visualize.trackingSolution = study.solve()trackingSolution.write('trackingSolution.sto')# study.visualize(trackingSolution)## Part 3: 对比 Predictive与Tracking结果
# 使用绘图函数mocoPlotTrajectory.m,加载.sto运动数据文件
plot.mocoPlotTrajectory('predictSolution.sto', 'trackingSolution.sto', 'predict', 'track')## Part 4: 肌肉驱动的逆动力问题,求解肌肉力量
# MocoInverse实例化
inverse = osim.MocoInverse()# 使用ModelProcessor加载.osim肌肉骨骼模型,可以通过.append操作符来修改模型
modelProcessor = osim.ModelProcessor(muscleDrivenModel)
# 将备用执行器添加到模型中,给模型的自由度提供额外的驱动力或控制
# 添加model,operation,AddReserves
# 2为optimalForce,该自由度最大的力
modelProcessor.append(osim.ModOpAddReserves(2))
# 将配置完成的模型选项给到MocoInverse实例中	
inverse.setModel(modelProcessor)# 使用TableProcessor 作为运动参考
inverse.setKinematics(tableProcessor)# Part 4c: Set the time range, mesh interval, and convergence tolerance.
# 初始时间0s,终止时间1s,间隔为0.05s.
inverse.set_initial_time(0)
inverse.set_final_time(1)
inverse.set_mesh_interval(0.05)
#后面两行可以不设置
inverse.set_convergence_tolerance(1e-4)
inverse.set_constraint_tolerance(1e-4)# 默认情况下,运动学数据包含额外的列,Moco会报错。
# 在这里,告诉Moco允许(并忽略)这些额外的列。
inverse.set_kinematics_allow_extra_columns(True)
# 设置肌肉激活程度最小
inverse.set_minimize_sum_squared_activations(True)# 设定特定肌肉结果的关键字属性,设置muscleOutputs.sto文件的表头
inverse.append_output_paths('.*normalized_fiber_length')
inverse.append_output_paths('.*passive_force_multiplier')# Part 4d: 求解! 将结果进行保存到 inverseSolution.sto文件中
# 内容是如下,每列个表头为一列数据
# activation,
# normalized_tendon_force,
# joint angle,joint speed,
# muscle force,reserve jointset force, 
# implicitderiv_normalized_tendon_force
inverseSolution = inverse.solve()
solution = inverseSolution.getMocoSolution()
solution.write('inverseSolution.sto')# Part 4e: 将inverse结果写入到 muscleOutputs.sto中
# 内容是每个肌肉的fiber_length和passive_force_multiplier
inverseOutputs = inverseSolution.getOutputs()
sto = osim.STOFileAdapter()
sto.write(inverseOutputs, 'muscleOutputs.sto')## Part 5: 器械辅助下的肌肉驱动逆问题,求解器械辅助力
# Part 5a: 修改肌肉驱动模型,膝盖坐标添加一个SpringGeneralizedForce。# 在knee_angle_r广义坐标上添加一个弹簧阻尼组件,输入坐标名称
device = osim.SpringGeneralizedForce('knee_angle_r')
device.setStiffness(50)
device.setRestLength(0)
device.setViscosity(0)
# 在模型中添加力组件
muscleDrivenModel.addForce(device)# Part 5b: Create a ModelProcessor similar to the previous one, using the same
# reserve actuator strength so we can compare muscle activity accurately.
# 修改后的模型,加载到ModelProcessor,添加储备执行器强度,比较是否器械情况下的肌肉情况
modelProcessor = osim.ModelProcessor(muscleDrivenModel)
modelProcessor.append(osim.ModOpAddReserves(2))
inverse.setModel(modelProcessor)# Part 5c:固定格式,求解! 获取结果并保存
inverseDeviceSolution = inverse.solve()
deviceSolution = inverseDeviceSolution.getMocoSolution()
deviceSolution.write('inverseDeviceSolution.sto')## Part 6: 比较无辅助和辅助情况下的逆问题结果
print('Cost without device: ', solution.getObjective())
print('Cost with device: ', deviceSolution.getObjective())# 使用此函数进行方便的结果对比画图
helpers.compareInverseSolutions(inverseSolution, inverseDeviceSolution)

4. 关节扭矩驱动与肌肉驱动的模型处理方法

模型的预处理封装在exampleSquatToStand_helpers.py中供直接使用,此处只截取模型处理部分进行注释说明。


def addCoordinateActuator(model, coordName, optForce):"""向给定的生物力学模型添加坐标致动器参数:- model:生物力学模型对象。- coordName:要添加致动器的坐标名称,要与.osim文件"Coordinate name=**"中一致- optForce:最大扭矩值。"""# 获取模型的关节坐标集coordSet = model.updCoordinateSet()# 创建一个坐标致动器actu = osim.CoordinateActuator()# 设置致动器的名称actu.setName('tau_' + coordName)# setCoordinate将致动器关联到特定的坐标actu.setCoordinate(coordSet.get(coordName))# setOptimalForce设置致动器的最大扭矩actu.setOptimalForce(optForce)# 输入的control的最小/小控制值,一般设置inf,.osim中有对应属性actu.setMinControl(-1)actu.setMaxControl(1)# 将致动器添加到模型中model.addComponent(actu)def getTorqueDrivenModel():# 加载基础模型model = osim.Model('squatToStand_3dof9musc.osim')# 移除模型中的肌肉model.updForceSet().clearAndDestroy()model.initSystem()# 向模型的关节自由度上添加坐标致动器addCoordinateActuator(model, 'hip_flexion_r', 150)addCoordinateActuator(model, 'knee_angle_r', 300)addCoordinateActuator(model, 'ankle_angle_r', 150)return modeldef getMuscleDrivenModel():# 加载基础模型model = osim.Model('squatToStand_3dof9musc.osim')# 进行重载,完成模型的连接model.finalizeConnections()# 使用DeGrooteFregly提出的肌肉替换原模型,# 它们的特性曲线针对Direct Collocation法进行了优化(即无间断点、二次可微等)osim.DeGrooteFregly2016Muscle().replaceMuscles(model)# 通过强化模型和加宽主动力-长度曲线,使问题更容易求解# 遍历模型中的所有肌肉,对于每个肌肉有如下操作for m in np.arange(model.getMuscles().getSize()):musc = model.updMuscles().get(int(m))# 设置最小控制值为 0musc.setMinControl(0.0)# 设置不忽略激活动力学,即使用肌肉激活动力学和肌腱顺应性musc.set_ignore_activation_dynamics(False)musc.set_ignore_tendon_compliance(False)# 将最大等长力设置为原来的两倍,例子中只考虑身体一半的右腿musc.set_max_isometric_force(2.0 * musc.get_max_isometric_force())# 肌肉转换为dgf = osim.DeGrooteFregly2016Muscle.safeDownCast(musc)# 肌肉主动力-长度曲线(Muscle Active Force-Length Curve)中# 设置肌肉主动力宽度为 1.5倍dgf.set_active_force_width_scale(1.5)# 肌腱的顺应性动力学模型设置为隐式形式dgf.set_tendon_compliance_dynamics_mode('implicit')# 忽略比目鱼肌“soleus_r”被动纤维力,被动纤维力对应具有刚性# 因为比目鱼肌肌腱很长,比目鱼肌肌腱不具有被动纤维力,即没有刚性,为纯柔性# 否则,因为纤维长度,会产生过多的被动纤维力# 设置后,soleus_r_passive_force列的值都为0if str(musc.getName()) == 'soleus_r':dgf.set_ignore_passive_fiber_force(True)return model

这篇关于使用Moco工具生成人体蹲起运动并分析辅助器械作用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1122686

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]