主要内容

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

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

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

第三方的先决条件

要求

本例生成CUDA MEX,第三方需求如下。

  • CUDA®启用NVIDIA®GPU和兼容驱动程序。

可选

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

检查GPU环境

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

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

分割网络

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

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

本例使用哈姆林海滩州立公园数据[2]以及预先训练好的U-Net网络,以便正确地对每个像素进行分类。

所使用的U-Net被训练为属于18类的像素,其中包括:

0.其他类/图像边界野餐桌14。草1。道路标志15.黑木面板沙2。树9。16.白色木板水(湖) 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的multispectralUnet网络对输入图像进行贴片语义分割multispectralUnet.mat文件。方法加载网络对象multispectralUnet.mat文件转换为持久变量mynet并在后续的预测调用中重用持久变量。

类型(“segmentImageUnet.m”
function out = segmentImageUnet(im,patchSize,trainedNet) % out = segmentImageUnet(im,patchSize,trainedNet)返回一个语义上%分割的图像,使用% trainedNet中指定的多光谱Unet进行分割。分割在大小为% patchSize的每个补丁上执行。版权所有The MathWorks, Inc. %#codegen persistent mynet;if isempty(mynet) mynet = code . loaddeeplearningnetwork (trainedNet);end [height, width, nChannel] = size(im);补丁=编码器。nullcopy (0 ([patchSize nChannel-1]));% Pad图像的尺寸为patchSize padSize = 0(1,2)的倍数;padSize(1) = patchSize(1) - mod(高度,patchSize(1));padSize(2) = patchSize(2) - mod(宽度,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网络

本例使用multispectralUnet包含预训练U-Net网络的mat文件。该文件大小约为117 MB。从MathWorks网站下载该文件。

trainedUnetFile = matlab.internal.examples.download金宝appSupportFile(“视觉/数据”“multispectralUnet.mat”);

U-Net是一个DAG网络,包含58层,包括卷积、最大池化、深度拼接和像素分类输出层。

负载(trainedUnetFile);disp(净)
DAGNetwork with properties: Layers: [58×1 nnet.cnn.layer.Layer] Connections: [61×2 table] InputNames: {'ImageInputLayer'} OutputNames: {' segment - layer '}

要查看网络体系结构,请使用analyzeNetwork(深度学习工具箱)函数。

analyzeNetwork(净);

准备数据

本例使用来自[2]的高分辨率多光谱数据。这组图像是用无人机在纽约哈姆林海滩州立公园上空拍摄的。数据包含有标记的训练集、验证集和测试集,有18个对象类标签。数据文件的大小为~3.0 GB。

使用downloadHamlinBeachMSIData帮助函数下载数据集的mat文件版本。该函数作为支持文件附加到示例中。金宝app

如果~ (fullfile (pwd,存在“数据”),“dir”) url =“http://www.cis.rit.edu/ ~ rmk6217 / rit18_data.mat”;downloadHamlinBeachMSIData (url, pwd +“/数据/”);结束

在MATLAB中加载并检查数据。

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

图像有七个通道。RGB颜色通道是第三、第二和第一图像通道。接下来的三个通道对应于近红外波段,并根据其热特征突出显示图像的不同组成部分。通道7是一个掩码,表示有效的分割区域。

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

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

运行MEX代码生成

生成CUDA代码segmentImageUnet.m入口点函数,为MEX目标创建GPU配置对象,将目标语言设置为c++。使用编码器。DeepLearningConfig函数创建CuDNN深度学习配置对象,并将其分配给DeepLearningConfigGPU代码配置对象的属性。运行codegen命令指定输入大小为12446-by-7654-by-7,补丁大小为1024-by-1024。这些值对应于整体test_data大小。较小的补丁尺寸加快了推断。要了解如何计算补丁,请参阅segmentImageUnet入口点函数。

cfg = code . gpuconfig (墨西哥人的);cfg。ConstantInputs =“删除”;cfg。TargetLang =“c++”;cfg。DeepLearningConfig =编码器。DeepLearningConfig (“cudnn”);inputArgs = {ones(size(test_data),“uint16”),...编码器。常数(1024年[1024]),coder.Constant (trainedUnetFile)};codegen配置cfgsegmentImageUnetarg游戏inputArgs报告
代码生成成功:查看报告

运行Generated MEX来预测test_data的结果

segmentImageUnet函数接收要测试的数据(test_data)和一个包含要使用的补丁大小尺寸的向量。获取图像的补丁,预测特定补丁中的像素,然后将所有补丁组合在一起。由于测试数据的大小(12446-by-7654-by-7),在补丁中更容易处理如此大的图像。

segmentedImage = segmentImageUnet_mex(test_data);

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

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

由于语义分割的输出是有噪声的,可以使用参数去除噪声和杂散像素medfilt2函数。

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

显示U-Net分段test_data

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

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

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

cmap = jet(编号(classNames));B = labeloverlay (imadjust (test_data (:,:, (3,2,1)), 0.6 [0], [0.1 - 0.9], 0.55),...segmentedImage,“透明”, 0.8,“Colormap”,提出);figure imshow(B) N = number (classNames);ticks = 1/(N*2):1/N:1;colorbar (“TickLabels”cellstr(类名),“滴答”蜱虫,“TickLength”0,...“TickLabelInterpreter”“没有”);colormap城市规划机构(cmap)标题(“分割图像”);

参考文献

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

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

另请参阅

功能

对象

相关的例子

更多关于