深度学习与图像处理(PaddlePaddle版)课件6.实例分割_第1页
深度学习与图像处理(PaddlePaddle版)课件6.实例分割_第2页
深度学习与图像处理(PaddlePaddle版)课件6.实例分割_第3页
深度学习与图像处理(PaddlePaddle版)课件6.实例分割_第4页
深度学习与图像处理(PaddlePaddle版)课件6.实例分割_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章实例分割(肾小球影像分析仪)模型训练C++DLL生成C#界面设计主讲人:朱会杰、钱彬内容安排任务概述01.算法原理02.算法研发03.C#工控程序部署04.PART01任务概述任务概述----任务背景01肾小球病理切片是病理标本的一种,医生通过对病理切片的观察,可以定位出切片中的肾小球位置,统计肾小球的数量,评估每个肾小球的健康状态,进而判断病人肾炎的类别与程度病理切片中肾小球的精确识别是诊断肾脏病变程度的关键,本章将采用实例分割算法来完成任务概述----实例分割概述01本章将使用PaddleDetection套件中的实例分割算法MaskRCNN来完成肾小球影像分析任务PART02算法原理算法原理----实例分割概述02MaskRCNN作为该领域开山之作,最具有里程碑意义。MaskRCNN为两阶段检测框架:第一个阶段扫描图像并生成候选区域proposals(即有可能包含一个目标的区域);第二阶段对候选框进一步分类和调整,生成更精细的边界框和掩码。MaskRCNN=FasterRCNN+FCN算法原理----实例分割概述02使用双线性内插的方法获得坐标为浮点数的像素点上的图像数值,从而将整个特征聚集过程转化为一个连续的操作通过ROIAlign操作可以把RPN生成并筛选后的框所对应的区域全部变成用户需要大小的特征图算法原理----实例分割概述02左边为FasterRCNN+ResNet,右边为FasterRCNN+FPNMaskRCNN最后的任务就是对这些ROIAlign后的特征图作进一步的分类、定位和分割。分类和定位的实现原理和RPN算法相同PART03算法研发算法研发----数据集准备03该数据集采用外径在100μm至300μm之间的探针来收集组织样本,然后使用4μm的组织切片制备石蜡块,并使用碘酸-希夫(PAS)进行染色,最后使用LeicaAperioScanScopeCS扫描仪对组织样本进行20倍放大扫描。。肾小球医学影像数据集原始网址/datasets/k7nvtgn2x6/3具有31个完整切片的原始图像数据,数据格式为svs,每张图像大小为21651×10498像素至49799×3235像素之间,每张图像包含不同类型的肾小球,检测到的肾小球位于DATASET_B数据集中;DATASET_A包括2340张png格式的肾小球图像,每张图像仅包含1个肾小球,所有图像均匀分成两类,即正常肾小球和硬化肾小球。DATASET_B算法研发----数据集准备03通过OpenSlide读取图像并进行切块保存,完整的处理脚本代码如下(PaddleDetection/crop_imgs.py):importcv2importnumpyasnpimportos#引入openslide驱动库OPENSLIDE_PATH=r'C:\Users\openslide-win64-20221217\bin'#指定openslide可执行程序路径ifhasattr(os,'add_dll_directory'):withos.add_dll_directory(OPENSLIDE_PATH):importopenslideelse:importopenslide#参数定义srcfolder='./dataset/DATASET_A_DIB'#原始图像文件夹路径patchW=2048#采样图像子块宽度patchH=2048#采样图像子块高度算法研发----数据集准备03数据标注算法研发----数据集准备03/light_of_july/PaddleDetectiongitclone/light_of_july/PaddleDetection.git1.下载PaddleDetection2.配置Pycharm等编译器 conda环境

设置默认环境数据转化算法研发----数据集准备03具体转换过程参照以下步骤:(1)将所有的jpg格式的图像文件放在同一个目录下,如dataset/wsi/images目录下;(2)将所有标注好的json文件放在同一个目录下,如dataset/wsi/annotations目录下;(3)使用PaddleDetection套件提供的转换脚本进行转换,命令如下:3.数据格式转化为COCO格式pythontools/x2coco.py\--dataset_typelabelme\--json_input_dir./dataset/wsi/annotations/\--image_input_dir./dataset/wsi/images/\--output_dir./dataset/wsi_coco/\--train_proportion0.9\--val_proportion0.1\--test_proportion0.0dataset_type:数据集类型,此处对应labelme;json_input_dir:标注好的json文件路径;image_input_dir:图像文件路径;output_dir:转换后的数据集存储路径;train_proportion:训练集比例;val_proportion:验证集比例;test_proportion:测试集比例;算法研发----数据集准备03基础配置在base中主配置优先级更高1.MaskRCNN的配置文件2.本案例参考

