海思3516a实现OSD叠加水印

2023-05-16

文章目录

  • 前言
  • 一、三个文件的编译
  • 二、海思SDK使用步骤
    • 1.创建叠加字符
    • 2.添加叠加区域到视频通道
  • 总结


前言

两天的努力终于实现了,激动!在网上查阅了各种资料,只是有零散的信息,海思3516a上添加水印功能终于实现,过程还是比较艰辛的,在此记录,希望能对朋友们有所帮助,如果有帮助就点个赞吧,谢谢!


提示:以下是本篇文章正文内容,下面案例可供参考

一、三个文件的编译

freetype+SDL+SDL_ttf简介:
FreeType2是一个简单的跨平台的字体绘制引擎
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。
SDL_ttf是TrueType字体渲染库,使用SDL库,几乎一样的便携。这取决于FreeType2处理TrueType字体数据。它允许程序员使用多个TrueType字体无需代码的字体渲染程序本身。随着轮廓字体和反走样的力量,高质量的文本输出可以毫不费力的获得。
交叉编译可以参考一下网上的例子:
交叉编译链接1
交叉编译链接2

二、海思SDK使用步骤

1.创建叠加字符

代码如下(示例):

#include<stdio.h>
#include "./SDL/SDL.h"
#include "./SDL/SDL_ttf.h"

int main(int argc, const char *argv[])
{
    char pstr[128] = {0};
    if(argv[1] == NULL)
	{
		snprintf(pstr, 128, "%s","hello world");
	}
	else 
	{
		snprintf(pstr, 128, "%s", argv[1]);
	}
    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("./msyh.ttf", 15);
    if ( font == NULL )
    {
        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());
    }

    SDL_Color forecol = { 0x80, 0xff, 0x00, 0xff };//0 245 255
    text = TTF_RenderUTF8_Solid(font, pstr, forecol);
    //text = TTF_RenderUTF8_Shaded(font,pstr, forecol,forecol_gb);
    //TTF_RenderUTF8_Blended(font, pstr, 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;
    fmt->Amask = 0x8000;
    fmt->Rmask = 0x7C00;          //ARGB1555
    fmt->Gmask = 0x03E0;
    fmt->Bmask = 0x001f;

    //Uint32 colorkey=SDL_MapRGB(fmt,0xff,0xFF,0xFF);
    //SDL_SetColorKey(text, SDL_SRCALPHA, colorkey);
    temp = SDL_ConvertSurface(text,fmt,0);
    SDL_SaveBMP(temp, "save.bmp");

    SDL_FreeSurface(text);
    SDL_FreeSurface(temp);
    TTF_CloseFont(font);
    TTF_Quit();

    return 0;
}

这只是一个独立的例子,也是参考了网上网友编写的,可以测试一下编译出的库文件有没有问题。实际项目中不可能直接使用一张图片添加OSD,需要直接获取bmp图像的存储数据,然后在视频上叠加。下面给出代码:

TTF_Font *font = NULL;
   /* Initialize the TTF library */  
if ( TTF_Init() < 0 )
{
	return;  
}
   font = TTF_OpenFont("simhei.ttf", 33); 
   if ( font == NULL ) {  
	printf("%s %d The fonts is NULL !\n",__FUNCTION__,__LINE__);
	return;
}
   RgnHandle = 1;
char tmp_buf[128] = "如果要显示C++ Hello World";
   SDL_Color forecol=   { 0xff, 0xff, 0xff, 0xff};
SDL_Surface *text = TTF_RenderUTF8_Solid(font, tmp_buf, forecol);
   if(text == NULL)
{
	printf("%s:[%d] The text is NULL !\n",__FUNCTION__,__LINE__);
	return;
}
   	SDL_PixelFormat *fmt;
fmt = (SDL_PixelFormat*)malloc(sizeof(SDL_PixelFormat));
if(fmt == NULL)
{
	printf("%s:[%d] The fmt is NULL !\n",__FUNCTION__,__LINE__);
}
memset(fmt, 0, sizeof(SDL_PixelFormat));
fmt->BitsPerPixel = 16;
fmt->BytesPerPixel = 2;
fmt->Rmask = 0xff000000;//0x00FF0000
fmt->Gmask = 0x0000ff00;//0x0000FF00
fmt->Bmask = 0x000000ff;//0x000000FF
fmt->Amask = 0;
   fmt->colorkey = 0x000000ff; 
   fmt->alpha = 0xff; 
