技术文章及通讯

在树莓派和NVIDIA Jetson上运行MATLAB图像处理算法

作者:Jim Brock和Murat Belge, MathWorks


由于低成本的硬件平台,如树莓派™,现在比以往任何时候都更容易在硬件上原型图像处理算法。大多数图像处理算法都是计算密集型的,在具有可接受的帧速率的嵌入式平台上运行它们可能具有挑战性。虽然树莓派足以运行简单的图像处理算法,但大型图像和复杂算法最好在更强大的硬件上运行,如NVIDIA®杰森。

本文以色度键效果为例,描述了部署MATLAB的简单工作流®基于嵌入式硬件的图像处理算法。我们将用MATLAB Coder™从算法生成C代码,然后使用在硬件上运行实用程序在树莓派板上原型算法。最后,我们将把算法转移到NVIDIA Jetson Tx1平台上,以实现实时性能。

本例中使用的代码可用于下载

色度键控算法

色度键控广泛应用于电视天气预报、电影制作和照片编辑应用程序中,它是一种视频处理技术,其中前景主题在纯色背景(如绿色屏幕)下拍摄,随后被不同的场景所取代(图1)。

图1。前后色度键控的例子。

图1。前后色度键控的例子。

色度键控算法将图像中的每个像素与代表纯色背景色的参考颜色进行比较。如果像素的颜色与参考颜色足够接近,则将像素替换为预选场景图像中的对应像素。在数学上,色度键控算法可以表述为:

\ [P_{一}(j, k) = m (j, k) * P_{原始}(j, k) + (1 - m (j, k)) * P_{场景}(j, k) \]

其中\(P_{final}(j,k)\)表示色度键控后位置\((j,k)\)的最终像素值,\(P_{original}(j,k)\)是原始图像对应的像素值,\(P_{scene}(j,k)\)是表示替换纯色背景色的场景的像素值,\(m(j,k)∈[0,1]\)是掩码值。掩模值\(m(j,k)\)对于前景像素应该是1,对于背景像素应该是0。掩码值在0到1之间提供了从背景到前景的平滑过渡。

每个像素的掩码值通常在YCbCr颜色空间中计算,而不是通常的RGB颜色空间。YCbCr图像的Y分量表示亮度分量,并决定图像的亮或暗。Cb和Cr分量代表色度分量,可用于测量与参考颜色的相似性。仅使用图像的Cb和Cr分量测量颜色相似性,使得算法对纯背景颜色的明暗区域的亮度值变化具有鲁棒性。

为了测量像素颜色与参考颜色的相似性,我们使用色度空间中的欧几里得距离平方:

\ [d ^ 2 (j, k) = (Cb (j, k) -Cb_ {ref} (j, k)) ^ 2 + (Cr (j, k) -Cr_ {ref} (j, k)) ^ 2 \]

最后,我们用下面的公式计算图像中\((j,k)\)位置的掩模值:

\ [m (j, k) = \ \{\离开开始{矩阵}
1 & if d(j,k)>t_2 \\ \
0 &如果d(j,k)\压裂{d ^ 2 (j, k) t_1 ^ 2} {t_2 ^ 2-t_1 ^ 2} &如果t_1 < d (j, k) < t_2
结束\{矩阵}\吧。\]

其中\(t_{1}\)和\(t_{2}\)和\(t_{2} > t_{1}\)表示待确定的阈值。

MATLAB实现

这里是色度键控算法的MATLAB实现。

函数Pfinal = chromaKey(P, Pscene, refColorYCbCr, t1, t2) Cbref = double(refColorYCbCr(1,1,2));Crref = double(refColorYCbCr(1,1,3));PYCbCr = rgb2ycbcr(P);Cb = double(PYCbCr(:,:,2));Cr = double(PYCbCr(:,:,3));d = (Cb - Cbref)。^2 + (Cr - Crref).^2;T1 = T1 ^2;T2 = T2 ^2;M = 0 ([size(d,1) size(d,2)]);J = 1:size(m,1)K = 1:size(m,2)如果D (j,k) > t2 m(j,k) = 1;elseifD (j,k) > t1 m(j,k) = (D (j,k) - t1) / (t2 - t1);结束结束结束M = repmat(imgaussfilt(M,0.8), [1 1 3]);Pfinal = uint8(double(P)。*m + double(Pscene).*(1-m));结束

在MATLAB中,图像用uint8类型的[N, M, 3]数组表示。这意味着在执行数学运算之前,我们需要将图像数据类型转换为“double”。为了避免从背景到前景的突变,我们对计算的掩码应用高斯滤波器。

确定参考颜色和阈值

色度键控算法需要参考颜色和阈值。利用树莓派MATLAB支持包中的摄像接口,对实际场景进行图像采集。金宝app然后,我们可以根据经验确定背景的近似参考颜色和近似阈值。

R =树皮;照相机;K = 1:10 img =快照(凸轮);结束

Img =快照(凸轮);命令在MATLAB中绘制树莓派相机捕获的图像。我们使用MATLAB绘图中的数据游标工具来指定背景颜色(图2)。

图2。MATLAB数据游标工具,用于确定背景颜色值。

图2。MATLAB数据游标工具,用于确定背景颜色值。

为了确定阈值,我们在循环中运行算法并调整阈值:

refColorRGB = 0 ([1,1,3],“uint8”);refColorRGB(1,1,:) = uint8([93 177 21]);refColorYCbCr = rgb2ycbcr(refColorRGB);T1 = 28;T2 = 29;Data = code .load(“background.mat”“bg”);Scene = data.bg;%主循环K = 1:1000 img =快照(凸轮);imgFinal = chromaKey(img, scene, refColorYCbCr, t1, t2);图(1)、图像(img);图(2)、图像(imgFinal);drawnow;结束

当我们运行这段代码时,我们会在所选的背景下显示一张图像(图3)。

图3。原始图像,以及运行色度键控算法后得到的图像。

图3。左:原图。右图:运行色度键控算法后得到的图像。

将色度键控算法部署到树莓派

在部署代码之前,我们需要编写一个围绕色度键控算法的循环来从相机捕获图像,并将它们显示在连接到树莓派的显示器上:

函数chromaKeyApp ()%色度键控的例子,树莓派硬件。版权所有2017 The MathWorks, Inc.W = matlab.raspi.webcam(0,[1280,720]);d = matlab.raspi.SDLVideoDisplay;refColorYCbCr = 0 ([1,1,3],“uint8”);refColorYCbCr(1,1,:) = uint8([0 76 98]);Data = code .load(“background.mat”“bg”);Scene = imrotate(data.bg,90);%主循环K = 1:60 img =快照(w);img = chromaKey(img, scene, refColorYCbCr, 28,29);displayImage (d, img);结束释放(w);释放(d);结束

matlab.raspi.webcam而且matlab.raspi.SDLVideoDisplay系统对象™在在硬件上运行在部署工作流中方便使用相机和树莓派显示的实用程序。为了编译和运行代码,我们执行以下命令:

runOnHardware (r,“chromaKeyApp”

这个函数runOnHardware创建树莓派硬件的MATLAB Coder配置,为树莓派硬件生成代码chromaKeyApp.m脚本,并部署它。为了以合理的帧率运行算法,可以将图像大小减小到640x480或320x240。

生成GPU代码

该算法在树莓派上运行正常,但并没有达到我们所期望的实时性能。为了加速算法,我们将使用GPU Coder™将其部署到NVIDIA Jetson平台。我们需要生成GPU代码来利用算法中固有的并行性。首先,我们编写一个包装器主要该功能使用OpenCV访问连接到NVIDIA Jetson的USB摄像头。这个函数将把视频帧从相机整理到我们的chromaKey算法,然后在屏幕上显示输出。

在生成GPU代码时,我们首先创建一个GPU Coder配置对象,将GPU参数设置为针对NVIDIA Jetson平台,并包括我们的自定义主要函数。我们不会在MATLAB主机上编译代码,因为我们是专门为NVIDIA Jetson板生成代码。我们将创建一个脚本来设置GPU Coder配置,输入示例数据,并为我们的应用程序生成源代码。

为Jetson TX2创建GPU编码器配置cfg = code . gpuconfig (exe”);cfg.GpuConfig.MallocMode =“统一”;cfg.GpuConfig.ComputeCapability =“6.2”;cfg。GenCodeOnly = 1;cfg。CustomSource =“main_webcam.cu”%创建样本输入Fg = imread(“greenScreenFrame.jpg”);Bg = imread(“Scenery.jpg”);refColorRGB = [70 130 85];% RGB淡绿色tmpColor = 0 ([1,1,3],(“uint8”);tmpColor(1,1,:) = uint8(refColorRGB);refColor = rgb2ycbcr(tmpColor);Threshold1 = 14;Threshold2 = 20;为chromaKey生成CUDA代码codegen-config cfg -args {fg,bg,refColor,threshold1,threshold2} chromaKey

然后我们在MATLAB中运行脚本生成CUDA代码chromaKey算法。

将绿屏算法部署到NVIDIA Jetson

为了将生成的代码部署到NVIDIA Jetson,我们需要将所有必需的文件打包到codegen 目录,用下面的MATLAB命令。

准备文件传输到NVIDIA Jetson TX2拷贝文件(“Scenery.jpg”“codegen / exe / chromaKey /”);拷贝文件(“main_webcam.cu”“codegen / exe / chromaKey /”);拷贝文件(fullfile (matlabroot,“外来的”“包括”“tmwtypes.h”),“codegen / exe / chromaKey /”);拷贝文件(“buildAndRun.sh”“codegen / exe / chromaKey /”);

下一步是复制整个 生成的codegen 文件夹从主机到NVIDIA Jetson板。文件传输完成后,我们直接登录到NVIDIA Jetson以构建和运行应用程序。

登录到NVIDIA Jetson后,我们运行jetson_clocks.sh 脚本由NVIDIA提供的最大限度的性能板,更改为codegen 目录包含我们刚才传输的生成的源代码,并执行如下所示的compile命令。

一旦可执行文件(chromaKey)已构建,该应用程序通过NVIDIA Jetson板上的usb连接网络摄像头运行,并执行以下命令。帧/秒速率将显示在输出中。

$> sudo ./jetson_clock .sh $> cd codegen/exe/chromaKey $> nvcc -o chromaKey *. .cu -rdc=true -arch sm_62 -O3 ' pkg-config——cflags——libs opencv ' -lcudart $> ./chromaKey

图4显示了NVIDIA Jetson板的USB摄像头在绿屏效果前后的输出。

图4。应用绿屏效果前后对比的例子。

图4。应用绿屏效果前后对比的例子。

比较树莓派和NVIDIA Jetson性能

NVIDIA Jetson的GPU具有更强大的并行处理能力,极大地提高了算法的性能。树莓派实现了大约每秒1帧的速度,而NVIDIA Jetson在1280x720的图像大小上实现了每秒20帧以上的速度——我们在没有对算法进行任何修改或优化的情况下获得了超过20倍的速度。我们可以通过优化MATLAB算法来更有效地生成GPU代码,从而进一步提高性能。

总结

在这个例子中,我们看到了如何快速生成MATLAB算法的代码,并将其部署到像树莓派这样的嵌入式硬件上。我们很快就确定我们的算法工作正常,需要进行并行化。使用MATLAB和GPU Coder,我们生成了算法的高度并行实现,并将其部署到NVIDIA Jetson板上,实现了显著的性能提升。

2018年出版的

查看相关功能的文章