综合考虑检测精度和速度要求,本书参考配置文件mask_rcnn_r50_vd_fpn_ssld_1x_coco.yml进行修改和使用。resnet50可变形卷积FPN自我蒸馏模型配置算法研发----模型训练03############################数据集设置#######################################metric:COCO#数据类型,用于评价算法性能num_classes:2#数据集的类别数(不包括背景)TrainDataset:name:COCODataSet#数据集类型image_dir:train#训练集图像数据路径,相对于dataset_dir的路径anno_path:annotations/instance_train.json#标注文件路径,相对于dataset_dir的路径dataset_dir:./dataset/wsi_coco#数据文件夹相对路径data_fields:['image','gt_bbox','gt_class','gt_poly','is_crowd']#使用的标注项目EvalDataset:name:COCODataSet#数据集类型image_dir:val#验证集图像数据路径,相对于dataset_dir的路径anno_path:annotations/instance_val.json#标注文件路径,相对于dataset_dir的路径dataset_dir:./dataset/wsi_coco#数据文件夹相对路径TestDataset:name:ImageFolderanno_path:annotations/instance_val.json#标注文件路径,相对dataset_dir的路径ddataset_dir:./dataset/wsi_coco#测试集数据文件夹相对路径算法研发----模型训练03############################运行时设置#######################################use_gpu:true#是否使用gpuuse_xpu:falseuse_mlu:falseuse_npu:falselog_iter:20#日志打印间隔save_dir:output#训练模型保存的相对路径snapshot_epoch:5#模型保存间隔print_flops:false#是否打印flopsprint_params:false#是否打印网络参数算法研发----模型训练03PART04C#工控程序部署C#工控程序部署----C++DLL生成04环境准备首先工控机电脑需要配置有可以运行模型的独立显卡,软件需要安装显卡驱动、CUDA、cuDNN、TensorRT以及下载PaddleInference预测库。/inference/user_guides/download_lib.html对应CUDA版本为11.6(实测11.8版本也可以兼容),cuDNN版本为8.4,TensorRT版本为。安装完成后还需要下载zlib库,解压后将zlibwapi.lib文件拷贝到C:\ProgramFiles\NVIDIAGPUComputingToolkit\CUDA\v11.x\lib文件夹中,同时将zlibwapi.dll文件拷贝到C:\ProgramFiles\NVIDIAGPUComputingToolkit\CUDA\v11.x\bin文件夹中,其中11.x为读者的CUDA版本号。VisualStudio2019下载地址(请使用本书第五章提供的vs2019安装文件)https:///zh-cn/visualstudio/releases/2019/release-notesC#工控程序部署----C++DLL生成04VisualStudio2022介绍2022安装流程,请使用vs2019C#工控程序部署----C++DLL生成04VisualStudio2019C#工控程序部署----C++DLL生成04VisualStudio2019C#工控程序部署----C++DLL生成04VisualStudio2019如果安装的是vs2022,在右侧的C++的桌面开发中,勾选上msvc2019版本C#工控程序部署----C++DLL生成04VisualStudio2019C#工控程序部署----C++DLL生成04

Cmake/download/C#工控程序部署----C++DLL生成04

Cmake/download/C#工控程序部署----C++DLL生成04

Cmake/download/C#工控程序部署----C++DLL生成04

Cmake/download/C#工控程序部署----C++DLL生成04

Cmake/download/C#工控程序部署----C++DLL生成04OpenCV/blog/release/opencv-3-4-6/C#工控程序部署----C++DLL生成04OpenCV/blog/release/opencv-3-4-6/下载完成后双击exe解压缩文件将“……\opencv\build\x64\vc1x\bin”添加到环境变量中C#工控程序部署----C++DLL生成04

