0%

AI算法库API-V1

自动摘要: >修订历史 |时间|版本号|修订人|主要修订内容| ||||| |20220616|1.0 ……..

修订历史

时间 版本号 修订人 主要修订内容
2022-06-16 1.0.0 杨新 模板设定
2022-06-16 1.0.1 罗依蒙 整体文档结构安排
2022-06-17 1.0.2 罗依蒙 文档结构安排调整
2022-6-18 1.0.3 罗依蒙 文档结构敲定与分牙数据函数开始整合
2022-6-22 1.0.4 罗依蒙 全冠代码整理
2022-6-23 1.0.5 罗依蒙 全冠代码整理
2022-6-25 1.1.6 罗依蒙 全冠代码完善
2022-6-29 1.1.7 罗依蒙 全冠代码完善与部署类部分代码整理
2022-7-1 1.1.8 罗依蒙 部署类部分代码整理
2022-7-4 1.1.9 罗依蒙 部署类部分代码整理
2022-7-5 1.1.10 罗依蒙 部署类部分代码整理
2022-7-6 1.1.11 罗依蒙 部署类代码存在的疑问的修正
2022-7-7 1.2.12 罗依蒙 部署类代码整理完善
2022-7-8 1.2.13 罗依蒙 现有的分牙代码整理
2022-7-15 1.2.14 罗依蒙 添加“一键式”目录与FullCrown的run函数
2022-7-27 1.2.15 罗依蒙 嵌体部分代码整理
2022-8-1 1.2.16 罗依蒙 嵌体部分代码修改
2022-8-2 1.2.17 罗依蒙 完善函数注释

算法库链接

http://192.168.1.55/up3d/AI

APIImage measurement

蓝色字体是相对于原始代码更改的说明
棕色字体是对代码内容的疑问
橘色是对代码数据或输入输出注意点的说明

数据处理类-DataProcess

用于数据处理的一些函数,根据数据格式等的不同划分为3D数据处理、2D数据处理、文本数据处理以及图像数据处理。根据业务不同分为全冠数据处理、分牙数据处理

全冠数据处理-FullCrown

对原始数据进行隐式曲面处理,生成torch需要的数据

AI.Repair.FullCrown.init(self, user_path=None, torch_path=None, pt_path=None, generate_path=None,batch_size=167800)

1
2
3
4
5
6
7
8
9
10
def __init__(self, user_path=None, torch_path=None user_path, torch_path, pt_path=None, generate_path=None,batch_size=167800):
"""
定义FullCrown

:param user_path: (str)用户数据目录,其目录下的Object与Preparation内的文件名一一对应,默认None
:param torch_path: (str)torch数据输出目录/训练数据目录,默认None
:param pt_path: (str)历史/前一周期训练结果文件,默认None
:param generate_path: (str)推理数据目录,默认None
:param batch_size: (int)批量大小,默认 167800
"""

AI.Repair.FullCrown.mesh_split(self,mesh:trimesh.Trimesh)->list

1
2
3
4
5
6
7
def mesh_split(self, mesh:trimesh.Trimesh)->list:
"""
根据连通体,进行分割牙位,注意:只针对南航数据特性

:param mesh: (trimesh.Trimesh)含3个连通体的网格数据
:return: ((3,)trimesh.Trimesh)返回从左到右的三个连通体的list
"""

AI.Repair.FullCrown.normalize_meshes(self,mesh)

1
2
3
4
5
6
7
def normalize_meshes(self, mesh):
"""
归一化到[-0.45,0.45]

:param mesh: (trimesh.base.Trimesh)需要归一化的原始牙模型
:return: (trimesh.base.Trimesh)归一化后的牙模型
"""

AI.Repair.FullCrown.get_mid(self,sources_path=None, target_path=None)

1
2
3
4
5
6
7
8
def get_mid(self, sources_path=None, target_path=None):
"""
获取目标模型的中间牙

:param sources_path: (str)源路径
:param target_path: (str)目标路径
:return: (trimesh.base.Trimesh)中间牙模型
"""

