技术文章和通讯

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

Jim Brock和Murat Belge, MathWorks


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

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

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

色度键控算法

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

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

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

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

\ (P_{一}(j, k) \)代表最终的像素值位置\ ((j, k) \)色度键控后,\ (P_{原始}(j, k) \)对应于原始图像的像素值,\ (P_{场景}(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) = \ \{\离开开始{矩阵}
如果d(j,k)>t_2 \\
如果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 =双(refColorYCbCr (1, 1, 3));PYCbCr = rgb2ycbcr (P);Cb =双(PYCbCr (:,: 2));Cr =双(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:尺寸(m, 1)k = 1:尺寸(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 ((P)的两倍。* m +双(Pscene)。* (1 - m));结束

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

确定参考颜色和阈值

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

r = raspi;凸轮= cameraboard;K = 1:10 img = snapshot(cam);结束

img =快照(cam);命令在MATLAB中绘制从树莓派相机捕获的图像。我们在MATLAB图中使用Data Cursor工具来指定背景颜色(图2)。

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

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

refColorRGB = 0 (1, 1, 3,“uint8”);refColorRGB(1,1,:) = uint8([93 177 21]);refColorYCbCr = rgb2ycbcr (refColorRGB);t1 = 28;t2 = 29;数据= coder.load (“background.mat”“bg”);现场= data.bg;%主循环K = 1:1000 img = snapshot(cam);imgFinal = chromaKey(img, scene, refColorYCbCr, t1, t2);图(1)、图像(img);图(2)、图像(imgFinal);drawnow;结束

当我们运行代码时,我们会得到一个显示在我们选择的背景上的图像(图3)。

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

在树莓派上部署色度键控算法

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

函数chromaKeyApp ()%Chroma键控的例子树莓派硬件。版权所有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]);数据= coder.load (“background.mat”“bg”);现场= imrotate (data.bg, 90);%主循环K = 1:20 0 img = snapshot(w);img = chromaKey(img, scene, refColorYCbCr, 28,29);displayImage (d, img);结束释放(w);释放(d);结束

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

runOnHardware (r,“chromaKeyApp”

这个函数runOnHardware为树莓派硬件创建MATLAB编码器配置,生成代码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编码器配置,输入示例数据,并为我们的应用程序生成源代码。

为Jetson TX2创建GPU编码器配置cfg = coder.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

然后在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 脚本由英伟达提供的主板性能最大化,改为codegen 目录包含我们刚刚传输的生成源代码,并执行如下所示的compile命令。

一旦可执行文件(chromaKey),该应用程序运行在一个usb连接的网络摄像头在NVIDIA Jetson板与以下命令。每秒帧率将显示在输出上。

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

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

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

比较Raspberry Pi和NVIDIA Jetson的性能

NVIDIA Jetson上GPU更强大的并行处理能力显著提高了算法的性能。Raspberry Pi实现了大约每秒1帧的速度,而NVIDIA Jetson在1280x720的图像尺寸下实现了每秒20帧的速度——我们无需对算法进行任何修改或优化就获得了20倍以上的速度。我们可以通过优化MATLAB算法来提高性能,以获得更高效的GPU代码生成。

总结

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

2018年出版的

查看相关功能的文章