使用CMake编译C++工程C#工控程序部署----C++DLL生成04

使用CMake编译C++工程CUDA_LIB:C:/ProgramFiles/NVIDIAGPUComputingToolkit/CUDA/v11.8/lib/x64CUDNN_LIB:C:/ProgramFiles/NVIDIAGPUComputingToolkit/CUDA/v11.8/lib/x64OPENCV_DIR:D:/book_maskrcnn/opencvPADDLE_DIR:D:/book_maskrcnn/paddle_inferencePADDLE_LIB_NAME:paddle_inferenceTENSORRT_INC_DIR:C:/ProgramFiles/NVIDIAGPUComputingToolkit/CUDA/v11.8/includeTENSORRT_LIB:C:/ProgramFiles/NVIDIAGPUComputingToolkit/CUDA/v11.8/lib/x64C#工控程序部署----C++DLL生成04

编译可执行文件1.Debug模式调整为Release模式2.生成解决方案:“生成”→“重新生成解决方案”C#工控程序部署----C++DLL生成04

编译可执行文件OpenCV4.0及以上的版本,生成解决方案时会提示错误,需要将main.cc的代码:

intvideo_width=static_cast<int>(capture.get(CV_CAP_PROP_FRAME_WIDTH));intvideo_height=static_cast<int>(capture.get(CV_CAP_PROP_FRAME_HEIGHT));intvideo_fps=static_cast<int>(capture.get(CV_CAP_PROP_FPS));intvideo_frame_count=static_cast<int>(capture.get(CV_CAP_PROP_FRAME_COUNT));修改为:

intvideo_width=static_cast<int>(capture.get(cv::CAP_PROP_FRAME_WIDTH));intvideo_height=static_cast<int>(capture.get(cv::CAP_PROP_FRAME_HEIGHT));intvideo_fps=static_cast<int>(capture.get(cv::CAP_PROP_FPS));intvideo_frame_count=static_cast<int>(capture.get(cv::CAP_PROP_FRAME_COUNT));将compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);修改为:compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);C#工控程序部署----C++DLL生成04

编译可执行文件将object_detector.cc中的代码:

cv::reduce(mask_fp,colSum,0,CV_REDUCE_SUM,CV_32FC1);cv::reduce(mask_fp,rowSum,1,CV_REDUCE_SUM,CV_32FC1);修改为:

cv::reduce(mask_fp,colSum,0,cv::REDUCE_SUM,CV_32FC1);cv::reduce(mask_fp,rowSum,1,cv::REDUCE_SUM,CV_32FC1);C#工控程序部署----C++DLL生成04

编译可执行文件首先使用CPU推理模式验证生成的程序是否正确:.\main--model_dir=D:/book_maskrcnn/model_pics/maskrcnn--device=CPU--image_file=D:/book_maskrcnn/model_pics/demo.jpg然后再使用GPU和TensorRT加速:.\main--model_dir=D:/book_maskrcnn/model_pics/maskrcnn--device=GPU--run_mode=trt_fp32--run_benchmark--image_file=D:/book_maskrcnn/model_pics/demo.jpgC#工控程序部署----C++DLL生成04首先使用CPU推理模式验证生成的程序是否正确:.\main--model_dir=D:/book_maskrcnn/model_pics/maskrcnn--device=CPU--image_file=D:/book_maskrcnn/model_pics/demo.jpg然后再使用GPU和TensorRT加速:.\main--model_dir=D:/book_maskrcnn/model_pics/maskrcnn--device=GPU--run_mode=trt_fp32--run_benchmark--image_file=D:/book_maskrcnn/model_pics/demo.jpg

编译可执行文件C#工控程序部署----C++DLL生成04

编译C++动态链接库代码修改:1.main.cc:保留原来的include部分不变,其余代码删除或注释掉。2.定义一个PaddleDetection::ObjectDetector类的对象指针PaddleDetection::ObjectDetector*det;//定义全局变量det指针C#工控程序部署----C++DLL生成04

编译C++动态链接库代码核心部分划分为两个接口函数,一个是模型的初始化,一个是推理。C++变量C#变量char*stringunsignedchar*byte[]intint(1)初始化模型模型初始化参数:运行设备、batchsize大小等,模型路径作为函数的输入参数C#工控程序部署----C++DLL生成04