AI.Repair.FullCrown.data_process(self,ply_path: str, get_two_teeth: bool = True, resolution:int = 32, pcd_samples_num:int=100000, sigma:float = 0.1, sources_path=None) -> np.array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def data_process(self,ply_path: str, get_two_teeth: bool = True, resolution:int = 32, pcd_samples_num:int=100000,
sigma:float = 0.1, sources_path=None) -> np.array:
"""
处理ply数据
对两颗牙(含中间的基台)的源模型:获取两颗牙(不含中间基台)的数据
对三颗牙的目标模型:目标牙的样本点在其模型上的占用率

:param ply_path: (str)ply数据路径
:param get_two_teeth: (bool)是否要通过连通体进行裁剪成两个牙冠
:param resolution: (int)针对两个牙冠(源)体素进行采样的采样率 [32,64,128,256] 默认32
:param pcd_samples_num: (int)生成部位(目标)采样率 [100k,200k,300k,400K] 默认100k
:param sigma: (float)生成部位(目标)边界采样噪声方差 [ [0.1, 0.01]] 默认0.1
:param sources_path: (str)源模型的数据路径,默认None

when get_two_teeth==Ture
:return: data: ((n,n,n)bool)处理后的原始牙的体素栅格

when get_two_teeth==False
:return: data: ((n,)bool)目标牙的样本点在模型上的占用率
:return: pcd_n: (trimesh.caching.TrackedArray)样本点
"""

AI.Repair.FullCrown.process(self,user_path=None,torch_path=None) -> None:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def process(self,user_path=None,torch_path=None) -> None:
"""
对原始数据进行隐式曲面处理,生成torch需要的数据

步骤:
1.遍历X目录,载入待修复的牙冠
2.对x1,,Xn 进行均值归一化,并将中间的基台去除(对需求无帮助,即噪声)
3.对y1,,Yn 进行均值归一化
4.对处理的数据打包成pt格,放入指定路径下,方便直接于DataLoader加载数据

:param user_path: (str)用户数据目录,其目录下的Object与Preparation内的文件名一一对应,默认None(使用FullCrown对象的user_path)
:param torch_path: (str)torch数据输出目录/训练数据目录,默认None
:return: None
"""

AI.Repair.FullCrown.create_bounds(self,min=-0.45, max=0.45, res=256)

1
2
3
4
5
6
7
8
9
def create_bounds(self,min=-0.45, max=0.45, res=256):
"""
生成边界

:param min: (float)最小值,默认-0.45
:param max: (float)最大值,默认0.45
:param res: (int)在min到max范围内划分的个数
:return:points_list ((n, 3)float64)有效范围内各个点的坐标集合
"""

分牙数据处理-MeshSeg

AI.MeshSeg.MeshSeg.init(self, dataset_path,batch_size=12, save_path=”MeshSeg.pt”, num_workers=12):

1
2
3
4
5
6
7
8
9
10
def __init__(self, dataset_path,batch_size=12, save_path="MeshSeg.pt", num_workers=12):
"""
定义MeshSeg

:param dataset_path: (str)分牙数据目录
:param batch_size: (int)批量大小,默认12
:param save_path: (str)分牙结果存储,默认"MeshSeg.pt"
:param num_workers: (int)线程数,默认12
:return:None
"""

AI.MeshSeg.MeshSeg.dataProcessing(self):

1
2
3
4
5
6
def dataProcessing(self):
"""
数据处理

pass
"""

模型搭建类-Building

按模型形式分为点云/网格/体素模型、图像模型以及文本模型

点云模型-PointCloud

网格模型-Mesh

体素模型-Voxel

图像模型-Image

文本模型-Text

模型训练类-Training

按训练流程分为数据分割、优化器选择、损失函数选择以及模型保存按业务分为全冠训练、

AI.Repair.FullCrown.train(self, torch_path=None, pt_path=None,batch_size=1,num_workers=1,start_epoch=0,end_epoch=15000,shuffle=True):

