123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935 |
- import os.path
- import sys
- from pathlib import Path
- from enum import Enum
- import clr
- import numpy as np
- import TrainSdk
- from ctypes import *
- import json
- import copy
- import onnxruntime
- # 设置当前路径和系统路径
- system_path = Path(sys.executable).resolve().parents[0]
- current_path = Path(__file__).resolve().parents[0]
- network_path = os.path.join(current_path, 'depends\\Networks')
- # 导入c#的dll
- clr.AddReference('System.Drawing')
- clr.AddReference(os.path.join(current_path, 'depends\\AI.Common.dll'))
- clr.AddReference(os.path.join(current_path, 'depends\\AI.DiagSystem.dll'))
- clr.AddReference(os.path.join(current_path, 'depends\\ImageShowUtilsLib.dll'))
- clr.AddReference(os.path.join(current_path, 'depends\\MyocardialSegmenLib.dll'))
- from System import Array
- import ctypes
- from System.Runtime.InteropServices import GCHandle, GCHandleType
- from System.Drawing import Bitmap
- from System.IO import MemoryStream
- from AI.Common import InferenceNetworkUtils, InferenceCore, EnumInferCoreConfigKey, EnumDeviceType
- from AI.Common import InferenceNetworkInputImage, RawImage, Rect, Point2D, IDetectedObject
- from AI.DiagSystem import *
- from AI.DiagSystem.Workers.InferenceNetworks.Onnx import InferNetOnnxLesionDetectBreastBIRads, \
- InferNetOnnxOrganDetectorAbdomen, InferNetOnnxScanPartClrBreastAbdomenNeck
- from AI.DiagSystem.Workers.InferenceNetworks.Onnx import InferNetOnnxLiverFocalObd, InferNetOnnxLiverDiffuseClr, \
- InferNetOnnxLiverFocalSeg, InferNetOnnxLesionContourSegLiver, InferNetOnnxLesionContourSegBreast, \
- InferNetOnnxOrganDetectorThyroidCarotidArtery
- from ImageShowUtilsLib import RawImageShowUtils
- from MyocardialSegmenLib import InferNetOnnxMyocardialSegment
- from AI.Common.Tools import UsImageRegionSegHelper
- # gt_file_generate import
- from gt_file_generate import gtfilegenerate_classifications, gtfilegenerate_classifications_liverdiffuselesionclassifier
- from gt_file_generate import gtfilegenerate_objectdetection, gtfilegenerate_objectdetection_liverfocalobd
- from gt_file_generate import gtfilegenerate_semantic_segmentation, gtfilegenerate_semantic_segmentation_myocardial, \
- gtfilegenerate_semantic_segmentation_liverfocalSeg
- # pred_file_generate import
- from predict_file_generate import predfilegenerate_classification
- from predict_file_generate import predfilegenerate_object_detection
- from predict_file_generate import predfilegenerate_semantic_segmentation, \
- predfilegenerate_semantic_segmentation_myocardial
- # metrics import
- from classification_metric import Evaluator_classification
- from object_detection_metric import Evaluator_object_detection
- from semantic_segmentation_metric import Evaluator_object_semamtic_segmentation
- class GtFileGenerateType(Enum):
- """
- 枚举所有Gt文件的生成方法
- """
- # 适用于:导航的分类网络,判断乳腺腹部等扫查部分分类网络
- gtfilegenerate_classifications = 1
- # 适用于:肝脏弥漫性疾病分类
- gtfilegenerate_classifications_liverdiffuselesionclassifier = 2
- # 适用于: 乳腺检测,
- gtfilegenerate_objectdetection = 3
- # 适用于: 脏器分割
- gtfilegenerate_semantic_segmentation = 4
- # 适用于: 心肌的语义分割
- gtfilegenerate_semantic_segmentation_myocardial = 5
- # 适用于:肝脏局灶性疾病检测
- gtfilegenerate_objectdetection_liverfocalobd = 6
- # 适用于:肝脏局灶性疾病分割
- gtfilegenerate_semantic_segmentation_liverfocalSeg = 7
- class PredFileGenerateType(Enum):
- """
- 枚举所有Pred文件的生成方法
- """
- predfilegenerate_classification = 1
- predfilegenerate_object_detection = 2
- predfilegenerate_semantic_segmentation = 3
- predfilegenerate_semantic_segmentation_myocardial = 4
- class MetricsType(Enum):
- """
- 枚举所有评价类型,分为分类,检测,语义分割
- """
- # 分类
- classification_metric = 1
- # 检测
- object_detection_metric = 2
- # 语义分割
- semantic_segmentation_metric = 3
- class ModelName(Enum):
- """
- 枚举所有模型的名称
- """
- # 乳腺腹部其他分类模型
- InferNetOnnxScanPartClrBreastAbdomenNeck = 1
- # 乳腺检测模型
- InferNetOnnxLesionDetectBreastBIRads = 2
- # 腹部脏器分割模型
- InferNetOnnxOrganDetectorAbdomen = 3
- # 腹部局灶性检测模型
- InferNetOnnxLiverFocalObd = 4
- # 腹部弥漫性分类模型
- InferNetOnnxLiverDiffuseClr = 5
- # 腹部局灶性分割模型
- InferNetOnnxLiverFocalSeg = 6
- # 心肌分割模型:
- InferNetOnnxMyocardialSegment = 7
- # 肝脏局灶病灶前后景分割模型
- InferNetOnnxLesionContourSegLiver = 8
- # 乳腺病灶前后景分割模型
- InferNetOnnxLesionContourSegBreast = 9
- # 颈部脏器分割模型
- InferNetOnnxOrganDetectorThyroidCarotidArtery = 10
- class PlatformMetrics:
- def __init__(self, token, network_path, is_python_model_onnxruntime, modelname, gtfilegeneratetpye,
- predfilegeneratetpye, metricstpye, iscropped,
- numcpu, is_crop_region_affect_image_nums, crop_region_label,
- needed_imageresults_dict, needed_rois_dict, class_id_map, iou_thres):
- """
- :param token: 平台所需的token
- :param network_path: 测试模型的路径
- :param is_python_model_onnxruntime: 是否调用python的onnxruntime
- :param modelname: 模型的名称
- :param gtfilegeneratetpye:选择所需的gtfile生成方法
- :param predfilegeneratetpye:选择所需的predfile生成方法
- :param metricstpye:选择所需的metrics方法
- :param iscropped:是否裁切
- :param numcpu:cpu推理数量
- :param is_crop_region_affect_image_nums:
- :param crop_region_label:需要crop region的roi标签title
- :param needed_imageresults_dict:所需的image标签title 对应 预测模型的label,所形成的字典
- :param needed_rois_dict: 所需的roi标签title 对应 预测模型的label,所形成的字典
- :param class_id_map: 用于label改变的dict
- :param iou_thres: iou阈值,分类时无用
- """
- self.token = token
- self.network_path = network_path
- self.is_python_model_onnxruntime = is_python_model_onnxruntime
- self.modelname = modelname
- self.gtfilegeneratetpye = gtfilegeneratetpye
- self.predfilegeneratetpye = predfilegeneratetpye
- self.metricstpye = metricstpye
- self.iscropped = iscropped
- self.numcpu = numcpu
- self.is_crop_region_affect_image_nums = is_crop_region_affect_image_nums
- self.crop_region_label = crop_region_label
- self.needed_imageresults_dict = needed_imageresults_dict
- self.needed_rois_dict = needed_rois_dict
- self.class_id_map = class_id_map
- self.iou_thres = iou_thres
- def process(self):
- inferNet = self._choose_model_name(self.modelname)
- trainedNetwork = InferenceNetworkUtils().ReadNetworkDataFromFile(self.network_path, inferNet.NetworkName,
- inferNet.HashCode)
- inferenceCore = InferenceCore()
- inferenceCore.SetConfig(EnumInferCoreConfigKey.CPU_THREADS_NUM, str(self.numcpu), EnumDeviceType.CPU)
- inferNet.LoadNetwork(inferenceCore, EnumDeviceType.CPU, trainedNetwork)
- gt_type = self._choose_gt_file_type(self.gtfilegeneratetpye)
- pred_type = self._choose_pred_file_type(self.predfilegeneratetpye)
- metric_type = self._choose_metrics_type(self.metricstpye)
- image_count = TrainSdk.get_test_file_count(self.token)
- # 如果是python的onnxruntime,需要解析相应名称的onnx模型,设置session
- if self.is_python_model_onnxruntime:
- networkname = inferNet.NetworkName.split(".emd")[0] + '.onnx'
- trainedNetwork_path = os.path.join(self.network_path, networkname)
- onnx_path = os.path.join(os.getcwd(), trainedNetwork_path)
- sess_options = onnxruntime.SessionOptions()
- sess_options.intra_op_num_threads = self.numcpu
- session = onnxruntime.InferenceSession(onnx_path, sess_options, providers=['CPUExecutionProvider'])
- input_name = session.get_inputs()[0].name
- evaluator = metric_type(self.iou_thres)
- for i in range(image_count):
- imagedata, labeldata, img_name, _ = TrainSdk.get_test_labeled_file(self.token, i)
- stream = MemoryStream()
- stream.Write(imagedata, 0, len(imagedata))
- bitmap = Bitmap(stream)
- # 取图像的width和height
- image_width = bitmap.Width
- image_height = bitmap.Height
- image_size = [image_width, image_height]
- rawimage = RawImageShowUtils.BitmapToRawImage(bitmap)
- croprect = self._crop_image(rawimage)
- label_infos = json.loads(labeldata)
- if self.is_crop_region_affect_image_nums:
- label_infos_split = self._label_infos_split(label_infos, self.crop_region_label)
- else:
- label_infos_split = [label_infos]
- for label_info_index in range(len(label_infos_split)):
- gt_json = gt_type(label_infos_split[label_info_index], image_size, self.needed_imageresults_dict,
- self.needed_rois_dict, self.class_id_map)
- gt_file = json.loads(gt_json)
- inferinput = self._set_input_image(rawimage, label_infos_split[label_info_index], croprect)
- inferNet.PreProcess(inferinput) # 调用前处理
- # 进行推理
- # 推理分两种,一种调用RunModel(),采用c#框架下的onnxruntime;
- # 另一种将前处理之后的databuffer做成python所需要的格式,送入python框架下的onnxruntime,然后将结果赋值给_detectedResultData
- if self.is_python_model_onnxruntime:
- inputvariableshape = list(inferNet._inputVariableShape)
- assert len(inputvariableshape) == 4, "onnx模型输入必须为4通道"
- # 一般的模型都是将inferNet._moldedImage.DataBuffer放入模型进行推理
- # 但是弥漫性疾病分类那边,采用的是四通道,需要重新生成inferNet._inputDataBuffer放入模型进行推理
- if inferNet._moldedImage.DataBuffer:
- img_in = inferNet._moldedImage.DataBuffer
- else:
- img_in = inferNet._inputDataBuffer
- # img_in2直接转成list再转numpy太慢
- src_hndl = GCHandle.Alloc(img_in, GCHandleType.Pinned)
- try:
- src_ptr = src_hndl.AddrOfPinnedObject().ToInt64()
- bufType = ctypes.c_float * len(img_in)
- cbuf = bufType.from_address(src_ptr)
- img_np = np.frombuffer(cbuf, dtype=cbuf._type_)
- finally:
- if src_hndl.IsAllocated:
- src_hndl.Free()
- img_np = img_np.reshape(
- inputvariableshape[0], inputvariableshape[1], inputvariableshape[2], inputvariableshape[3])
- outputs = session.run(None, {input_name: img_np})[0]
- inferNet._detectedResultData = outputs.reshape(1, outputs.size).ravel().tolist()
- else:
- inferNet.RunModel()
- # 调用后处理
- idetectedobject = inferNet.PostProcess(inferinput)
- # 调用inferNet中的PreProcess(inferinput),RunModel(),PostProcess(inferinput) 等价于调用Process(inferinput)
- # idetectedobject = inferNet.Process(inferinput)
- pred_json = pred_type(idetectedobject, image_size, self.class_id_map)
- pred_file = json.loads(pred_json)
- image_index = str(img_name)
- evaluator.add_batch(gt_file, pred_file, image_index)
- return evaluator
- def _crop_image(self, image):
- """
- 调用c#的裁图函数,得到裁图框
- :param image: RawImage图像
- :return:
- """
- rect = Rect(0, 0, image.Width, image.Height)
- if self.iscropped:
- return rect
- else:
- res, dst_rect = UsImageRegionSegHelper().CropWithCvCore(image, rect)
- if res:
- return dst_rect
- else:
- return rect
- def _set_input_image(self, rawimage, label_info, croprect):
- """
- 生成c#中所需要的InferenceNetworkInputImage
- #肝脏弥漫性标注时,会标注一个弥漫性疾病的轮廓,再标注一个肝脏的轮廓的情况
- #因此需要max_roi_area,最终的croporgancontours中只会存在一个轮廓
- #后续croporgancontours中,如果需要出现多个轮廓,可改写次处
- #croporgancontours的结果传入InferenceNetworkInputImage中,
- #当_useContoursAsMask为True时,InferenceNetworkUtils.GenMaskOnImageAccordingToContours需要轮廓信息
- #GenMaskOnImageAccordingToContours的c++函数,需要支持多轮廓的处理,暂时没有这种情况,未验证
- :param rawimage:
- :param label_info:
- :param croprect:
- :return:
- """
- labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
- use_crop_region = False
- croporganrect = Rect.Empty
- croporgancontours = Array[Array[Point2D]](())
- max_roi_area = 0
- for each_roi_label in labeled_result["Rois"]:
- roi_cls = each_roi_label["Conclusion"]["Title"]
- if roi_cls in self.crop_region_label:
- roi_points = each_roi_label["Points"]
- x, y, points = [], [], []
- for point in roi_points:
- point_x = int(point["X"])
- point_y = int(point["Y"])
- x.append(point_x)
- y.append(point_y)
- points.append(Point2D(point_x, point_y))
- left, right = min(x), max(x)
- top, bottom = min(y), max(y)
- points_ = Array[Point2D](points)
- roi_contour = Array[Array[Point2D]]([points_])
- roi_area = (right - left) * (bottom - top)
- if roi_area > max_roi_area:
- croporganrect = Rect(left, top, right - left, bottom - top)
- croporgancontours = roi_contour
- max_roi_area = roi_area
- use_crop_region = True
- if use_crop_region:
- inputroi = croporganrect
- else:
- inputroi = croprect
- inferinput = InferenceNetworkInputImage(rawimage, inputroi, 1.0, croporgancontours, croprect)
- return inferinput
- def _label_infos_split(self, label_info, crop_region_label):
- """
- 将label_info拆成不同的部分
- crop_region_affect_image_nums存在时,
- 一张图中,在crop_region_label中如果有多个目标,此时该图像已经不作为一张图使用,
- 需要逐个根据crop_region_label,逐个拆分所需的label_info
- :param label_info:
- :param crop_region_label:
- :return:
- """
- labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
- needed_roi_infos = []
- # 过一遍数据,取到所需要的crop_region_roi信息
- for each_roi_label in labeled_result["Rois"]:
- roi_cls = each_roi_label["Conclusion"]["Title"]
- if roi_cls in crop_region_label:
- needed_roi_infos.append(each_roi_label)
- if len(needed_roi_infos) <= 1:
- return [label_info]
- else:
- label_infos_split = []
- for i in range(len(needed_roi_infos)):
- new_info = copy.deepcopy(labeled_result)
- for j in range(len(needed_roi_infos)):
- if j != i:
- new_info["Rois"].remove(needed_roi_infos[j])
- label_infos_split.append(new_info)
- return label_infos_split
- @staticmethod
- def _choose_model_name(modelname):
- """
- 根据ModelName中枚举的各个模型名称,选择所对应的推理模型,即选择c#中相应的模型推断class
- :param modelname:
- :return:
- """
- # 乳腺检测模型
- if modelname == ModelName.InferNetOnnxLesionDetectBreastBIRads:
- inferNet = InferNetOnnxLesionDetectBreastBIRads()
- elif modelname == ModelName.InferNetOnnxOrganDetectorAbdomen:
- inferNet = InferNetOnnxOrganDetectorAbdomen()
- # 乳腺腹部其他分类模型
- elif modelname == ModelName.InferNetOnnxScanPartClrBreastAbdomenNeck:
- inferNet = InferNetOnnxScanPartClrBreastAbdomenNeck()
- # 腹部局灶性检测模型
- elif modelname == ModelName.InferNetOnnxLiverFocalObd:
- inferNet = InferNetOnnxLiverFocalObd()
- # 腹部弥漫性分类模型
- elif modelname == ModelName.InferNetOnnxLiverDiffuseClr:
- inferNet = InferNetOnnxLiverDiffuseClr()
- # 腹部局灶性分割模型
- elif modelname == ModelName.InferNetOnnxLiverFocalSeg:
- inferNet = InferNetOnnxLiverFocalSeg()
- # 心肌分割模型:
- elif modelname == ModelName.InferNetOnnxMyocardialSegment:
- inferNet = InferNetOnnxMyocardialSegment()
- elif modelname == ModelName.InferNetOnnxLesionContourSegLiver:
- inferNet = InferNetOnnxLesionContourSegLiver()
- elif modelname == ModelName.InferNetOnnxLesionContourSegBreast:
- inferNet = InferNetOnnxLesionContourSegBreast()
- # 颈部脏器分割模型:
- elif modelname == ModelName.InferNetOnnxOrganDetectorThyroidCarotidArtery:
- inferNet = InferNetOnnxOrganDetectorThyroidCarotidArtery()
- else:
- raise Exception("Wrong modelname, choose correct one")
- return inferNet
- @staticmethod
- def _choose_gt_file_type(gtfilegeneratetpye):
- """
- 根据GtFileGenerateType中枚举的各种生成Gt文件函数,选择对应的函数
- 函数在gt_file_generate.py中定义
- :param gtfilegeneratetpye:
- :return:
- """
- if gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_classifications_liverdiffuselesionclassifier:
- gt_type = gtfilegenerate_classifications_liverdiffuselesionclassifier
- elif gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_classifications:
- gt_type = gtfilegenerate_classifications
- elif gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_objectdetection:
- gt_type = gtfilegenerate_objectdetection
- elif gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_semantic_segmentation:
- gt_type = gtfilegenerate_semantic_segmentation
- elif gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_semantic_segmentation_myocardial:
- gt_type = gtfilegenerate_semantic_segmentation_myocardial
- elif gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_objectdetection_liverfocalobd:
- gt_type = gtfilegenerate_objectdetection_liverfocalobd
- elif gtfilegeneratetpye == GtFileGenerateType.gtfilegenerate_semantic_segmentation_liverfocalSeg:
- gt_type = gtfilegenerate_semantic_segmentation_liverfocalSeg
- else:
- raise Exception("Wrong gtfilegeneratetpye, choose correct one")
- return gt_type
- @staticmethod
- def _choose_pred_file_type(predfilegeneratetpye):
- """
- 根据GtFileGenerateType中枚举的各种生成Gt文件函数,选择对应的函数
- 函数在predict_file_generate.py中定义
- :param predfilegeneratetpye:
- :return:
- """
- if predfilegeneratetpye == PredFileGenerateType.predfilegenerate_classification:
- pred_type = predfilegenerate_classification
- elif predfilegeneratetpye == PredFileGenerateType.predfilegenerate_object_detection:
- pred_type = predfilegenerate_object_detection
- elif predfilegeneratetpye == PredFileGenerateType.predfilegenerate_semantic_segmentation:
- pred_type = predfilegenerate_semantic_segmentation
- elif predfilegeneratetpye == PredFileGenerateType.predfilegenerate_semantic_segmentation_myocardial:
- pred_type = predfilegenerate_semantic_segmentation_myocardial
- else:
- raise Exception("Wrong predfilegeneratetpye, choose correct one")
- return pred_type
- @staticmethod
- def _choose_metrics_type(metricstype):
- """
- 根据MetricsType中枚举的不同类型评价,选择所对应的,暂时只支持分类,检测,语义分割
- :param metricstype:
- :return:
- """
- if metricstype == MetricsType.classification_metric:
- metrics = Evaluator_classification
- elif metricstype == MetricsType.object_detection_metric:
- metrics = Evaluator_object_detection
- elif metricstype == MetricsType.semantic_segmentation_metric:
- metrics = Evaluator_object_semamtic_segmentation
- else:
- raise Exception("Wrong metrics tpye, choose correct one")
- return metrics
- if __name__ == '__main__':
- # 乳腺检测模型设置
- """
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxLesionDetectBreastBIRads
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_objectdetection
- metricstpye = MetricsType.object_detection_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_object_detection
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = []
- needed_imageresults_dict = {
- "未见明显异常": 0
- }
- needed_rois_dict = {
- '脂肪瘤': 1,
- 'BI-RADS 2': 2,
- 'BI-RADS 3': 3,
- 'BI-RADS 4a': 4,
- 'BI-RADS 4b': 5,
- 'BI-RADS 4c': 6,
- 'BI-RADS 5': 7,
- }
- class_id_map = {
- 0: 0,
- 1: 1,
- 2: 1,
- 3: 1,
- 4: 2,
- 5: 2,
- 6: 2,
- 7: 2
- }
- """
- # 脏器分割模型设置
- '''
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxOrganDetectorAbdomen
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_semantic_segmentation
- metricstpye = MetricsType.semantic_segmentation_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_semantic_segmentation
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = []
- needed_imageresults_dict = {}
- needed_rois_dict = {
- '肝': 3,
- '胆囊胆道': 4,
- '肾脏': 5,
- '脾脏': 6,
- }
- class_id_map = {
- 3: 3,
- 4: 4,
- 5: 5,
- 6: 6,
- }
- '''
- # 颈部脏器分割模型设置
- """
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxOrganDetectorThyroidCarotidArtery
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_semantic_segmentation
- metricstpye = MetricsType.semantic_segmentation_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_semantic_segmentation
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = []
- needed_imageresults_dict = {"无可标项": 0}
- needed_rois_dict = {
- "甲状腺横切": 9,
- "甲状腺纵切": 9,
- "颈动脉短轴": 8,
- "颈动脉长轴": 8,
- }
- class_id_map = {
- 0: 0,
- 8: 2,
- 9: 1,
- }
- """
- # 心肌分割模型设置
- # 心肌那边c#输出来的label只有0,预测结果那边设置了加一,因此有轮廓对应1
- '''
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxMyocardialSegment
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_semantic_segmentation_myocardial
- metricstpye = MetricsType.semantic_segmentation_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_semantic_segmentation_myocardial
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = []
- needed_imageresults_dict = {'非B模式图': 0, "其他切面": 0}
- needed_rois_dict = {
- '四腔心_心肌': 1,
- '心尖段_心肌': 1,
- '三腔心_心肌': 1,
- '基底段_心肌': 1,
- '乳头肌水平切面_心肌': 1,
- '两腔心_心肌': 1
- }
- class_id_map = {
- 0: 0,
- 1: 1
- }
- '''
- # 肝脏局灶性检测
- """
- # gt file生成时如果只出现弥漫性疾病,该图为背景;既出现局灶性疾病,又出现弥漫性疾病,为有疾病图像
- # gt file生成时如果只出现未见明显异常,为背景图像;如果出现未见明显异常,和局灶性疾病,该图像无效
- # gt file生成时如果出现弥漫性疾病和未见明显异常,则为背景图像
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxLiverFocalObd
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_objectdetection_liverfocalobd
- metricstpye = MetricsType.object_detection_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_object_detection
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = ["肝脏未见明显异常",
- "肝脏有局灶性疾病/区域",
- "脂肪肝声像图改变",
- "肝脏弥漫性病变声像图改变",
- "肝硬化声像图改变"]
- needed_imageresults_dict = {}
- needed_rois_dict = {
- "肝脏未见明显异常": 0,
- "肝脏有局灶性疾病/区域": 0,
- "脂肪肝声像图改变": 0,
- "肝脏弥漫性病变声像图改变": 0,
- "肝硬化声像图改变": 0,
- "肝内强回声灶": 1,
- "肝血管瘤声像图改变": 2,
- "肝囊肿": 3,
- "肝癌可能": 4
- }
- class_id_map = {
- 0: 0,
- 1: 1,
- 2: 2,
- 3: 3,
- 4: 4
- }
- """
- # 肝脏局灶性分割
- """
- # gt file生成时如果只出现弥漫性疾病,该图为背景;既出现局灶性疾病,又出现弥漫性疾病,为有疾病图像
- # gt file生成时如果只出现未见明显异常,为背景图像;如果出现未见明显异常,和局灶性疾病,该图像无效
- # gt file生成时如果出现弥漫性疾病和未见明显异常,则为背景图像
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxLiverFocalSeg
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_semantic_segmentation_liverfocalSeg
- metricstpye = MetricsType.semantic_segmentation_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_semantic_segmentation
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = ["肝脏未见明显异常",
- "肝脏有局灶性疾病/区域",
- "脂肪肝声像图改变",
- "肝脏弥漫性病变声像图改变",
- "肝硬化声像图改变",
- "肝血吸虫病声像图改变"]
- needed_imageresults_dict = {}
- needed_rois_dict = {
- "肝脏未见明显异常": 0,
- "肝脏有局灶性疾病/区域": 0,
- "脂肪肝声像图改变": 0,
- "肝脏弥漫性病变声像图改变": 0,
- "肝硬化声像图改变": 0,
- "肝血吸虫病声像图改变": 0,
- "肝内强回声灶": 1,
- "肝血管瘤声像图改变": 2,
- "肝囊肿": 3,
- "肝癌可能": 4
- }
- class_id_map = {
- 0: 0,
- 1: 1,
- 2: 2,
- 3: 3,
- 4: 4
- }
- """
- # 肝脏弥漫性疾病分类
- # 肝脏弥漫性分类,比较特殊,因为标注问题,会出现:标注一个肝的轮廓,再标注一个弥漫性疾病的情况,
- # 分类标签无法确定,根据rois标签的title,将'肝脏未见明显异常'删除
- """
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxLiverDiffuseClr
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_classifications_liverdiffuselesionclassifier
- metricstpye = MetricsType.classification_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_classification
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = ["肝脏未见明显异常",
- "多囊肝声像图改变",
- "脂肪肝声像图改变",
- "肝脏弥漫性病变声像图改变",
- "肝硬化声像图改变"]
- needed_imageresults_dict = {}
- needed_rois_dict = {
- "肝脏未见明显异常": 0,
- "多囊肝声像图改变": 8,
- "脂肪肝声像图改变": 5,
- "肝脏弥漫性病变声像图改变": 6,
- "肝硬化声像图改变": 7,
- }
- class_id_map = {
- 0: 0,
- 5: 5,
- 6: 6,
- 7: 7,
- 8: 8
- }
- """
- # 肝脏局灶性疾病前后景分割
- '''
- # 前后景分割时,
- # needed_rois_dict中的
- # {
- # "肝脏未见明显异常":0,
- # "肝脏有局灶性疾病/区域":0,
- # "脂肪肝声像图改变":0,
- # "肝脏弥漫性病变声像图改变":0,
- # "肝硬化声像图改变":0,
- # "肝血吸虫病声像图改变":0,
- # } 并没有用,因为没有给到病灶轮廓,会拿原图进行推理,没有意义
- # 建议设置的原因:gt file生成时辅助判断
- # 比如:如果出现未见明显异常,和局灶性疾病,该图像应该是无效的,没有设置上述的needed_rois_dict,则会当作有效进行推理
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = False
- modelname = ModelName.InferNetOnnxLesionContourSegLiver
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_semantic_segmentation_liverfocalSeg
- metricstpye = MetricsType.semantic_segmentation_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_semantic_segmentation
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = True
- crop_region_label = ["肝内强回声灶", "肝血管瘤声像图改变", "肝囊肿", "肝癌可能"]
- needed_imageresults_dict = {}
- needed_rois_dict = {
- "肝脏未见明显异常": 0,
- "肝脏有局灶性疾病/区域": 0,
- "脂肪肝声像图改变": 0,
- "肝脏弥漫性病变声像图改变": 0,
- "肝硬化声像图改变": 0,
- "肝血吸虫病声像图改变": 0,
- "肝内强回声灶": 1,
- "肝血管瘤声像图改变": 1,
- "肝囊肿": 1,
- "肝癌可能": 1
- }
- class_id_map = {
- 0: 0,
- 1: 1,
- }
- '''
- # 乳腺病灶前后景分割
- '''
- # 前后景分割时,needed_imageresults_dict = {"未见明显异常": 0}并没有用,因为没有给到病灶轮廓,
- # 会拿原图进行推理,没有意义
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = False
- modelname = ModelName.InferNetOnnxLesionContourSegBreast
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_semantic_segmentation
- metricstpye = MetricsType.semantic_segmentation_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_semantic_segmentation
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = True
- crop_region_label = ["脂肪瘤", "BI-RADS 2", 'BI-RADS 3', 'BI-RADS 4a','BI-RADS 4b', 'BI-RADS 4c', 'BI-RADS 5']
- needed_imageresults_dict = {"未见明显异常": 0}
- needed_rois_dict = {
- '脂肪瘤': 1,
- 'BI-RADS 2': 1,
- 'BI-RADS 3': 1,
- 'BI-RADS 4a': 1,
- 'BI-RADS 4b': 1,
- 'BI-RADS 4c': 1,
- 'BI-RADS 5': 1,
- }
- class_id_map = {
- 0:0,
- 1:1,
- }
- '''
- # 乳腺腹部颈部等脏器分类 导航扫查分类分类 两者一致
- # 不同测试时,只需修改模型
- # 暂时导航那边的模型导入dll未更新,后续更新可加入
- # 没有拿到脏器分类的数据,写了导航那边的标签,测试脏器分类的模型
- """
- token = "4925EC4929684AA0ABB0173B03CFC8FF"
- is_python_model_onnxruntime = True
- modelname = ModelName.InferNetOnnxScanPartClrBreastAbdomenNeck
- gtfilegeneratetpye = GtFileGenerateType.gtfilegenerate_classifications
- metricstpye = MetricsType.classification_metric
- predfilegeneratetpye = PredFileGenerateType.predfilegenerate_classification
- iscropped = True
- numcpu = 1
- is_crop_region_affect_image_nums = False
- crop_region_label = []
- needed_imageresults_dict = {
- "肝脏剑突纵扫标准面": 0,
- "肝脏剑突纵扫偏上": 1,
- "肝脏剑突纵扫偏下": 1,
- "肝脏剑突纵扫偏左": 1,
- "肝脏剑突纵扫偏右": 2,
- "肝脏剑突纵扫无效": 3}
- needed_rois_dict = {}
- class_id_map = {
- 0: 0,
- 1: 1,
- 2: 2,
- 3: 3
- }
- """
- test_result = PlatformMetrics(
- token=token,
- network_path=network_path,
- is_python_model_onnxruntime=is_python_model_onnxruntime,
- modelname=modelname,
- gtfilegeneratetpye=gtfilegeneratetpye,
- predfilegeneratetpye=predfilegeneratetpye,
- metricstpye=metricstpye,
- iscropped=iscropped,
- numcpu=numcpu,
- is_crop_region_affect_image_nums=is_crop_region_affect_image_nums,
- crop_region_label=crop_region_label,
- needed_imageresults_dict=needed_imageresults_dict,
- needed_rois_dict=needed_rois_dict,
- class_id_map=class_id_map,
- iou_thres=0.5,
- )
- evaluator = test_result.process()
- print("--------------------------------------可用图像report--------------------------------------")
- wrong_file = evaluator.wrong_file
- print("gt file有问题的image:{}".format(wrong_file['gt_wrong']))
- print("pred file有问题的image:{}".format(wrong_file['pred_wrong']))
- all_image_dict = evaluator.all_image_dict
- print("如果is_crop_region_affect_image_nums为True,所有的图像数量大于等于原图的数量")
- print('所有可用的图像数量:{}'.format(all_image_dict['images_all_nums']))
- print("--------------------------------------背景图像report--------------------------------------")
- background_images_results_count = evaluator.background_images_results_count
- for key in background_images_results_count.keys():
- print(key + ':' + str(background_images_results_count[key]))
- background_images_results = evaluator.background_images_results
- for key in background_images_results.keys():
- print(key + ':' + str(background_images_results[key]))
- print("--------------------------------------非背景图像report--------------------------------------")
- print('非背景图像数量:{}'.format(
- all_image_dict['images_all_nums'] - background_images_results_count['background_images_all_nums']))
- metricsPerClass = evaluator.generate_metrics()
- for mc in metricsPerClass:
- c = mc['class']
- precision = mc['precision']
- recall = mc['recall']
- # ipre = mc['interpolated precision']
- # irec = mc['interpolated recall']
- total_positives = mc['total positives']
- total_TP = mc['total TP']
- total_FP = mc['total FP']
- precision_all = 0 if (total_TP + total_FP) == 0 else total_TP / (total_TP + total_FP)
- recall_all = 0 if total_positives == 0 else total_TP / total_positives
- # Print AP per class
- print('Label:%s, total_TP: %d, total_FP: %d, total_positives_gt: %d, precision: %f, recall: %f '
- % (c, total_TP, total_FP, total_positives, precision_all, recall_all))
- try:
- average_precision = mc['AP']
- print('Label:%s, AP: %f, ' % (c, average_precision))
- except:
- continue
- all_no_background_images_fp_results = evaluator.all_no_background_images_fp_results
- for key in all_no_background_images_fp_results.keys():
- each_result = all_no_background_images_fp_results[key]
- print('Label:' + key + ',FP对应的image:' + str(each_result))
- all_no_background_images_pos_results = evaluator.all_no_background_images_pos_results
- all_no_background_images_tp_results = evaluator.all_no_background_images_tp_results
- for key in all_no_background_images_pos_results.keys():
- each_pos_results = all_no_background_images_pos_results[key]
- if key in all_no_background_images_tp_results.keys():
- each_tp_results = all_no_background_images_tp_results[key]
- else:
- each_tp_results = []
- if key in all_no_background_images_fp_results.keys():
- each_fp_results = all_no_background_images_fp_results[key]
- else:
- each_fp_results = []
- each_fn_results = []
- for elem in each_pos_results:
- if elem not in each_tp_results:
- each_fn_results.append(elem)
- print('Label:' + key + ',FN对应的image:' + str(each_fn_results))
|