编译C++动态链接库//全局参数intFLAGS_batch_size=1;//batch_size大小,这里为1boolFLAGS_use_gpu=true;//是否使用GPUstd::stringFLAGS_device="GPU";//使用什么设备,可以设置为CPU、GPUstd::stringFLAGS_run_mode="trt_fp32";//可选(paddle/trt_fp32/trt_fp16/trt_int8)boolFLAGS_use_mkldnn=true;boolFLAGS_trt_calib_mode=true;intFLAGS_gpu_id=0;//GPU序号intFLAGS_cpu_threads=1;//CPU线程数intFLAGS_trt_min_shape=1;intFLAGS_trt_max_shape=1440;intFLAGS_trt_opt_shape=640;doubleFLAGS_threshold=0.5;//置信度阈值C#工控程序部署----C++DLL生成04

编译C++动态链接库//模型初始化函数intMask_Init(char*model_dir){try{det=newPaddleDetection::ObjectDetector(model_dir,FLAGS_device,FLAGS_use_mkldnn,FLAGS_cpu_threads,FLAGS_run_mode,FLAGS_batch_size,FLAGS_gpu_id,FLAGS_trt_min_shape,FLAGS_trt_max_shape,FLAGS_trt_opt_shape,FLAGS_trt_calib_mode);return1;}catch(...){return-1;}}C#工控程序部署----C++DLL生成04

编译C++动态链接库(2)推理函数将unsignedchar数据转化为OpenCV的mat格式数据,然后进行推理,最后再将mat格式数据转化为unsignedchar数据返回。为了提高运行效率,只传递数据的位置以及数据大小,尽量减少数据复制带来的运算C#工控程序部署----C++DLL生成04

编译C++动态链接库C#工控程序部署----C++DLL生成04intMask_Infer(unsignedchar*srcData,intsrcWidth,intsrcHeight,intsrcStride,unsignedchar*dstData,intdstWidth,intdstHeight,intdstStride){try{//将输入和输出数据初始化为mat格式

cv::Matim(srcHeight,srcWidth,CV_8UC3,srcData,srcStride);cv::Matim_out(dstHeight,dstWidth,CV_8UC3,dstData,dstStride);

//初始化推理设置

constintbatch_size=FLAGS_batch_size;constdoublethreshold=FLAGS_threshold;std::vector<cv::Mat>batch_imgs;batch_imgs.insert(batch_imgs.end(),im);std::vector<PaddleDetection::ObjectResult>result;std::vector<int>bbox_num;std::vector<double>det_times;det->Predict(batch_imgs,threshold,0,1,&result,&bbox_num,&det_times);//推理

autolabels=det->GetLabelList();//类别标签

autocolormap=PaddleDetection::GenerateColorMap(labels.size());//获得颜色图

std::vector<PaddleDetection::ObjectResult>im_result;intdetect_num=0;

编译C++动态链接库//挑选出大于阈值的结果保存在im_result中

for(intj=0;j<bbox_num[0];j++){PaddleDetection::ObjectResultitem=result[j];if(item.confidence<threshold||item.class_id==-1){continue;}detect_num+=1;im_result.push_back(item);printf("class=%dconfidence=%.4frect=[%d%d%d%d]\n",item.class_id,item.confidence,item.rect[0],item.rect[1],item.rect[2],item.rect[3]);}

C#工控程序部署----C++DLL生成04

编译C++动态链接库cv::Matim_vis=PaddleDetection::VisualizeResult(im,im_result,labels,colormap,false);//将结果绘画在原图上

cv::resize(im_vis,im_out,im_out.size());//将图片大小重置为输出结果限定大小

return1;}catch(...){return-1;}}C#工控程序部署----C++DLL生成04

代码测试与链接库编译//main函数用于验证函数是否有误,便于调试intmain(intargc,char**argv){//读取图片

char*img_path="D:/book_maskrcnn/model_pics/demo.jpg";cv::Matim=cv::imread(img_path,1);intimgHeight=im.rows;intimgWidth=im.cols;//初始化输入输出数据