SDL_Surface *osd_test = SDL_ConvertSurface(text, fmt, 0);
   if(osd_test == NULL)
{
	printf("%s:[%d] The osd_test is NULL !\n",__FUNCTION__,__LINE__);
}

通过上述代码可以看出bmp图像数据存储在变量“osd_test”中的osd_test->pixels里,其中osd_test->w,osd_test->h中存储的是图像的真实尺寸大小,后面有用到。

2.添加叠加区域到视频通道

步骤如下:
(1)用户填充区域属性并创建区域。
(2)将该区域指定到具体通道中(如 VENC)。在指定到具体通道时,需要输入通道的显
示属性。
(3)以上步骤完成区域的创建和使用。用户还可以通过以下操作来控制区域属性以及在某
通道的通道显示属性。
“通过 HI_MPI_RGN_GetAttr、HI_MPI_RGN_SetAttr 获取和设置区域属性。
”通过 HI_MPI_RGN_SetBitMap(仅针对 Overlay)设置区域的位图信息。
“通过 HI_MPI_RGN_GetDisplayAttr 和 HI_MPI_RGN_SetDisplayAttr 获取和设置区
域在某通道(如 VENC 通道)的通道显示属性。
”最后用户可以将该区域从通道中撤出(非必须操作),再销毁区域。

/*该步骤是创建叠加区域*/
RGN_HANDLE RgnHandle;
RGN_ATTR_S stRgnAttr;
stRgnAttr.enType = OVERLAY_RGN;
stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_RGB_1555;//PIXEL_FORMAT_RGB_565 
stRgnAttr.unAttr.stOverlay.stSize.u32Width  = osd_test->w;
stRgnAttr.unAttr.stOverlay.stSize.u32Height = osd_test->h;
stRgnAttr.unAttr.stOverlay.u32BgColor = 0xffffff00;
   int overlay_w = stRgnAttr.unAttr.stOverlay.stSize.u32Width;
   int overlay_h = stRgnAttr.unAttr.stOverlay.stSize.u32Height;
RgnHandle = 1;
s32Ret = HI_MPI_RGN_Create(RgnHandle, &stRgnAttr);
if(HI_SUCCESS != s32Ret)
{
	SAMPLE_PRT("HI_MPI_RGN_Create (%d) failed with %#x!\n", \
			RgnHandle, s32Ret);
	return;
}
/*该步骤是将该区域指定到具体通道中*/
MPP_CHN_S stChn;
stChn.enModId = HI_ID_VENC;
stChn.s32DevId = 0;
stChn.s32ChnId = 0;
RGN_CHN_ATTR_S stChnAttr;
memset(&stChnAttr,0,sizeof(stChnAttr));
stChnAttr.bShow = HI_TRUE;
stChnAttr.enType = OVERLAY_RGN;
stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 0;
stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 1000;
stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 128;
stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 80;
stChnAttr.unChnAttr.stOverlayChn.u32Layer = 0;

stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = HI_FALSE;
stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp  = 0;

stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16*2;
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width = 16*2;
stChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 0;
//stChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn = HI_TRUE;
//stChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod = LESSTHAN_LUM_THRESH;

s32Ret = HI_MPI_RGN_AttachToChn(RgnHandle, &stChn, &stChnAttr);
if(HI_SUCCESS != s32Ret)
{
    SAMPLE_PRT("HI_MPI_RGN_AttachToChn (%d) failed with %#x!\n",\
            RgnHandle, s32Ret);
    return;
}
/*该步骤是设置区域的位图信息*/
Joseph_Osd_Bmp.pData = malloc(2*(osd_test->w)*(osd_test->h));
if(Joseph_Osd_Bmp.pData == NULL)
{
printf("%s:[%d] The osd_bmp_data is NULL ,when malloc !\n",__FUNCTION__,__LINE__);
}
printf("%s: bmp_w:[%d] bmp_h:[%d]", __FUNCTION__, osd_test->w, osd_test->h);
memset(Joseph_Osd_Bmp.pData,0,(2*(osd_test->w)*(osd_test->h)));