1
2
3
4
5
6
7
8
9
10
11
12
13
def train(self, torch_path=None, pt_path=None,batch_size=1,num_workers=1,start_epoch=0,end_epoch=15000,shuffle=True):
"""
进行训练

:param torch_path: (str)torch数据输出目录/训练数据目录,默认None(使用FullCrown对象的torch_path)
:param pt_path: (str)历史/前一周期训练结果文件,默认None(使用FullCrown对象的pt_path)
:param batch_size: (int)批量大小,默认1
:param num_workers: (int)线程数,默认1
:param start_epoch: (int)训练起始周期,默认0
:param end_epoch: (int)训练结束周期,默认15000
:param shuffle: (bool)是否打乱顺序,默认Ture
:return:None
"""

AI.Segmentation.MeshSeg.train(self,num_epochs=2000):

1
2
3
4
5
6
7
def train(self,num_epochs=2000):
"""
模型训练

:param num_epochs: (int)训练周期,默认2000
:return: None
"""

AI.DentalInlay.DentalInlay.train(dataroot=None,,checkpoints_dir=”C:\“,batch_size=8, name=”dental_pix2pix”, model_type=”pix2pix”):

1
2
3
4
5
6
7
8
9
10
11
def train(dataroot=None,checkpoints_dir="C:\\",batch_size=8, name="dental_pix2pix", model_type="pix2pix"):
"""
实现嵌体生成训练

:param dataroot:(str)参与训练的图片目录,默认None
:param checkpoints_dir:(str)生成的pth文件存储的目录,默认"C:\\"
:param batch_size:(int)批量大小,默认8
:param name:(str)训练的模型与样本所存储的文件夹的名称,默认"dental_pix2pix"
:param model_type:(str)模型类型,默认pix2pix
:return:None
"""

原始代码中是每五周期保存一份当前周期的训练结果文件并更新latest_net_D.pth与latest_net_G.pth,由于这样会导致整个文件夹内容过大现仅实现更新训练生成的pth文件存储在:checkpoints_dir/name训练过程中的图片存储目录:checkpoints_dir / name + ‘/web/images’推理生成的html存储目录:checkpoints_dir / name + ‘/web’

数据分割-DataPartition

优化器选择-Optimizer

损失函数选择-LossFunction

推理类-Inference

按目的分为分割推理、分类推理、生成推理以及检测推理

分割推理-Segmentation

分类推理-Classification

生成推理-Generation

AI.Repair.FullCrown.generate_pcd(self,mesh_path,out_path)

1
2
3
4
5
6
7
8
def generate_pcd(self,mesh_path,out_path):
"""
实现单份点云模型的生成推理

:param mesh_path(str): 未修复模型的路径
:param out_path(str): 生成模型的输出路径
:return:None
"""

AI.Repair.FullCrown.generate_vol(self,mesh_path,out_path)

1
2
3
4
5
6
7
8
9
def generate_vol(self,mesh_path,out_path,batch_size=167800):
"""
实现单份体素模型的生成推理

:param mesh_path: (str)未修复模型的路径
:param out_path: (str)生成模型的输出路径
:param batch_size: (int)批量大小,默认167800
:return: None
"""

AI.Repair.FullCrown.generate_all_vol(self,generate_path=None,pt_path=None):

1
2
3
4
5
6
7
8
def generate_all_vol(self,generate_path=None,pt_path=None):
"""
实现整个目录下模型的生成推理,调用的是generate_vol

:param generate_path: (str)推理数据目录,默认None(使用FullCrown对象的generate_path)
:param pt_path: (str)历史/前一周期训练结果文件,默认None(使用FullCrown对象的pt_path)
:return:None
"""

AI.DentalInlay.DentalInlay.inference(dataroot=None, checkpoints_dir=”C:/“,name=”experiment_name”,direction=”BtoA”):

1
2
3
4
5
6
7
8
9
10
def inference(dataroot=None, checkpoints_dir="C:/",name="dental_pix2pix",direction="BtoA"):
"""
实现嵌体生成推理,onnx模型生成

:param dataroot:(str)参与推理的图片目录
:param checkpoints_dir:(str)训练生成的pth文件存储的目录,默认"C:\\"
:param name:(str)推理的模型所存储的文件夹的名称,默认"dental_pix2pix"
:param direction:(str)推理方向,默认BtoA
:return:None
"""