unsignedchar*input_data=newunsignedchar[4096*4096*3];memcpy(input_data,im.data,im.total()*im.elemSize());unsignedchar*output_data=newunsignedchar[4096*4096*3];char*model_dir="D:/book_maskrcnn/model_pics/maskrcnn";intinit=Mask_Init(model_dir);//初始化模型

//模型推理

intinfer=Mask_Infer(input_data,imgWidth,imgHeight,imgWidth*3,output_data,imgWidth,imgHeight,imgWidth*3);//对输出结果进行格式转换并保存

cv::Matim_out=cv::Mat(imgHeight,imgWidth,CV_8UC3);memcpy(im_out.data,output_data,imgHeight*imgWidth*3);cv::imwrite("./output.jpg",im_out);std::cout<<"图片保存为:output.jpg"<<std::endl;system("pause");return0;}C#工控程序部署----C++DLL生成04

代码测试与链接库编译动态链接库导出声明,一般放置在代码最前面://声明动态链接库导出extern"C"__declspec(dllexport)intMask_Init(char*model_dir);extern"C"__declspec(dllexport)intMask_Infer(unsignedchar*srcData,intsrcWidth,intsrcHeight,intsrcStride,unsignedchar*dstData,intdstWidth,intdstHeight,intdstStride);修改CMakeLists.txt,将生成可执行文件修改为生成动态链接库:#add_executable(main${SRCS})#注释掉生成可执行文件命令ADD_library(mainSHARED${SRCS})#生成链接库,添加生成链接库命令C#工控程序部署----C++DLL生成04

界面设计1.创建Windows窗体应用创建新项目,搜索C#,选择Windows窗口应用C#工控程序部署----编写C#工程04

界面设计1.创建Windows窗体应用输入名字,选择路径添加3个Button控件(“打开图片”、“初始化模型”和“推理”)和2个PictureBox控件(Size为400*400),SizeMode为StretchImageC#工控程序部署----编写C#工程04

界面设计1.创建Windows窗体应用输入名字,选择路径添加3个Button控件(“打开图片”、“初始化模型”和“推理”)和2个PictureBox控件(Size为400*400),SizeMode为StretchImageC#工控程序部署----编写C#工程04

界面设计1.C#代码编写publicpartialclassForm1:Form中添加以下代码publicpartialclassForm1:Form{//导入动态链接库函数

publicclassModel{[DllImport("main.dll")]publicexternstaticintMask_Init(stringmodel_path);[DllImport("main.dll")]publicstaticexternintMask_Infer(byte[]srcData,intsrcWidth,intsrcHeight,intsrcStride,byte[]dstBytes,intdstWidth,intdstHeight,intdstStride);}publicForm1()……//增加命名空间usingSystem.IO;//数据流读取usingSystem.Runtime.InteropServices;//导入库DllImport需要增加的命名空间usingSystem.Drawing.Imaging;C#工控程序部署----编写C#工程04

界面设计1.C#代码编写“打开图片”按钮privatevoidbutton1_Click(objectsender,EventArgse){OpenFileDialogopen=newOpenFileDialog();open.InitialDirectory=@"D:\book_maskrcnn";//定义初始目录

open.Filter="图片文件|*.bmp;*.jpg;*.jpeg;*.gif;*.png";//过滤打开的文件

if(open.ShowDialog()==DialogResult.OK){stringpic_path=open.FileName.ToString();if(pic_path!=null){pictureBox1.Image=Image.FromFile(pic_path);//显示图片

button1.Text="读取成功";}}else{MessageBox.Show("读取图片失败,请重新选择");}

}C#工控程序部署----编写C#工程04

界面设计1.C#代码编写“初始化模型”按钮privatevoidbutton2_Click(objectsender,EventArgse){stringmodel_path="D:/book_maskrcnn/model_pics/maskrcnn";intresult=Model.Mask_Init(model_path);//模型初始化

if(result==1){button2.Text="已初始化";}else {MessageBox.Show("模型初始化失败");}}C#工控程序部署----编写C#工程04

界面设计1.C#代码编写“推理”按钮privatevoidbutton3_Click(objectsender,EventArgse){Bitmapsource=newBitmap(pictureBox1.Image);//从pictureBox控件获取数据

//将Bitmap数据转化为byte数组

BitmapDatasourceData=source.LockBits(newRectangle(0,0,source.Width,source.Height),ImageLockMode.ReadOnly,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论