主要内容

基于U-net的语义分割网络的代码生成

这个例子展示了一个使用深度学习的图像分割应用程序的代码生成。它使用codegen命令生成一个MEX函数,该函数对用于U-Net(用于图像分割的深度学习网络)的DAG Network对象执行预测。

对于一个类似的例子,覆盖图像分割使用U-Net没有codegen命令,看到基于深度学习的多光谱图像语义分割(图像处理工具箱)

第三方的先决条件

要求

本例生成CUDA MEX,并具有以下第三方需求。

  • CUDA®支持NVIDIA®GPU和兼容驱动程序。

可选

对于非mex构建,如静态、动态库或可执行文件,本例有以下附加要求。

验证GPU环境

使用coder.checkGpuInstall(GPU编码器)函数来验证运行此示例所需的编译器和库是否正确设置。

envCfg = coder.gpuEnvConfig (“主机”);envCfg。DeepLibTarget =“cudnn”;envCfg。DeepCodegen = 1;envCfg。安静= 1;coder.checkGpuInstall (envCfg);

分割网络

U-Net[1]是一种用于语义图像分割的卷积神经网络(CNN)。在U-Net中,最初的卷积层序列被最大池化层点缀,依次降低了输入图像的分辨率。这些层之后是一系列卷积层,点缀上采样算子,依次增加输入图像的分辨率。将这两条串联路径组合在一起形成u形图。该网络最初被训练用于生物医学图像分割应用的预测。这个例子演示了该网络跟踪森林覆盖随时间变化的能力。环境机构跟踪森林砍伐,以评估和确定一个区域的环境和生态健康状况。

基于深度学习的语义分割可以从高分辨率航空照片中获得精确的植被覆盖度测量值。一个挑战是区分具有相似视觉特征的类别,例如试图将绿色像素划分为草、灌木或树。为了提高分类精度,一些数据集包含多光谱图像,提供关于每个像素的额外信息。例如,哈姆林海滩州立公园的数据集用近红外通道补充了彩色图像,提供了更清晰的分类。

本例使用Hamlin Beach State Park Data[2]和预先训练的U-Net网络来正确地分类每个像素。

使用的U-Net经过训练,可以分割属于18类的像素,其中包括:

0.其他类/图像边界野餐桌上14。草1。路标8。黑木面板沙2。树9。16.白木面板水(湖泊)3。 Building 10. Orange Landing Pad 17. Water (Pond) 4. Vehicle (Car, Truck, or Bus) 11. Water Buoy 18. Asphalt (Parking Lot/Walkway) 5. Person 12. Rocks 6. Lifeguard Chair 13. Other Vegetation

segmentImageUnet入口点函数

segmentImageUnet.m入口点函数利用中发现的多光谱unet网络对输入图像进行patchwise语义分割multispectralUnet.mat文件。函数从multispectralUnet.mat文件到持久变量中mynet并在后续的预测调用中重用持久变量。

