
像素是图像的基本单元,一个个像素就组成了图像。可以认为像素就是图像中的一个点。
下面图片中的一个个小方块就是像素:

图像(或视频)的分辨率是指图像的大小或尺寸,一般用像素个数来表示图像的尺寸。
视频行业常见的分辨率有 QCIF(176x144)、CIF(352x288)、D1(704x576 或 720x576),还有 360P(640x360)、720P(1280x720)、1080P(1920x1080)、4K(3840x2160)、8K(7680x4320)等。
同样一张图像用不同的分辨率表示会有什么不同?可以通过以下这组图片来直观感受一下。

不难看出:
通常,彩色图像中都有 R 、G、B 三个通道,即每个像素有三个颜色值,分别是红、蓝、绿。
一般 R 、G、B 各占 8 个位,即一个字节。8 位可以表示 256 中颜色值,所以一个像素的颜色值可以有 256x256x256 种,即 16777216 种。这种图像称 8bit 图像,此处的 8bit 就是位深。
可以看出,位深越高,能够表示的颜色值就越多,图像就可以更精确展示色彩。
当然,图像的位深越大,需要的存储空间就越大,传输过程中需要的带宽也就越大。目前大部分情况下,图像的位深都是 8bit。
Stride 不是图像本身的属性,在视频中会经常遇到。Stride 可以称为跨距,指图像存储时,内存中每行像素所占用的空间。
为了能快速读取一行像素,一般会对内存中的图像实现内存对齐,如 16 字节对齐。这样,每行像素的字节数就不一定是图像宽度 x 位深,而是图像宽度 x 位深 + 内存对齐的字节数。
比如,有一张 RGB 图像,分辨率是 1278x720,将其存储在内存中,一行像素需要 1278x3 = 3834 字节,如果内存对齐是 16 字节,那么一行像素需要 3840 字节,需要填充 6 个字节。此时,Stride 就是 3840。

这种情况下,每读取一行数据的时候需要跳过这多余的 6 个字节。如果没有跳过的话,填充的 6 个字节的像素就会被误认为是下一行开始的 2 个像素(每个像素 R、G、B 各占 1 个字节,2 个像素共 6 个字节)。那这样得到的图像就完全错了,显示出来的就是“花屏”现象,屏幕会出现一条条的斜线。
视频是由一系列图像组成的,即“连续”的一帧帧图像就可以组成视频。但事实上,视频中的图像并不是真正意义上的连续。也就是说,在 1 秒钟之内,图像的数量是有限的。只是当数量达到一定值之后,人的眼睛的灵敏度就察觉不出来了,看起来就是连续的视频了。
1 秒钟内图像的数量就是帧率。据研究表明,一般帧率达到 10 ~ 12 帧每秒,人眼就会认为是流畅的了。
通常,在电影院看的电影帧率一般是 24fps(帧每秒),监控行业常用 25fps,可以根据自己的使用场景来具体设定帧率值。
选择帧率的时候还需要考虑设备处理性能的问题,尤其是实时视频通话场景。帧率高,代表着每秒钟处理的图像数量会很高,从而需要的设备性能就比较高。如果是含有多个图像处理过程,比如人脸识别、美颜等算法的时候,就更需要考虑帧率大小和设备性能的问题。同样,也要考虑带宽流量的问题。帧率越大,对带宽的要求也会越高。
视频的帧率越高,1 秒钟内的图像数据量就会越大。通常存储视频的时候需要对图像进行压缩之后再存储,否则视频会非常大。
码率是指视频在单位时间内的数据量的大小,一般是 1 秒钟内的数据量,其单位一般是 Kb/s 或者 Mb/s。通常,用压缩工具压缩同一个原始视频的时候,码率越高,图像的失真就会越小,视频画面就会越清晰。但同时,码率越高,存储时占用的内存空间就会越大,传输时需要的带宽也会越大。
并不是码率越高,清晰度就会越高。和压缩算法有关,有些算法可以在保证清晰度的情况下,减小码率。
通常,RGB 图像每一个像素都是分别存储 R、G、B 三个值,且三个值依次排列存储。如一张 8 bit 位深的 RGB 图,每个值占用一个字节。但是,需要注意,不一定按照 RGB 的顺序存储,也可能是 BGR 的顺序。
比如,OpenCV 经常使用 BGR 格式存储图像:

虽然 RGB 比较简单,同时在图像处理的时候也经常会用到。但是在视频领域,更多地是使用 YUV 颜色空间来表示图像的。这是因为 R、G、B 三个颜色是有相关性的,所以不太方便做图像压缩编码。
YUV 最早主要是用于电视系统与模拟视频领域,现在视频领域基本都是使用 YUV 颜色空间。
跟 RGB 图像中 R、G、B 三个通道都跟色彩信息相关这种特点不同,YUV 图像将亮度信息 Y 与色彩信息 U、V 分离开来。Y 表示亮度,是图像的总体轮廓,称之为 Y 分量。U、V 表示色度,主要描绘图像的色彩等信息,分别称为 U 分量和 V 分量。这样一张图像如果没有了色度信息 U、V,只剩下亮度 Y,则依旧是一张图像,只不过是一张黑白图像。
使用 YUV 的好处
以前只有黑白电视机,每一帧电视画面都是黑白的,没有色彩信息。当然黑白电视机也不支持显示彩色图像。后来随着技术的发展,出现了彩色电视机,每一帧画面都是有颜色信息的,那当然可以使用 RGB、YUV 等颜色空间来表示一帧图像。
但是考虑到兼容老的黑白电视机,如果使用 RGB 表示图像,那么黑白电视机无法播放。因为 R、G、B 三个通道都是彩色的,而 Y、U、V 就可以。因为黑白电视机可以使用 Y 分量,Y 分量就是黑白图像,而且包含了图像的总体轮廓信息,只是没有色彩信息而已。
YUV 主要分为 YUV 4:4:4、YUV 4:2:2、YUV 4:2:0 几种常用的类型。其中最常用的又是 YUV 4:2:0。这三种类型的 YUV 主要的区别就是 U、V 分量像素点的个数和采集方式。
YUV 4:4:4 就是每一个 Y 就对应一个 U 和一个 V;

而 YUV 4:2:2 则是每两个 Y 共用一个 U、一个 V;

YUV 4:2:0 则是每四个 Y 共用一个 U、V。

总的来说:
YUV 存储方式主要分为两大类:Planar 和 Packed 两种。Planar 格式的 YUV 是先连续存储所有像素点的 Y,然后接着存储所有像素点的 U,之后再存储所有像素点的 V,也可以是先连续存储所有像素点的 Y,然后接着存储所有像素点的 V,之后再存储所有像素点的 U。Packed 格式的 YUV 是先存储完所有像素的 Y,然后 U、V 连续的交错存储。









YUV 类型 | 存储类型 | |
|---|---|---|
YUV 4:4:4 | I444 | |
YV24 | ||
YUV 4:2:2 | Packed | NV16 |
NV61 | ||
Planar | YU16 | |
YV16 | ||
YUV 4:2:0 | Packed | NV12 |
NV21 | ||
Planar | YU12 | |
YV12 | ||
Color Range
对于一个 8bit 的 RGB 图像,它的每一个 R、G、B 分量的取值理论是 0~255 的。但是真的是这样的吗?其实不是的。这里就涉及到 Color Range 这个概念。Color Range 分为 Full Range 和 Limited Range。Full Range 的 R、G、B 取值范围都是 0 ~ 255。而 Limited Range 的 R、G、B 取值范围是 16 ~ 235。
BT709 和 BT601 定义了一个 RGB 和 YUV 互转的标准规范,BT601 是标清的标准,而 BT709 是高清的标准。

每种标准下不同 Color Range 的转换公式是不同的,在做 RGB 往 YUV 转换的时候需要知道是使用的哪个标准的哪种 Range 做的转换,并告知对方。这样对方使用同样的标准和 Range 才可以正确的将 YUV 转换到 RGB。
图像的缩放就是将原图像的已有像素经过加权运算得到目标图像的目标像素。
比如,已有图像是 720P 的分辨率,称为原图像,需要放大到 1080P,称 1080P 图像是目标图像。目标图像在宽度方向上放大了 1920 / 1280 = 1.5 倍,高度方向上也放大了 1080 / 720 = 1.5 倍。
那怎么通过 720P 的原图像生成 1080P 的目标图像呢?先将目标图像的像素位置映射到原图像的对应位置上,然后把通过插值计算得到的原图像对应位置的像素值作为目标图像相应位置的像素值。

同样的以 720P 作为原图像,那么 720P 缩小到目标图像 360P 的过程也是类似于图像放大的过程的。

使用更通用的表达式表示:假设原图像的分辨率是 w0 x h0,需要缩放到 w1 x h1。那只需要将目标图像中的像素位置(x,y)映射到原图像的(x * w0 / w1,y * h0 / h1),再插值得到这个像素值就可以了,这个插值得到的像素值就是目标图像像素点(x,y)的像素值。注意,(x* w0 / w1,y * h0 / h1)绝大多数时候是小数。这就是图像缩放算法原理的通用表达。









三种算法对比
双三次插值需要计算 16 个点的权重再乘以像素值求和,相较于前面的最近邻插值和双线性插值计算量较大,但插值后的图像效果最好。

插值算法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
最近邻插值 | 取待插值周围 4 个像素点中距离最近的像素值 | 计算量小,速度快 | 图像效果不好,容易产生锯齿 |
双线性插值 | 先通过在周围 4 个像素水平线性插值得到中间像素,再对中间像素垂直线性插值得到待插值像素值 | 效果比邻近插值好 | 速度比邻近插值慢 |
双三次插值 | 通过周围 16 个像素点求得各个水平和垂直权重,将水平和垂直权重相乘得到最终权重,将 16 个点按自己的权重加权求和得到待插值像素值 | 图像效果最好 | 计算量最大,速度最慢 |