前言
现在图像格式主要分为RGB格式和YUV格式, 由于RGB格式的图像数据量较大,因此几乎所有图像处理都是以YUV格式作为输入,本文主要介绍的是基于NV12格式的手工图像裁剪(使用CPU来进行,不过现在的嵌入式SOC上一般都有专门的硬件模块可以完成这个功能)
一、什么是软处理, 什么是硬处理
1. 硬处理
现在的嵌入式SOC上一般都会有一些专门用来进行图像处理的硬件模块, 比如ISP, VSP等,说白了就是一个集成在SOC中一个IP核,通过SOC内部的总线和CPU进行连接, CPU通过专门的寄存器地址去控制这些硬件模块。例如对于RCar H3 这个SOC来说,它里面就有VSP硬件模块可以进行图像裁剪,缩放等功能
2. 软处理
所谓的软处理, 就是指通过CPU来进行处理, 效率比硬处理低很多。比如对于图像裁剪,使用CPU来进行处理, CPU负责整个系统的运行, 要处理的事情很多, 而CPU同一时间只能干一件事,对于图像裁剪,CPU还需要进行内存拷贝和一些计算的操作, 效率自然就低。
二、NV12图像格式
1. YUV格式介绍
YUV采样格式
- YUV 相比于 RGB 格式最大的好处是可以做到在保持图像质量降低不明显的前提下,减小文件大小;
- YUV 主流的采样方式有三种:
YUV 4:4:4(YUV444) :YUV 4:4:4 采样,每一个 Y 对应一组 UV 分量
YUV 4:2:2(YUV422) :YUV 4:2:2 采样,每两个 Y 共用一组 UV 分量
YUV 4:2:0(YUV420) :YUV 4:2:0 采样,每四个 Y 共用一组 UV 分量
YUV存储格式
YUV 存储可以分为两种:packed(打包)和planar(平面);
- packed:Y、U、V 分量穿插着排列,三个分量存在一个 Byte 型数组里;
- planar: Y、U、V 分量分别存在三个 Byte 型数组中;
常见的YUV像素格式
其中YUV420格式的图像是比较常见的图像处理算法所支持的格式,主要是YUV420格式的数据量最小,并且Y分量和UV分量是分开的,对于很多图像处理算法,它们只需要Y分量就够了, 另外,对于H264编码这种,它们只支持NV12格式作为输入格式;
- YUV422:YUYV、YVYU、UYVY、VYUY
这四种格式每一种又可以分为 2 类(packed和planar),以 YUYV 为例,一个 6*4 的图像的存储方式如下:
所占字节数为 width * height * 2 = 6 * 4 * 2 = 48byte
- YUV420:I420、YV12、NV12,、NV21
而YUV420又可细分为YUV420p和YUV420sp两种,本文所用的NV12就属于YUV420sp
YUV420p: I420、YV12
YUV420sp: NV12、NV21
同样,对于一个6*4的图像,这四种像素格式的存储方式如下:
所占字节数为 width * height * 3 / 2 = 6 * 4 * 3 / 2 = 36byte
2.NV12图像裁剪代码实现
以下代码实现了将输入源为1280 * 720 NV12格式的一张图片转换为一张 640 * 640 的NV12 图片,用户可以修改对应的x_offset和y_offset值,达到从任意位置开始裁剪的图像的功能。
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>