类型(“segmentImageUnet.m”
% OUT = segmentmageunet (IM, PATCHSIZE)返回一个语义分割的%图像,使用网络多光谱unet分割。分割%是在大小为PATCHSIZE的每个补丁上执行的。% % Copyright 2019-2021 The MathWorks, Inc. function out = segmentmageunet (im, patchSize) %#codegen persistent mynet;if isempty(mynet) mynet = code . loaddeeplearningnetwork ('trainedUnet/multispectralUnet.mat');end [height, width, nChannel] = size(im);补丁=编码器。nullcopy (0 ([patchSize nChannel-1]));% pad图像的尺寸为patchSize的倍数padSize = 0 (1,2);- mod(height, patchSize(1));- mod(width, patchSize(2)); im_pad = padarray (im, padSize, 0, 'post'); [height_pad, width_pad, ~] = size(im_pad); out = zeros([size(im_pad,1), size(im_pad,2)], 'uint8'); for i = 1:patchSize(1):height_pad for j =1:patchSize(2):width_pad for p = 1:nChannel-1 patch(:,:,p) = squeeze( im_pad( i:i+patchSize(1)-1,... j:j+patchSize(2)-1,... p)); end % pass in input segmentedLabels = activations(mynet, patch, 'Segmentation-Layer'); % Takes the max of each channel (6 total at this point) [~,L] = max(segmentedLabels,[],3); patch_seg = uint8(L); % populate section of output out(i:i+patchSize(1)-1, j:j+patchSize(2)-1) = patch_seg; end end % Remove the padding out = out(1:height, 1:width);

获得预先训练的U-Net DAG网络对象

trainedUnet_url =“//www.tatmou.com/金宝appsupportfiles/vision/data/multispectralUnet.mat”;downloadTrainedUnet (trainedUnet_url pwd);
下载哈姆林海滩数据集的预训练U-net…下载需要几分钟…完成了。
ld =负载(“trainedUnet / multispectralUnet.mat”);网= ld.net;

DAG网络由卷积层、最大池化层、深度级联层、像素分类输出层等58层组成。要显示深度学习网络架构的交互式可视化,请使用analyzeNetwork函数。analyzeNetwork(净);

准备数据

下载哈姆林海滩州立公园的数据。

如果~ (fullfile (pwd,存在“数据”),“dir”) url =“http://www.cis.rit.edu/ ~ rmk6217 / rit18_data.mat”;downloadHamlinBeachMSIData (url, pwd +“/数据/”);结束
下载Hamlin Beach数据集…下载需要几分钟…完成了。

在MATLAB中加载并检查数据。

负载(fullfile (pwd,“数据”“rit18_data”“rit18_data.mat”));%检查数据test_data
名称大小字节类属性test_data 7x12446x7654 1333663576 uint16

图像有七个通道。RGB彩色通道分别是第四、五、六图像通道。前三个通道对应于近红外波段,并根据它们的热信号突出图像的不同成分。通道7是一个表示有效分割区域的掩码。

多光谱图像数据被排列为numchannels -by-width- height阵列。在MATLAB中,多通道图像按宽度-高度- numchannels排列。要重塑数据以使通道处于第三维,请使用助手函数,switchChannelsToThirdPlane

test_data = switchChannelsToThirdPlane (test_data);%确认数据具有正确的结构(通道最后)。test_data
名称大小字节类属性test_data 12446x7654x7 1333663576 uint16

运行MEX代码生成

生成CUDA代码segmentImageUnet.m为MEX目标创建一个GPU Configuration对象,将目标语言设置为c++。使用编码器。DeepLearningConfig(GPU编码器)函数创建CuDNN的深度学习配置对象,并将其分配给DeepLearningConfig图形处理器代码配置对象的属性。运行codegen命令,指定输入大小为[12446,7654,7]和补丁大小为[1024,1024]。这些值对应于整个test_data大小。较小的补丁大小可以加速推理。要了解补丁是如何计算的,请参阅segmentImageUnet.m入口点函数。

cfg = coder.gpuConfig (墨西哥人的);cfg。TargetLang =“c++”;cfg。DeepLearningConfig =编码器。DeepLearningConfig (“cudnn”);inputArgs ={(大小(test_data),“uint16”),编码器。常数(1024 [1024])};codegen配置cfgsegmentImageUnetarg游戏inputArgs报告
代码生成成功:查看报告

运行生成的MEX来预测test_data的结果

segmentImageUnet函数接受要测试的数据(test_data)和一个包含要使用的补丁大小的维度的向量。取图像的小块,预测特定小块中的像素,然后将所有小块组合在一起。由于test_data的大小(12446x7654x7),在patch中处理这样大的图像更容易。

segmentimagage = segmentmageunet_mex (test_data,[1024 1024]);

为了只提取分割的有效部分,将分割后的图像乘以测试数据的掩模通道。

test_data(:,:,7)~=0) .* uint8(test_data(:,:,7)~=0) .* uint8(test_data(:,:,7)~=0);

由于语义分割的输出是有噪声的,所以使用medfilt2函数。

segmentedImage = medfilt2 (segmentedImage [5,5]);

显示U-Net分段test_data

下面的代码行创建了一个类名向量。

一会= [“路标”“树”“建筑”“汽车”“人”...“LifeguardChair”“PicnicTable”“BlackWoodPanel”...“WhiteWoodPanel”“OrangeLandingPad”“浮”“石头”...“LowLevelVegetation”“Grass_Lawn”“Sand_Beach”...“Water_Lake”“Water_Pond”“沥青”];

在分割后的RGB测试图像上叠加标签,并在分割图像上添加一个颜色条。

提出=喷气(元素个数(类名);B = labeloverlay (imadjust (test_data (:,: 4:6), 0.6 [0], [0.1 - 0.9], 0.55),...segmentedImage,“透明”, 0.8,“Colormap”,提出);图imshow(B) N = numel(classNames);蜱虫= 1 / (N * 2): 1 / N: 1;colorbar (“TickLabels”cellstr(类名),“滴答”蜱虫,“TickLength”,0,...“TickLabelInterpreter”“没有”);colormap城市规划机构(cmap)标题(“分割图像”);

参考文献

Ronneberger, Olaf, Philipp Fischer和Thomas Brox。U-Net:用于生物医学图像分割的卷积网络。arXiv预印本arXiv: 1505.04597,2015.

R. Kemker, C. Salvaggio和C. Kanan。用于语义分割的高分辨率多光谱数据集。2017年,abs / 1703.01918。