生成的onnx文件存储目录:checkpoints_dir / name推理生成的图片输出目录:’./results_dir/‘ + name + ‘/test_last/images’推理生成的html输出目录:’./results_dir/‘ + name + ‘/test_last’在计算平均SSIM时,原本sum += i,现改为sum += 1

AI.DentalInlay.DentalInlay.Inference_model(onnx_path,dataroot=None,name=”dental_pix2pix”,direction=” BtoA”)

1
2
3
4
5
6
7
8
9
10
def Inference_model(checkpoints_dir="C:/",dataroot=None,name="dental_pix2pix",direction=" BtoA"):
"""
利用.onnx模型实现嵌体生成推理

:param checkpoints_dir:(str)onnx模型存储的目录,默认"C:\\"
:param dataroot:(str)参与推理的图片目录
:param name:推理的模型所存储的文件夹的名称,默认"dental_pix2pix"
:param direction:(str)推理方向,默认BtoA
:return:None
"""

调用的onnx文件的存储目录:checkpoints_dir / name推理生成的图片输出目录: 当前文件所在的目录下

检测推理-Measurement

显示类-Show

AI.Repair.FullCrown.show(self,sources_path,target_path)

1
2
3
4
5
6
7
8
def show(self,sources_path,target_path):
"""
实现单份数据的原始数据与推理结果显示

:param sources_path: (str)原始地址
:param target_path: (str)修复后模型的地址
:return: None
"""

AI.Repair.FullCrown.show_all(self,generate_path=None):

1
2
3
4
5
6
7
def show_all(self,generate_path=None):
"""
实现整个地址路径下的所有原始数据与推理结果显示

:param generate_path: (str)推理数据目录,默认None(使用FullCrown对象的generate_path)
:return: None
"""

一键式-Run

全冠生成

AI.Repair.FullCrown.run(self,process:bool = True,train:bool = True,generate:bool = True,show:bool = True):

1
2
3
4
5
6
7
8
9
10
def run(self,process:bool = True,train:bool = True,generate:bool = True,show:bool = True):
"""
包括训练在内的整个流程实现:数据处理->训练->推理->显示

:param process: (bool)是否进行数据处理,默认True
:param train: (bool)是否进行训练,默认True
:param generate: (bool)是否进行模型推理,默认True
:param show: (bool)是否进行显示,默认True
:return: None
"""

部署类-Deploy

自定义的相关工具-Tools

AI.Deploy.Tools.NpEncoder.default(self, obj)

1
2
3
4
5
6
7
def default(self, obj):
"""
自定义json编码器

:param obj:编译对象
:return:目标格式的对象
"""

AI.Deploy.Tools.DictToJson(data,out_path=”out.json”)

1
2
3
4
5
6
7
8
def DictToJson(data,out_path="out.json"):
"""
将字典保存为json格式保存

:param data:需要保存的数据
:param out_path: (str)保存地址,默认out.json
:return: None
"""

AI.Deploy.Tools.json_to_ply(json_path:str,out_dir)

1
2
3
4
5
6
7
8
def json_to_ply(json_path:str,out_dir):
"""
将分牙json字典,转发成ply输出

:param json_path: (str)json字典路径
:param out_dir: (str)ply输出输出路径
:return: None
"""

AI.Deploy.Tools.show_json(json_path)

1
2
3
4
5
6
7
def show_json(json_path):
"""
将json结果进行渲染显示

:param json_path: (str)json字典路径
:return: None
"""

正畸部署-OrthodonticDeploy

class ToothSeg:

调用AI模型进行分牙实现: 数据处理;推理;结果优化;

AI.Deploy.OrthodonticDeploy.ToothSeg.init(self, mesh_path, model_path,devices=’CPUExecutionProvider’, num_classes=15):

1
2
3
4
5
6
7
8
9
10
def __init__(self, mesh_path, model_path, devices='CPUExecutionProvider',
num_classes=15):
"""
定义ToothSeg

:param mesh_path:(str)需要分牙的网格的路径
:param model_path:(str)分牙模型的路径
:param devices:(str)模型推理设备,默认'CPUExecutionProvider'
:param num_classes:(int)当前模型支持分割类数,默认15
"""

