基于U-net的语义分割网络代码生成
这个例子展示了一个使用深度学习的图像分割应用程序的代码生成。它使用codegen
命令生成对U-Net(用于图像分割的深度学习网络)的DAG网络对象执行预测的MEX函数。
对于一个类似的例子,涉及图像分割使用U-Net没有codegen
命令,看到基于深度学习的多光谱图像语义分割(图像处理工具箱).
第三方的先决条件
要求
本例生成CUDA MEX,第三方需求如下。
CUDA®启用NVIDIA®GPU和兼容驱动程序。
可选
对于非mex构建,例如静态、动态库或可执行文件,此示例具有以下附加要求。
英伟达工具包。
NVIDIA cuDNN库。
编译器和库的环境变量。有关更多信息,请参见第三方硬件而且设置必备产品s manbetx 845.
检查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万博1manbetxSupportFile(“视觉/数据”,“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文件版本。该函数作为支持文件附加到示例中。万博1manbetx
如果~ (fullfile (pwd,存在“数据”),“dir”) url =“https://home.cis.rit.edu/ cnspci /其他/数据/ 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
深度学习配置对象,并将其分配给DeepLearningConfig
GPU代码配置对象的属性。运行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。
Kemker, Ronald, Carl Salvaggio和Christopher Kanan。基于深度学习的多光谱遥感图像语义分割算法ISPRS摄影测量与遥感杂志,深度学习RS数据,145(2018年11月1日):60-77。https://doi.org/10.1016/j.isprsjprs.2018.04.014。
另请参阅
功能
对象
相关的例子
- 基于深度学习的多光谱图像语义分割(图像处理工具箱)
- 基于深度学习的语义分割(计算机视觉工具箱)
- 基于NVIDIA DRIVE的语义分割(NVIDIA Jetson万博1manbetx和NVIDIA DRIVE平台的MATLAB Coder支持包)
- 训练和部署用于语义分割的全卷积网络
- 基于U-net的语义分割网络代码生成
更多关于
- 开始使用深度学习进行语义分割(计算机视觉工具箱)