多亏了低成本的硬件平台,比如Raspberry Pi™,现在在硬件上建立图像处理算法的原型比以往任何时候都容易。大多数图像处理算法都是计算密集型的,在具有可接受帧速率的嵌入式平台上运行它们可能是一项挑战。虽然树莓派足以运行简单的图像处理算法,但大型图像和复杂算法最好运行在更强大的硬件上,如NVIDIA®杰森。
本文以色度键效果为例,描述了一个部署MATLAB的简单工作流®图像处理算法到嵌入式硬件。我们将用MATLAB Coder™从算法中生成C代码,然后使用在硬件上运行utility to prototype the algorithm on a Raspberry Pi board. Finally, we'll move the algorithm to an NVIDIA Jetson Tx1 platform to achieve real-time performance.
本例中使用的代码可用于download。
色度键控算法
色度键控是一种视频处理技术,广泛应用于电视天气预报、电影制作和照片编辑等领域a solid color background, such as a green screen, that is later replaced by a different scene (Figure 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)\)是表示替换固体背景颜色场景中的像素值,和\(米(J,K)∈[0,1] \)为一个掩码值。掩模值\(米(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,如果d(J,K)> T_2 \\
0 & d(j,k)
其中\(T_ {1} \)和\(T_ {2} \)与\(T_ {2}> T_ {1} \)来确定代表阈值。
MATLAB实现
这里是色度键算法的MATLAB实现。
函数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;[size(d,1)]);对于j=1:尺寸(m,1)对于k=1:尺寸(m,2)如果d(j,k)>t2 m(j,k)=1;ELSEIFd(J,K)> T1米(J,K)=(d(J,K) - T1)/(T2 - T1);结束结束结束m=repmat(imgaussfilt(m,0.8),[1 1 3]);Pfinal=uint8(双(P)。*m+double(Pscene)。*(1-m));结束
在MATLAB中,图像表示为uint8类型的[N,M,3]数组。这意味着在执行数学运算之前,我们需要将图像数据类型转换为“double”。为了避免从背景到前景的突变,我们对计算的掩模应用高斯滤波器。
确定参考颜色和阈值
甲色度键控算法需要一个参考颜色和阈值。利用Matlab软件支持包树莓派相机界面,我们捕捉到实际场景的图像。万博1manbetx然后,我们可以凭经验确定为背景和近似阈值的近似基准颜色。
r=raspi;cam=cameraboard;对于k=1:10 img=快照(cam);结束
该img=快照(cam);
command plots the image captured from Raspberry Pi camera in MATLAB. We use the Data Cursor tool in the MATLAB plot to specify the background color (Figure 2).
为了确定阈值,我们在循环中运行算法并调整阈值:
refColorRGB = 0 (1, 1, 3,'UINT8');refColorRGB(1,1,:)=uint8([93 177 21]);refColorYCbCr=rgb2ycbcr(refColorRGB);t1=28;t2=29;数据=编码器加载('background.mat','背景');场景= data.bg;% Main loop对于k=1:1000 img=快照(cam);imgFinal=chromaKey(图像,场景,refColorYCbCr,t1,t2);图(1),图像(img);图(2),图像(imgFinal);drawnow;结束
当我们运行代码,我们得到针对我们选择的背景(图3)中所示的图像。
在Raspberry Pi上部署色度键控算法
在部署代码之前,我们需要围绕色度键控算法编写一个循环,以从相机捕捉图像,并将其显示在与Raspberry Pi相连的监视器上:
函数chromaKeyApp ()用于树莓Pi硬件的%Chroma键控示例。%#codegen %版权所有2017w = matlab.raspi.webcam(0,(1280、720));d = matlab.raspi.SDLVideoDisplay;refColorYCbCr = 0 (1, 1, 3,'UINT8');refColorYCbCr(1,1,:)=uint8([0 76 98]);数据=编码器加载('background.mat','背景');场景=旋转(数据.bg,90);% Main loop对于K = 1:60 IMG =快照(W);IMG =色度(IMG,场景,refColorYCbCr,28,29);displayImage(d,IMG);结束释放(W);释放(d);结束
matlab.raspi.webcam
和matlab.raspi.SDLVideoDisplay
系统对象™在在硬件上运行并方便了RASPERY在工作流程中的使用。为了编译和运行代码,我们执行以下命令:
runOnHardware(r,'chromaKeyApp')
这个函数runOnHardware
creates a MATLAB Coder configuration for Raspberry Pi hardware, generates code for thechromaKeyApp.m公司
脚本,并部署它。为了以合理的帧率运行算法,可以将图像尺寸减小到640x480或320x240。
生成GPU代码
该算法工作的树莓派,但它没有达到我们正在寻找的实时性能。为了加速算法,我们将使用GPU编码器™将其部署到NVIDIA特森平台。我们需要生成代码GPU拿在算法固有的并行优势。首先,我们编写一个包装main
即使用了OpenCV访问连接到NVIDIA杰特森一个USB摄像头功能。此功能将元帅的视频帧从摄像机到我们的色度键
算法,然后在屏幕上显示的输出。
当生成GPU代码,我们首先创建一个GPU编码器配置对象,设置GPU参数为目标的NVIDIA杰特森平台,包括我们的定制main
函数。我们不会在MATLAB主机上编译代码,因为我们将为NVIDIA Jetson主板生成专门的代码。我们将创建一个脚本来设置GPU编码器配置,输入示例数据,并为我们的应用程序生成源代码。
%创建杰特森TX2 GPU编码器配置CFG = coder.gpuConfig('可执行程序');cfg.GpuConfig.MallocMode ='统一';cfg.GpuConfig.ComputeCapability =“6.2”;cfg.GenCodeOnly = 1;cfg.CustomSource ='主_网络摄像头.cu';%创建采样输入FG = imread(“greenScreenFrame.jpg”);bg=图像读取(“Scenery.jpg”);refColorRGB = [70 130 85];%RGB光绿色tmpColor =零([1,1,3],('UINT8');tmpColor(1,1,:)=uint8(refColorRGB);refColor=rgb2ycbcr(tmpColor);阈值1=14;阈值2=20;%为chromaKey生成CUDA代码代码生成-config cfg -args {fg,bg,refColor,threshold1,threshold2} chromaKey
然后在MATLAB中运行该脚本生成CUDA代码色度键
算法。
部署一个绿屏算法NVIDIA特森
要将生成的代码部署到nvidiajetson上,我们需要将所有必需的文件打包到代码生成
%准备文件转移到NVIDIA特森TX2拷贝文件(“Scenery.jpg”,'代码生成/ EXE /色度/');复制文件('主_网络摄像头.cu','代码生成/ EXE /色度/');复制文件(fullfile(matlabroot,“外来的”,'包括','tmwtypes.h'),'代码生成/ EXE /色度/');复制文件(“buildAndRun.sh”,'代码生成/ EXE /色度/');
下一步是复制整个代码生成
一旦进入NVIDIA杰特森记录,我们运行杰森_时钟.sh
代码生成
一旦可执行文件(色度键
)已经建成,所述应用与使用下面的命令在NVIDIA杰特森板USB连接的摄像头运行。帧每秒速率将在输出显示。
$>苏多/杰森_时钟.sh$>cd codegen/exe/chromaKey$>nvcc-o chromaKey*.cu-rdc=true-arch sm_62-O3`pkg config--cflags--libs opencv`-lcudart$>。/chromaKey 1
图4显示了NVIDIA Jetson板的USB摄像头在绿屏效果前后的输出。
树莓派和NVIDIA特森性能比较
NVIDIA Jetson的GPU更强大的并行处理能力显著提高了算法的性能。覆盆子的Pi达到了大约每秒1帧的速度,而NVIDIA的Jetson在图像尺寸为1280x720的情况下达到了每秒超过20帧的速度——我们在没有修改或优化算法的情况下获得了超过20倍的速度。我们可以通过优化MATLAB算法来提高GPU代码生成效率,从而进一步提高性能。
总结
在这个例子中,我们看到了如何快速生成一个MATLAB算法的代码,并将其部署到像Raspberry Pi这样的嵌入式硬件上。我们很快确定我们的算法工作正常,需要并行化。利用MATLAB和GPU编码器,实现了算法的高度并行实现,并将其应用到NVIDIA Jetson板上,取得了显著的性能改善。