Joseph_Osd_Bmp.u32Width = osd_test->w;  
Joseph_Osd_Bmp.u32Height = osd_test->h;
memcpy(Joseph_Osd_Bmp.pData,osd_test->pixels,(2*(osd_test->w)*(osd_test->h)));	
//Joseph_Osd_Bmp->pData = osd_test->pixels;
Joseph_Osd_Bmp.enPixelFormat= PIXEL_FORMAT_RGB_1555;

s32Ret = HI_MPI_RGN_SetBitMap(RgnHandle,&Joseph_Osd_Bmp);
if(s32Ret != HI_SUCCESS)
{
    SAMPLE_PRT("HI_MPI_RGN_SetBitMap failed with %#x!\n", s32Ret);
    exit(0);
    return;
}
SDL_FreeSurface(text);
text = NULL;
SDL_FreeSurface(osd_test);
text = NULL;
free(fmt);
fmt = NULL;
free(Joseph_Osd_Bmp.pData);				
Joseph_Osd_Bmp.pData = NULL;
TTF_CloseFont(font);
font = NULL;
TTF_Quit();

重点来了,小伙伴们在尝试添加水印时,有可能会遇到明明水印文件字体是常规,不是倾斜的,但在视频上显示倾斜,而且还显示不全,这个问题我遇到了。

stRgnAttr.unAttr.stOverlay.stSize.u32Width  = osd_test->w;
stRgnAttr.unAttr.stOverlay.stSize.u32Height = osd_test->h;

这两句特别重要,如果你是随意设置的,就会出现这种现象,需要设置的和bmp图像大小一直才行,这个也是一点一点试出来的,先生成bmp数据,然后取得尺寸。
还遇到一个问题:我想把字号变大:

font = TTF_OpenFont("./msyh.ttf", 15)

你会发现设置一些数字后,在你运行程序时报错,报参数设置错误:0xA0038003 HI_ERR_RGN_ILLEGAL_PARAM 参数超出合法范围。这个地方还没有研究透彻,我设置23不行,25可以,30不行,33可以,挺怪的,后续再继续研究吧。最后上效果图:
在这里插入图片描述


总结

如果对你有帮助 点个赞再走吧,嘿嘿!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海思3516a实现OSD叠加水印 的相关文章

