色度键控算法
广泛用于电视天气报告,电影制作和照片编辑应用,Chroma键控是一种视频处理技术,其中前景对象被射击纯色背景,例如绿色屏幕,后来被不同的场景替换(图1)。
色度键控算法将图像中的每个像素与表示纯色背景颜色的参考颜色进行比较。如果像素的颜色足够接近参考颜色,则用来自预选场景图像的相应像素替换像素。在数学上,色度键控算法可以配制如下:
\ [P_{一}(j, k) = m (j, k) * P_{原始}(j, k) + (1 - m (j, k)) * P_{场景}(j, k) \]
其中\(p_ {final}(j,k)\)表示位置\((j,k)\)之后的最终像素值,在色度键控后,\(p_ {morigin}(j,k)\)是像素对应于原始图像的值,\(p_ {scape}(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,如果d(j,k)> t_2 \\
如果d(j,k)
其中\(t_ {1} \)和\(t_ {2}> t_ {1} \)表示要确定的阈值。
Matlab实施
这是Chroma键控算法的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;eleesif.d(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]阵列。这意味着在执行数学操作之前,我们需要将图像数据类型转换为“双”。为了避免从背景到前景的突然转换,我们将高斯过滤器应用于计算的掩码。
确定参考颜色和阈值
色度键控算法需要参考颜色和阈值。使用MATLAB支持包中的相机接口进行覆盆子PI,我们捕获实际场景的图像。万博1manbetx然后,我们可以经验确定背景的近似参考颜色和近似阈值。
r = raspi;CAM = Cameraboard;对于k = 1:10 img =快照(凸轮);结束
当IMG =快照(CAM);
命令绘制在Matlab中从覆盆子PI相机捕获的图像。我们使用Matlab Plot中的数据光标工具来指定背景颜色(图2)。
为了确定阈值,我们循环运行算法并调整阈值值:
refColorRGB = 0 (1, 1, 3,'uint8');RefColRORGB(1,1,:) = UINT8([93 177 21]);RefColoryCBCR = RGB2YCBCR(REFCOLRORGB);t1 = 28;T2 = 29;data = coder.load('background.mat'那'bg');场景= data.bg;%主循环对于k = 1:1000 img =快照(Cam);Imgfinal = Chromaxey(IMG,场景,RefColoryCBCR,T1,T2);图(1),图像(IMG);图(2),图像(IMGFinal);粗暴;结束
当我们运行代码时,我们会收到我们选择的后台显示的图像(图3)。
在树莓派上部署色度键控算法
在部署代码之前,我们需要在Chroma键控算法周围编写一个环,以从相机捕获图像,并在连接到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]);data = coder.load('background.mat'那'bg');场景= imroTate(data.bg,90);%主循环对于k = 1:60 img =快照(w);IMG = Chromaxey(IMG,场景,RefColoryCBCR,28,29);DisplayImage(D,IMG);结束释放(W);释放(D);结束
matlab.raspi.webcam.
和matlab.raspi.sdlvideodisplay.
系统对象™在在硬件上运行便于在部署工作流程中使用相机和覆盆子PI显示的实用程序。要编译和运行代码,我们执行以下命令:
RunonHardware(R,'ChromakeyApp')
这个函数Runonhardware
为Raspberry PI硬件创建MATLAB编码器配置,为此生成代码Chromakeyapp.m.
脚本,并部署它。为了在合理的帧率下运行该算法,可以将图像大小减小到640x480或320x240。
生成GPU代码
该算法正在研究覆盆子PI,但它没有实现我们正在寻找的实时性能。为了加速算法,我们将使用GPU编码器™将其部署到NVIDIA Jetson平台。我们需要生成GPU代码以利用算法中固有的并行性。首先,我们写一个包装主要
使用OpenCV访问连接到NVIDIA Jetson的USB摄像机的功能。此功能将来自相机的录像帧到我们的Chromaxey.
算法,然后在屏幕上显示输出。
生成GPU代码时,我们首先创建GPU编码器配置对象,设置GPU参数来定位NVIDIA Jetson平台,并包括我们的自定义主要
函数。我们不会在MATLAB主机上编译代码,因为我们是专门为NVIDIA Jetson板生成代码。我们将创建一个脚本来设置GPU编码器配置,输入示例数据,并为我们的应用程序生成源代码。
%为Jetson Tx2创建GPU编码器配置cfg = coder.gpuconfig('exe');cfg.g.guconfig.mallocmode =.'统一';cfg.gpuconfig.ComputEcapability =.“6.2”;cfg.gencodeonly = 1;cfg.cusomsource ='main_webcam.cu';%创建示例输入fg = imread(“greenScreenFrame.jpg”);bg = imread(“Scenery.jpg”);RefcolorRGB = [70 130 85];%RGB浅绿色tmpcolor = zeros([1,1,3],('uint8');tmpcolor(1,1,:) = uint8(Refcolorgb);RefColor = RGB2YCBCR(TMPColor);阈值1 = 14;阈值2 = 20;%生成Cuda的CUDA代码Codegen.-config cfg -args {fg,bg,refColor,threshold1,threshold2
然后在MATLAB中运行脚本,生成CUDA代码Chromaxey.
算法。
将绿色屏幕算法部署到NVIDIA Jetson
要将生成的代码部署到NVIDIA Jetson,我们需要将所有必需的文件包装到Codegen.
%准备转移到nvidia jetson tx2的文件copyfile(“Scenery.jpg”那'codegen / exe / chromaxey /');copyfile('main_webcam.cu'那'codegen / exe / chromaxey /');Copyfile(FullFile(Matlabroot,“外来的”那“包括”那'tmwtypes.h'),'codegen / exe / chromaxey /');copyfile(“buildAndRun.sh”那'codegen / exe / chromaxey /');
下一步是复制整个Codegen.
一旦登录到NVIDIA Jetson,我们运行Jetson_clocks.sh.
Codegen.
一旦可执行文件(Chromaxey.
)已构建,应用程序在NVIDIA Jetson Loard上使用USB连接的网络摄像头运行,其中包含以下命令。每秒帧将显示在输出上。
$> sudo ./jetson_clocks.sh $> cd codegen / exe / chromaxey $> nvcc -o chromakey * .cu -rdc = true -arch sm_62 -o3`pkg-config --cflags --libs opencv` -lcudart $>./Chromakey 1.
图4显示了绿色屏幕效果之前和之后NVIDIA Jetson Lock的USB相机的输出。
比较覆盆子PI和NVIDIA Jetson性能
NVIDIA Jetson上GPU更强大的并行处理能力显著提高了算法的性能。Raspberry Pi实现了大约每秒1帧的速度,而NVIDIA Jetson在1280x720的图像尺寸下实现了每秒20帧的速度——我们无需对算法进行任何修改或优化就获得了20倍以上的速度。我们可以通过优化MATLAB算法来提高性能,以获得更高效的GPU代码生成。
总结
在此示例中,我们了解如何快速生成Matlab算法的代码,并将其部署到嵌入式硬件,如覆盆子PI。我们快速确定我们的算法正常工作,需要并行化。使用MATLAB和GPU编码器,我们生成了算法的高度并行实现,并将其部署到NVIDIA Jetson板,实现了显着的性能改进。