颜色空间
RGB是比较常用的格式,也是OpenCV画图API中接受的格式,像素的排列是RGBRGB...
DVPP编解码器的输入输出都是YUV420SP[1],如果要使用OpenCV的画图API的话需要先将解码后的图片从YUV420SP转成RGB,画图后再转回YUV420SP才能编码。而且颜色空间转换非常的慢,在Atlas200DK上将1080P的YUV420SP转成RGB就需要20ms左右,而画图加标注文字本身一般也只需要1ms左右。所以处于性能的考虑,我选择直接在YUV420SP上画图。
YUV420SP
画图的基本操作就是在设置一个像素的颜色,所以我们要先了解一下YUV420SP的格式。上图[2]是对YUV420SP格式直观的一个展示: Y平面可以看作一张普通的灰度图,UV可以看作两张长宽只有一半的灰度图而且UV是交织在一起的。在demo中我采取了一个简单的方法,分别设置YUV三个平面的像素:
inline void SetPixel(int h, int w, const YUVColor &color) {
*(y_addr + h * img_w) = color.y;
uint8_t *uv_offset = uv_addr + (h / 2) * img_w + w / 2 * 2;
uv_offset[0] = color.u;
uv_offset[1] = color.v;
}
搞定一个像素以后,我们就可以用这个方法完成任意的绘图操作。
标注文字
输出文字我选择的是freetype[3],参考官方demo简单的移植到我的应用中:
- FT_New_Face(library, font_path, 0, &face)加载一个字体库
- FT_Set_Pixel_Sizes(face, font_size, font_size)设置字体大小
- FT_Get_Char_Index(face, ch)获取字符对应的下标
- FT_Load_Glyph(face, glyph_idx, FT_LOAD_RENDER)加载glyph
- FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)渲染glyph
- 根据freetype给的buffer中的像素值和SetPixel函数,在图像上逐个像素点设置