AI.Deploy.OrthodonticDeploy.ToothSeg._remove_overlapping_triangles(self,m: trimesh.Trimesh):

1
2
3
4
5
6
7
def _remove_overlapping_triangles(self,m:  trimesh.Trimesh) -> trimesh.Trimesh:
"""
删除重叠的三角面片

:param m : (trimesh.Trimesh)需要处理的网格模型
:return cleaned_mesh :(trimesh.Trimesh)清除重叠面片后的网格模型
"""

原注释为“删除重叠的三角面片”,实际是对共面的相邻面进行处理,面片数会增加,则其原本的目的是什么?@sindre(sindre)

AI.Deploy.OrthodonticDeploy.ToothSeg.prepare(self):

1
2
3
4
5
6
def ToothSeg.prepare(self):
"""
实现模型预处理,包括删除离群点与重复面片,

:return:None
"""
  1. 正则化特征[-1,1]的for循环内是正态分布向标准正态分布的转换过程,则原始面片与法线是怎样遵循正态分布的
  2. A_S&A_L设置的目的

AI.Deploy.OrthodonticDeploy.ToothSeg.infer(self, model_path):

1
2
3
4
5
6
7
def infer(self, model_path):
"""
推理

:param model_path: (str) 实现推理的模型地址
:return data: ([(1,n,15)float32])完成推理后的结果,其内容包括面片的三个点坐标、重心坐标以及法向量
"""

AI.Deploy.OrthodonticDeploy.ToothSeg.optimized(self, tensor_prob_output):

1
2
3
4
5
6
7
def optimized(self, tensor_prob_output):
"""
推理结果数据优化

:param tensor_prob_output: ([(1,n,15)float32])推理结果
:return data: ([(1,n,15)float32])精炼优化后的结果
"""

@sindre(sindre)

  1. beta的意义,常数(向量内积)取模的意义
  2. edges的第三个值(权重)的计算方式/公式
  3. is_upper的意义
  4. 267为什么会有零散的面片(nei==0),内含四个是“删除重叠面片”里添的,1-3是正常状态,此处处理的是预处理后的模型。

AI.Deploy.OrthodonticDeploy.ToothSeg.run(self, json_out_path):

1
2
3
4
5
6
7
def run(self, json_out_path):
"""
实现分牙的整个流程

:param json_out_path:(str)分牙结果的json输出地址
:return:None
"""

AI.Deploy.OrthodonticDeploy.ToothSeg.KNN(self, json_path, target_mesh_path, json_out_path):

1
2
3
4
5
6
7
8
9
def KNN(self, json_path, target_mesh_path, json_out_path):
"""
对结果进行knn映射

:param json_path: (str)当前分牙json文件
:param target_mesh_path: (str)目标mesh路径
:param json_out_path: (str)结果输出路径
:return: None
"""

class ToothArrange:

调用AI模型进行排牙实现:数据处理;推理;结果优化;

AI.Deploy.OrthodonticDeploy.ToothArrange.init(self, data_list, out_dir, model_path=”14牙弓.npy”):

1
2
3
4
5
6
7
8
9
def __init__(self, data_list, out_dir, model_path="14牙弓.npy"):
"""
定义ToothArrange

:param data_list (list): 需要排牙的牙齿teeth_list,文件命名需符合 _tooth_牙位号.ply
:param model_path (str): 目标排牙模型的路径
:param out_dir (str): 排牙后输出目录,默认"14牙弓.npy"

"""

AI.Deploy.OrthodonticDeploy.ToothArrange.prepare(self):

1
2
3
4
5
6
7
def prepare(self):
"""
读入原始牙齿模型

:return: None

"""

AI.Deploy.OrthodonticDeploy.ToothArrange.infer(self):

1
2
3
4
5
6
7
def infer(self):
"""
实现排牙

:return: None

"""

AI.Deploy.OrthodonticDeploy.ToothArrange.optimized(self):

1
2
3
4
5
6
7
def optimized(self):
"""
结果优化

pass

"""

AI.Deploy.OrthodonticDeploy.ToothArrange.run(self):

1
2
3
4
5
6
7
def run(self):
"""
实现排牙的整个流程

:return: None

"""

class GumGen:

通过模板牙龈进行牙列拟合,从而实现”牙龈生成”

AI.Deploy.OrthodonticDeploy.GumGen.init(self, teeth_list, gum_path, seg_list):

1
2
3
4
5
6
7
8
def __init__(self, teeth_list, gum_path, seg_list):
"""
定义GumGen

:param teeth_list: list(str)牙齿数据列表,需要 牙位号.ply 结尾
:param gum_path: (str)模板牙龈stl文件的路径
:param seg_list: (str)分割后牙列路径
"""

AI.Deploy.OrthodonticDeploy.GumGen.get_teeth_edge_points(self):

1
2
3
4
5
6
def get_teeth_edge_points(self):
"""
获取牙列网格与牙列数据

:return: None
"""

AI.Deploy.OrthodonticDeploy.GumGen.get_gum_edge_points(self):

1
2
3
4
5
6
def get_gum_edge_points(self):
"""
获取牙龈数据

:return: None
"""

AI.Deploy.OrthodonticDeploy.GumGen.fitting(self):

1
2
3
4
5
6
def fitting(self):
"""
原始的牙龈向目标牙进行匹配形变,生成形变后的牙龈网格

:return: None
"""

AI.Deploy.OrthodonticDeploy.GumGen.export(self, out_path):

1
2
3
4
5
6
7
def export(self, out_path):
"""
实现牙龈生成的整个流程并导出牙齿和牙龈

:param out_path: (str)文件输出路径
:return:None
"""

AI.Deploy.OrthodonticDeploy.GumGen.show(self):

1
2
3
4
5
6
def show(self):
"""
显示牙齿和牙龈

:return: None
"""

class Orthodontic:

正畸整个流程实现:数据修复–>分牙–>排牙–>生成牙龈

AI.Deploy.OrthodonticDeploy.Orthodontic.init(self, mesh_path, model_path,arrange_model):

1
2
3
4
5
6
7
8
def __init__(self, mesh_path, model_path,arrange_model):
"""
定义Orthodontic

:param mesh_path: (str)原始网格模型路径
:param model_path: (str)分牙模型路径
:param arrange_model: (str)标准牙弓线路径
"""

AI.Deploy.OrthodonticDeploy.Orthodontic.DataRepair(self):

1
2
3
4
5
6
def DataRepair(self):
"""
数据修复方法

pass
"""

AI.Deploy.OrthodonticDeploy.Orthodontic.ToothSeg(self, out_dir):

1
2
3
4
5
6
7
def ToothSeg(self, out_dir):
"""
牙齿分割

:param out_dir: (str)分牙后单颗牙的输出目录
:return:None
"""

AI.Deploy.OrthodonticDeploy.Orthodontic.ToothArrange(self, out_dir):

1
2
3
4
5
6
7
def ToothArrange(self, arrange_out_dir):
"""
牙齿排列

:param arrange_out_dir:(str)排牙后输出目录
:return:None
"""

AI.Deploy.OrthodonticDeploy.Orthodontic.GumsGen(self, gum_out_dir):

1
2
3
4
5
6
7
def GumsGen(self, gum_out_dir):
"""
牙龈生成

:param gum_out_dir: (str)牙龈生成后输出目录
:return:None
"""

AI.Deploy.OrthodonticDeploy.Orthodontic.run(self, gum_out_dir, arrange_out_dir, seg_out_dir):

1
2
3
4
5
6
7
8
9
def run(self, seg_out_dir, arrange_out_dir, gum_out_dir):
"""
实现正畸整个流程

:param seg_out_dir: (str)分牙后单颗牙的输出目录
:param arrange_out_dir: (str)排牙后输出目录
:param gum_out_dir: (str)牙龈生成后输出目录
:return:None
"""

AI.Deploy.OrthodonticDeploy.Orthodontic.ShowSeg(self):

1
2
3
4
5
6
7
def ShowSeg(self):
"""
显示分牙结果

pass

"""

AI.Deploy.OrthodonticDeploy.Orthodontic.ShowArrange(self):

1
2
3
4
5
6
7
def ShowArrange(self):
"""
显示排牙结果

pass

"""

欢迎关注我的其它发布渠道