红外热成像下篇--叠加字符OSD
红外热成像下篇–叠加字符OSD
背景
前段时间不是玩了下红外热成像,视频可见我的公众号和视频号:
还有个瑕疵:视频上没有实时显示相应的温度(叠加在视频上),这段时间就把它给实现了,视频可见我的公众号和视频号。
在视频上实现温度信息叠加,里面一个主要技术点就是字符OSD,这里使用了一种IPC芯片通用的字符OSD方案(RK、海思等方案都适用):freetype
+ sdl
+ Soc的图层处理硬件模块。
首先介绍下前面这3个东东:
freetype:
FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。
sdl:
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。现SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
Soc的图层处理硬件模块
一般IPC芯片算力都比较低,但几乎都带有2D图层的硬件处理模块,如这里RK的RGA。
原理其实很简单:
- 通过 freetype 来处理要叠加的字符。
- 然后用 sdl 生成相应的bmp图
- 再转为ipc的soc芯片能支持叠加的位图(这一步要根据具体的soc支持情况来,有些支持sdl的16位 rgb565 就不需要转)。
- 最后叠加到对应的图像数据上去。一般都使用soc提供的相应硬件接口。
注: sdl默认生成的是16位 rgb565 格式的图,而我这里使用的 rv1109/rv1126的OSD叠加的图只支持32位ARGB888格式,所以需要手动转换下。
实现
首先交叉编译好要用的freetype
,SDL
,SDL_ttf
这三个库,一般都通过buidlroot来编译,具体细节这就不多说了。
最后上主要的代码,这里以RK的rv1109/rv1126为例:
SDL_PixelFormat *fmt;
TTF_Font *font;
//图面结构
SDL_Surface *text, *temp;
if (TTF_Init() < 0 )
{
fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
SDL_Quit();
}
//打开字库,设字体为80号
font = TTF_OpenFont("simsun_cn_3000.ttf", 30); //字体库需自己准备
if ( font == NULL )
{
fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());
}
//设置字体颜色
SDL_Color forecol = { 0x00,0x00, 0x00}; //3个参数分别代表rgb
//SDL渲染字符
text = TTF_RenderUTF8_Solid(font, str, forecol);
//定义格式
fmt = (SDL_PixelFormat*)malloc(sizeof(SDL_PixelFormat));
memset(fmt,0,sizeof(SDL_PixelFormat));
fmt->BitsPerPixel = 16; //每像素位数
fmt->BytesPerPixel = 2; //每像素字节数
fmt->colorkey = 0xffffffff;
fmt->alpha = 0xff; //透明度 0<=alpha<=255
//渲染字符,默认RGB565格式
temp = SDL_ConvertSurface(text,fmt,0);
BITMAP_S stBitmap;
//将渲染后的Surface转换成Bitmap,转成RV1126支持的ARGB8888格式
SurfaceWord_ToBMP(temp, &stBitmap, forecol);
//释放资源
SDL_FreeSurface(text);
SDL_FreeSurface(temp);
TTF_CloseFont(font);
TTF_Quit();
free(fmt);
fmt = NULL;
//使用RK自带的RGN来叠加图片
OSD_REGION_INFO_S RngInfo;
RngInfo.enRegionId = 5;
RngInfo.u32PosX = bitmap_PosX;
RngInfo.u32PosY = bitmap_PosY;
RngInfo.u32Width = bitmap_width;
RngInfo.u32Height = bitmap_height;
RngInfo.u8Enable = 1;
RngInfo.u8Inverse = 0;
printf("# ENABLE RGN enRegionId[%d]: < u32PosX:%d,u32PosY:%d,u32Width:%d,u32Height:%d> for 100ms...\n",
RngInfo.enRegionId, RngInfo.u32PosX, RngInfo.u32PosY,
RngInfo.u32Width, RngInfo.u32Height);
int ret = RK_MPI_VENC_RGN_SetBitMap(0, &RngInfo, &stBitmap); //
if (ret) {
printf("ERROR: set rgn stBitmap(enable) failed! ret=%d\n", ret);
if (stBitmap.pData)
free(stBitmap.pData);
//break;
return -1;
}
// free stBitmap
free(stBitmap.pData);
stBitmap.pData = NULL;
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DD'Notes!
评论