随机推荐

  • STM32F1C8T6Flash读取音频和DAC播放

    文章目录 一 Flash简介1 Flash原理2 STM32F1中的Flash 二 Flash地址空间的数据读取1 题目要求2 CUbeMX工程建立3 Keil工程修改4 STlink调试说明5 调试运行 三 基于片内Flash的提示音播放
  • C语言中的头文件为什么不能定义变量

    1 前提 在实际项目中 xff0c 会遇到这样的情况 xff0c 在链接阶段 xff0c 会提示定义在头文件中的变量 xff0c 重定义 xff0c 然后将将头文件中的变量定义成static类型 xff0c 然后 xff0c 不报错误了 例
  • Ubuntu16.04安裝ROS

    此文章在前人的基礎上 xff0c 並把安裝遇到的問題寫出來 Ubuntu16 04安装ROS Kinetic详细过程 https blog csdn net weixin 43159148 article details 83375218
  • B-spline的理解与路径规划中的应用及C++代码的实现

    研究项目 xff0c 无人机的路径规划 xff0c 需要用到B样条 xff0c 所以在此写下B spline的结合C 43 43 代码的理解以及在项目中的应用 一 阶数p 阶数 61 所有权重中t的最高次幂 61 控制点数量 1 xff1b
  • Jetson TX2 各个模式

    Jetson TX2 工作模式及相应的CPU和GPU频率 xff1a 上电的时候 xff0c 默认最低功耗模式1 xff0c 风扇不转 1 直接运行home下的jetson clocks sh xff0c 开启最大频率 sudo jetso
  • 网络通信基础知识—网络通信的发展历程

    网络通信基础知识 网络通信的发展历程 xff08 1 xff09 单机阶段 xff08 2 xff09 局域网阶段 xff08 3 xff09 广域网internet阶段 xff08 很多个局域网之间通信 xff09 xff08 4 xff
  • win7下装ubuntu双系统 硬盘安装详细教程

    本文转载自http www linuxidc com Linux 2014 10 108430 htm https jingyan baidu com article e4d08ffdace06e0fd2f60d39 html 在自己安装过
  • ROS导航——配置机器人的导航功能(move_base包)

    中间部分是整个导航的核心部分 xff0c 由move base功能包提供 配置如下 xff1a lt launch gt lt node pkg 61 34 move base 34 type 61 34 move base 34 resp
  • 基于docker安装tensorflow

    最近在自学机器学习 xff0c 大热的Tensorflow自然不能错过 xff0c 所以首先解决安装问题 xff0c 为了不影响本地环境 xff0c 所以本文基于Docker来安装Tensorflow xff0c 我的环境是Ubuntu16
  • okHttpUtil工具类

    pom文件 lt dependency gt lt groupId gt com squareup okhttp3 lt groupId gt lt artifactId gt okhttp lt artifactId gt lt vers
  • 基于采样的RRT/RRT*/RRT_connect算法笔记及C++实现

    本文记录常见的基于采样的RRT算法及相关改进算法 xff08 RRT xff0c RRT connect xff09 的原理和代码实现效果 与上一章介绍A 算法的文章不同 xff0c 本文会先给出几种算法之间的效果对比 xff0c 先有个直
  • STM32F103ZE驱动PMW3901光流模块

    本文将会简单的介绍如何使用STM32F103ZE驱动PMW3901光流模块 xff0c 使用标准库 所用材料如下 一块 STM32F103最小系统板以及一个 PMW3901光流模块 通过查阅PMW3901的数据手册可以得知 xff0c 该芯
  • 计算两圆相交面积

    转自 xff1a 模板 求两圆相交面积 xff08 模板 xff09 两圆相交分如下集中情况 xff1a 相离 相切 相交 包含 设两圆圆心分别是O1和O2 xff0c 半径分别是r1和r2 xff0c 设d为两圆心距离 又因为两圆有大有小
  • 深蓝学院-移动机器人运动规划重点笔记

    移动机器人运动规划笔记 xff0c 转载自https blog csdn net wqwqqwqw1231 article details 107310965 感谢原作者的总结 xff01
  • TFmini Plus在Arduino上的开发例程(二)

    本例程以Arduino Uno板为例 xff0c 通过Arduino实现TFmini Plus相关指令的写入 xff0c 上行数据的读取 判断和测量数据的获取打印 xff0c 主要帮助客户快速熟悉我公司雷达 xff0c 减少产品的研发周期
  • Linux命令发送Http GET/POST请求

    Linux命令发送Http GET POST请求 Get请求 1 使用curl命令 xff1a curl span class token string 34 http www baidu com 34 span 如果这里的URL指向的是一
  • VSCode 常用设置项

    代码编辑工具VSCode 常用设置项 span class token punctuation span span class token comment VScode主题配置 span span class token string 34
  • 机器人运动控制-上位机通讯

    机器人 xff0c 无论是工业机器人还是服务机器人等多种类机器人 xff0c 都有自己的控制器 在他们的控制面板上 xff0c 我们可以通过简单的操作和程序指令 xff0c 让机器人自行运动 为了让机器人更加智能 xff0c 我们需要在机器
  • Imu误差模型、零偏、零偏稳定性

    原文链接 零偏 xff0c 零偏稳定性和零偏重复性 xff0c IMU误差模型 什么是零偏 xff08 Bias xff09 在陀螺静止时 xff0c 陀螺仪仍会 xff0c 以规定时间内测得的输出量平均值相应的等效输入角速率表示 xff0
  • 海思3516a实现OSD叠加水印

    文章目录 前言一 三个文件的编译二 海思SDK使用步骤1 创建叠加字符2 添加叠加区域到视频通道 总结 前言 两天的努力终于实现了 xff0c 激动 xff01 在网上查阅了各种资料 xff0c 只是有零散的信息 xff0c 海思3516a