标签:ubi 系统 dig src 编码 标准 图像 == article
原文说转 没有具体的转链接 我转备用。 具体验证还未完成。
转: https://blog.csdn.net/zwz1984/article/details/50403150
YUV图像合成原理
引言:在视频监控中最常用的就是图像拼接和字符叠加,25FPS的视频流,如果每隔40MS就从各个通道中取一幅图像来合成,则可以看到一个实时的合成视频。合成的过程也就是原始图像的拼接、缩放的过程,本文主要阐述UV分开存储的YUV420图像拼接的过程,实现下图的效果。
一、原图图像格式
1、图像常用的格式有两种RGB和YUV
(1)YUV是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式采用的颜色空间。在现代彩色电视系统中,通常采用三管彩色摄影机或彩色CCD摄影机进行取像,然后把取得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的YUV色彩空间表示。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。
(2)RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
2、两者在存储上的区别
(1)YUV按照内存消耗量总体上分为YUV420、YUV422两种
YUV420-----其Y:U:V或者Y:UV或者Y:V:U的总量为4:2:0
YUV422-----其Y:U:V比例为4:2:2
(2)RGB内存比例为1:1:1
则可以看出 显示一个像素点 需要的内存字节数
YUV420=(4+2+0)/4=3/2BYTE
YUV422=(4+2+2)/4=2 BYTE
RGB=(1+1+1)/1=3 BYTE
现在有一副图像,宽W高H,那么显示一副图像所需内存
YUV420=W*H*3/2 BYTE
YUV422=W*H*2 BYTE
RGB=W*H*3 BYTE
3、YUV数据格式YUV420-UV分开存储
X代表Y分量 0代表U/V分量 420的常规打包格式如下:
也就是说在水平方向和锤子4个像素点Y分量公用一组U/V分量
在内存结构上U/V分量水平和垂直分量均为1/2 U=w/2*h/2 V=w/2*h/2
用表格数据得出来就是
二、图像合成过程
合成前的图像和需要合成到的目的图像如下图所示
需要进行采样缩放、贴图后就能实现图像合成
1、采样
这里不做详细介绍 只看采样后效果
2、贴图
贴图原理-采样后图像的Y分量直接memcpy到合成图像的对应区域,Y/V分量则需要注意下
U/V水平和垂直均1/2采样
隔行拷贝,每次拷贝采样后w/2长度。由于合成图像的U/V数据已经隔行-存储的时候是连续的,所以UV拷贝的时候连续拷贝采样后长度/2然后进入合成图像下一行的U/V然后再拷贝,拷贝的高度为采样后图像高度h/2
上代码
-
-
-
-
-
-
-
-
-
-
-
YUV_IMAGE(){ y = NULL; u = NULL; v = NULL; w = 0; h = 0; }
-
~YUV_IMAGE(){ y = NULL; u = NULL; v = NULL; w = 0; h = 0; }
-
-
-
-
-
-
-
-
-
BOOL CDigitalCourt::GetMergeImg()
-
-
DWORD dwTimeBegin = GetTickCount();
-
-
-
-
for (int i = 0; i < MAX_CHANNEL_CNT; i++)
-
-
-
-
-
if (m_pChannel[i]->GetYUVImage(&pImg))
-
-
-
MergeImage(pImg, &m_MergeImg, i);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
SwsContext * CDigitalCourt::CreateSws(YUV_IMAGE *src, UINT nOrder, UINT w, UINT h)
-
-
if (NULL == src || nOrder >= MAX_CHANNEL_CNT || 0 == w || 0 == h)
-
-
-
if (NULL == m_pSubSws[nOrder])
-
-
m_pSubSws[nOrder] = sws_getContext(src->w,
-
-
-
-
-
-
-
-
-
-
-
-
LOG(LOG_ERROR, "CDigitalCourt::Create sws failed index=%d,w=%d,h=%d,mergeW=%d,mergeH=%d!", nOrder, src->w, src->h, m_nMergeW, m_nMergeH);
-
-
-
-
return m_pSubSws[nOrder];
-
-
-
-
-
void CDigitalCourt::Scale(YUV_IMAGE *src, YUV_IMAGE *dst, SwsContext *pSws)
-
-
-
-
-
if (NULL == src || NULL == dst || NULL == pSws) return;
-
-
pictsrc.data[0] = src->y;
-
pictsrc.data[1] = src->u;
-
pictsrc.data[2] = src->v;
-
pictsrc.linesize[0] = src->w;
-
pictsrc.linesize[1] = src->w / 2;
-
pictsrc.linesize[2] = src->w / 2;
-
-
pictdst.data[0] = dst->y;
-
pictdst.data[1] = dst->u;
-
pictdst.data[2] = dst->v;
-
pictdst.linesize[0] = dst->w;
-
pictdst.linesize[1] = dst->w / 2;
-
pictdst.linesize[2] = dst->w / 2;
-
-
sws_scale(pSws, pictsrc.data, pictsrc.linesize, 0, src->h, pictdst.data, pictdst.linesize);
-
-
-
-
-
-
void CDigitalCourt::MergeImage(YUV_IMAGE *src, YUV_IMAGE *dst, UINT nOrder)
-
-
-
UINT nOffY = 0, nOffx = 0,w=0,h=0;
-
-
YUV_IMAGE *pImgSmall = NULL;
-
-
if (NULL == src || NULL == dst || nOrder < 0 || nOrder >= MAX_CHANNEL_CNT)
-
-
-
-
-
-
-
-
-
-
-
-
pImgSmall = &m_mainMerge;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
LOG(LOG_ERROR, "CDigitalCourt::MergeImage failed of image order error!");
-
-
-
-
pSws = CreateSws(src, nOrder, w, h);
-
-
Scale(src, pImgSmall, pSws);
-
-
MapImage(pImgSmall, &m_MergeImg, nOffx, nOffY);
-
-
-
void MapImage(YUV_IMAGE *src, YUV_IMAGE *dst, UINT nOffX, UINT nOffY)
-
-
if (NULL == src || NULL == dst) return;
-
if (src->w > dst->w || src->h > dst->h) return;
-
if (NULL == src->y || NULL == src->u || NULL == src->v) return;
-
if (NULL == dst->y || NULL == dst->u || NULL == dst->v) return;
-
-
-
for (int i = 0; i < src->h; i++)
-
-
nOff = dst->w*(nOffY + i) + nOffX;
-
-
memcpy(dst->y + nOff, src->y + src->w*i, src->w);
-
-
UINT nUVOffX = nOffX / 2, nUVOffY = nOffY / 2;
-
UINT nUVSrcW = src->w / 2, nUVSrcH = src->h / 2;
-
UINT nUVDstW = dst->w / 2, nUVDstH = dst->h / 2;
-
-
for (int j = 0; j < nUVSrcH; j++)
-
-
nOff = nUVDstW*(nUVOffY + j) + nUVOffX;
-
memcpy(dst->u + nOff, src->u + nUVSrcW*j, nUVSrcW);
-
memcpy(dst->v + nOff, src->v + nUVSrcW*j, nUVSrcW);
-
-
画中画 视频合成
标签:ubi 系统 dig src 编码 标准 图像 == article
原文地址:https://www.cnblogs.com/swing07/p/9710599.html