在图像视频监控中,需要在画面中增加监控地点、时间戳等水印,通过我之前写的 【opencv交叉编译移植到linux-arm开发板,并做测试】已经可以利用opencv方便的将时间戳打到抓拍的图像上。使用opencv打水印虽然简单方便,但存在两个缺点:
1.putText不可放置中文;
2.应用在视频OSD显然是不方便的,因为海思的region区域管理通常以bmp位图叠加的方式进行OSD,通过阅读官方SDK例程的sample_region源码可以看出,其例程是读入已有的bmp文件叠加在视频流中,例程中bmp是死的,是不会变化的。
而实际应用场景中需要生成变化的OSD并打到图像或视频流中,那么我们可以通过【将字符串生成位图,再叠加到图像视频】实现。
通过阅读大神的博客 【海思多媒体(MPP)开发(5)——区域管理(REGION&OSD字符显示)】,可见实现【字符串生成位图】需要使用并移植以下三个工具
1.freetype
2.SDL
3.SDL_ttf

目标明确后,开始着手移植吧。

一、freetype的下载、编译

1.下载freetype源码
http://mirror.yongbok.net/nongnu/freetype/,我下的是2.7.1版本,下载后解压得到文件夹freetype-2.7.1
2.编译安装
这里我们依旧使用cmake-gui进行交叉编译。需要注意的是CMAKE_INSTALL_PREFIX选项,选一个路径,并记住这个路径。这里我选择的是/usr/local路径。
cmake配置好后一次进行make、make install,完成后交叉编译的freetype头文件、库文件夹就分别在/usr/local/include /usr/local/lib中了。

二、SDL的下载、编译

1.下载SDL源码
http://www.libsdl.org/download-1.2.php
下载的是SDL-1.2.15.tar.gz,解压得到SDL-1.2.15文件夹,进入文件夹。
2.编译安装
进入之后进行编译配置

./configure --prefix=/opt/arm --disable-pulseaudio --disable-video-nanox -disable-video-qtopia --disable-static --enable-shared --disable-video-photon --disable-video-ggi --disable-video-svga --disable-video-aalib --disable-video-dummy --disable-video-dga --disable-arts --disable-esd --disable-alsa --disable-video-x11 --disable-nasm --disable-joystick --disable-input-tslib -enable-video-fbcon --host=arm-himix200-linux

注意最后的 --host= 后填你的交叉编译链。配置成功后再进行make、make install,完成后SDL的相关头文件、库就被安装到–prefix=指明的/opt/arm中去了。

三、SDL_ttf的下载、编译

1.下载SDL_ttf源码
http://www.libsdl.org/projects/SDL_ttf/release/
下载的是SDL_ttf-2.0.11.tar.gz,解压得到SDL_ttf-2.0.11文件夹,进入。
2.编译安装
进行编译配置,需要注意的就是配置交叉编译链、配置安装目录、配置之前安装的freetype、SDL目录,以及freetype、SDL对应的库文件目录。因为SDL_ttf的编译依赖于SDL和freetype。

./configure --host=arm-himix200-linux -prefix=/opt/arm --with-sdl-prefix=/opt/arm --with-freetype-prefix=/usr.local --without-x LDFLAGS=”-L/usr/local/lib  -L/opt/arm/lib -lSDL -lfreetype”

配置完成后进行make、make install。需要注意的是make过程中可能提示xxxx头文件找不到的情况,解决办法有两个:1.在上述配置代码中加入头文件的路径;2.在Makefile里直接加入头文件的路径。两种方法都可以。

四、运行测试程序

测试程序的最终目的就是将字符串转换为bmp位图,并且能运行在arm平台上。借鉴前辈【海思多媒体(MPP)开发(5)——区域管理(REGION&OSD字符显示)】的代码并做简单修改,如下。功能是生成几张时间位图,字符串中包含了中文、英文和符号,证明了生成位图的完整性。

test.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#include "SDL_ttf.h"
#include "time.h"

 
#define FONT_PATH       "./UbuntuMono-BI.ttf"
int string_to_bmp(char *pu8Str);
int cnt = 0;
int main()
{
    
    time_t now;
    struct tm *ptm;
    char timestr[100] = {0};
    while(1)
    {
        usleep(1000000);
        time(&now);
        ptm = localtime(&now);
        snprintf(timestr,100,"时间%d-%02d-%02d %02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
        string_to_bmp(timestr);
        memset(timestr,0,100);
        if(cnt++ > 5)
        {
            break;
        }
    }
    return 0;
}
 
int string_to_bmp(char *pu8Str)
{
    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();
    }  
 
    font = TTF_OpenFont(FONT_PATH, 80); 
    if ( font == NULL ) 
    {  
        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());  
    }  
 
    SDL_Color forecol = { 0xff, 0xff, 0xff, 0xff };  
    text = TTF_RenderUTF8_Solid(font, pu8Str, 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;
 
    temp = SDL_ConvertSurface(text,fmt,0);

    char savename[10] = {0};

    snprintf(savename,10,"%d.bmp",cnt);
    printf("savename = %s\n",savename);
    SDL_SaveBMP(temp, savename); 
 
    SDL_FreeSurface(text);  
    SDL_FreeSurface(temp);
    TTF_CloseFont(font);  
    TTF_Quit();  
 
    return 0;
}

交叉编译命令为

arm-himix200-linux-gcc test.c -I/opt/arm/include/SDL -L/opt/arm/lib -lSDL -lSDL_ttf -lpthread

可以看出使用了动态链接库,故将编译好的可执行文件复制到开发板后,还需要复制所需的so库文件到开发板的/lib目录下。可以先运行以下,缺哪个库就复制哪个库,都在之前交叉编译的SDL、SDL_ttf的lib目录下。
程序运行结果如下

/user/sdl # ./a.out 
savename = 0.bmp
savename = 1.bmp
savename = 2.bmp
savename = 3.bmp
savename = 4.bmp
savename = 5.bmp
savename = 6.bmp

运行完后看一下运行目录,已经生成了0~6张位图

/user/sdl # ls
0.bmp              3.bmp              6.bmp
1.bmp              4.bmp              UbuntuMono-BI.ttf
2.bmp              5.bmp              a.out

将位图复制到ubuntu下,可以看到与预期相符。
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
如此一来,就可以使用opencv,或者海思的region区域管理给图像视频添加任意水印OSD了。

————2020-06-04更新————

上述是从别人的例程那赋值粘贴而来,后来代码审核发现内存泄漏问题,原因很简单——fmt没有free。

Logo

更多推荐