海思3559万能平台搭建:OSD的自动反色

简介: OSD的自动反色

前言

 OSD功能在之前两篇中已经满足了大部分的应用场景,为了进一步提升效率和自适应环境亮度和反色,这里介绍改进方法

效率提升

 我们之前整体的流程框架是这样的:TTF初始化,打开字体,区域初始化后while1通过SDL_CreateRGBSurface创建大的位图,再分别渲染小的位图通过SDL_LowerBlit叠到大位图上,  memcpy大位图数据到海思的区域结构体BITMAP_S,然后释放资源

 每次需要通过TTF_RenderUTF8_Solid渲染更新内容没法避免,而且这个是必须每次都释放的,一定要记得SDL_FreeSurface。但是频繁的SDL_CreateRGBSurface和SDL_FreeSurface就没有必要了,可以只创建一次,然后while1通过SDL_FillRect来达到更新的作用(不然就都糊一起啦)

 海思的区域设置部分不需要改动

HI_VOID osd_init(HI_VOID *arg)
{ 
    HI_S32 s32Ret;
    if (TTF_Init() < 0 ) 
    {  
        fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());  
        SDL_Quit();
    }  
    font = TTF_OpenFont(FONT_PATH, 29); 
    if ( font == NULL ) 
    {  
        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());  
        // return -1;
    }  
    pthread_t luma_update_id;
    s32Ret=pthread_create(&luma_update_id, NULL, &luma_update_task,NULL);
    if(s32Ret != 0)
    {
        SAMPLE_PRT("pthread video_process_osd create failed\n");
        // return -HI_FAILURE;
    }
    pthread_detach(luma_update_id);
    video_process_s* pstPara;
    pstPara = (video_process_s*)arg;
    time_t now;
    struct tm *ptm;
    char timestr[OSD_LENGTH] = {0};
    char lost_target_info_str[OSD_LENGTH] = {0};
    char other_info_str[OSD_LENGTH] = {0};
    char trk_str[OSD_LENGTH] = {0};
    char frame_str[OSD_LENGTH] = {0};
    osd_fmt = (SDL_PixelFormat*)malloc(sizeof(SDL_PixelFormat));
    hi_memset(osd_fmt,sizeof(SDL_PixelFormat),0,sizeof(SDL_PixelFormat));
    osd_fmt->BitsPerPixel = 16;
    osd_fmt->BytesPerPixel = 2;
    osd_fmt->colorkey = 0xffffffff;
    osd_fmt->alpha = 0xff;
    osd_bottom_left = SDL_CreateRGBSurface(SDL_SWSURFACE, OSD_BOTTOM_LEFT_W, OSD_BOTTOM_LEFT_H, 
                                    osd_fmt->BitsPerPixel,osd_fmt->Rmask, osd_fmt->Gmask, osd_fmt->Bmask, osd_fmt->Amask);
    osd_top_left = SDL_CreateRGBSurface(SDL_SWSURFACE, OSD_TOP_LEFT_W, OSD_TOP_LEFT_H, 
                                    osd_fmt->BitsPerPixel,osd_fmt->Rmask, osd_fmt->Gmask, osd_fmt->Bmask, osd_fmt->Amask);
    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); 
    snprintf(lost_target_info_str,100,"脱靶信息:X:%02d,Y:%02d",osd_fmt->BitsPerPixel,osd_fmt->BytesPerPixel);
    snprintf(other_info_str,100,"视场角信息:X:%02d,Y:%02d,焦距:%02d",osd_fmt->BitsPerPixel,osd_fmt->BytesPerPixel,osd_fmt->BytesPerPixel);
    snprintf(trk_str,100,"跟踪器状态:检测?识别?跟踪? ");
    snprintf(frame_str,100,"帧率:%02d",osd_fmt->BytesPerPixel);
    string_to_bmp_bottom_left(lost_target_info_str,other_info_str,timestr);
    string_to_bmp_top_left(trk_str,frame_str);
    RGN_AddOsdToVpss_bottom_left(pstPara->VpssChn);
    RGN_AddOsdToVpss_top_left(pstPara->VpssChn);
}
HI_S32 string_to_bmp_bottom_left(char *pu8Str_losttargrt_info,char *pu8Str_other_info,char *pu8Str_time)
{
    SDL_Rect bounddst,boundsrc;
    // printf("before TTF_RenderUTF8_Solid\n");
    osd_time_text            = TTF_RenderUTF8_Solid(font, pu8Str_time, forecol);
    osd_losttarget_info_text = TTF_RenderUTF8_Solid(font, pu8Str_losttargrt_info, forecol);
    osd_other_info_text      = TTF_RenderUTF8_Solid(font, pu8Str_other_info, forecol);
    boundsrc.x = 0;
  boundsrc.y = 0;
    boundsrc.w = OSD_BOTTOM_LEFT_W;
    boundsrc.h = OSD_BOTTOM_LEFT_H;
    SDL_FillRect(osd_bottom_left,&boundsrc,SDL_MapRGB(osd_bottom_left->format, 0, 0, 0));//起到更新作用
    boundsrc.x = 0;
  boundsrc.y = 0;
  boundsrc.w = osd_losttarget_info_text->w;
  boundsrc.h = osd_losttarget_info_text->h;
    bounddst.x = 0;
  bounddst.y = 0;
  bounddst.w = osd_losttarget_info_text->w;
  bounddst.h = osd_losttarget_info_text->h;
  SDL_LowerBlit(osd_losttarget_info_text, &boundsrc, osd_bottom_left, &bounddst); 
    // SDL_UpdateRect(osd_losttarget_info_text,0,0,osd_losttarget_info_text->w,osd_losttarget_info_text->h); 
  boundsrc.x = 0;
  boundsrc.y = 0;
  boundsrc.w = osd_other_info_text->w;
  boundsrc.h = osd_other_info_text->h;
    bounddst.x = 0;
  bounddst.y = osd_losttarget_info_text->h;
  bounddst.w = osd_other_info_text->w;
  bounddst.h = osd_other_info_text->h;
  SDL_LowerBlit(osd_other_info_text, &boundsrc, osd_bottom_left, &bounddst);
    // SDL_UpdateRect(osd_other_info_text,0,0,osd_other_info_text->w,osd_other_info_text->h);
    boundsrc.x = 0;
  boundsrc.y = 0;
  boundsrc.w = osd_time_text->w;
  boundsrc.h = osd_time_text->h;
    bounddst.x = 0;
  bounddst.y = osd_losttarget_info_text->h+osd_other_info_text->h;
  bounddst.w = osd_time_text->w;
  bounddst.h = osd_time_text->h;
  SDL_LowerBlit(osd_time_text, &boundsrc, osd_bottom_left, &bounddst);
    // SDL_UpdateRect(osd_time_text,0,0,osd_time_text->w,osd_time_text->h);
     for(int uj=0;uj<hSubcnt[1];uj++)
    {
        for(int ui=0;ui<wSubcnt[1];ui++)
        {
            int uk=uj*wSubcnt[1]+ui;
            if(g_aRectLuma[1][uk]>luma_value)
            {
                unsigned short int *dptr=(unsigned short int*)osd_bottom_left->pixels;                  
                for(int osd_h=0;osd_h<OSD_BOTTOM_LEFT_H;osd_h++)
                {
                    for(int osd_w=0;osd_w<OSD_BOTTOM_LEFT_W;osd_w++)
                    {
                       dptr[osd_h*OSD_BOTTOM_LEFT_W+osd_w]=(dptr[osd_h*OSD_BOTTOM_LEFT_W+osd_w])& 0x8000;
                    }
                }
            }
        }
    }
    hi_memset(stBitmap_bottom_left.pData, (2*OSD_BOTTOM_LEFT_W*OSD_BOTTOM_LEFT_H),0, (2*OSD_BOTTOM_LEFT_W*OSD_BOTTOM_LEFT_H));
  hi_memcpy(stBitmap_bottom_left.pData, (2*OSD_BOTTOM_LEFT_W*OSD_BOTTOM_LEFT_H),osd_bottom_left->pixels, (2*OSD_BOTTOM_LEFT_W*OSD_BOTTOM_LEFT_H));
    stBitmap_bottom_left.u32Width = OSD_BOTTOM_LEFT_W;
    stBitmap_bottom_left.u32Height = OSD_BOTTOM_LEFT_H;  
    SDL_FreeSurface(osd_time_text);  
    SDL_FreeSurface(osd_losttarget_info_text); 
    SDL_FreeSurface(osd_other_info_text); 
    return 0;
}

 另外令人疑惑的是SDL_UpdateRect看起来是更新窗口的函数,一旦调用就会导致段错误,对SDL库理解不深,暂时放下以后在研究吧

反色功能

 SDL和海思对于黑色的算法应该是不一样的,也可能是海思的小bug,海思会认为SDL位图这边的黑色是透明色!RGB的值实测在0x80之下好像都没起到作用。更换颜色很容易,变成黑色很困难

而海思自己的反色机制又是个摆设

 所以只能通过我们手动获取区域亮度,调好阈值,在超过指定亮度时,将我们的白色每个数值&0x8000达到反色的效果

 获取区域两度的函数海思的vpss部分给出HI_MPI_VPSS_GetRegionLuma,缺点是其占用资源极大,为了在方便实用的同时兼顾效率,可以单独开个线程获取亮度


HI_VOID *luma_update_task(HI_VOID*arg)
{
    VIDEO_REGION_INFO_S     stRegionInfo_top_left;
    VIDEO_REGION_INFO_S     stRegionInfo_bottom_left;
    RECT_S   LumaRect_top_left[64]={0};
    RECT_S   LumaRect_bottom_left[64]={0};
     /* 获取区域亮度copy from suxuandong */
    wSubcnt[0]=osd_top_left_wh[0][0]/OSDGRIDSIZE;
    hSubcnt[0]=osd_top_left_wh[0][1]/OSDGRIDSIZE;
    stRegionInfo_top_left.u32RegionNum=wSubcnt[0]*hSubcnt[0];
    for(int uj=0;uj<hSubcnt[0];uj++)
        {
            for(int ui=0;ui<wSubcnt[0];ui++)
            {
                LumaRect_top_left[uj*wSubcnt[0]+ui].s32X=osd_top_left_xy[0][0]+ui*OSDGRIDSIZE;
                LumaRect_top_left[uj*wSubcnt[0]+ui].s32Y=osd_top_left_xy[0][1]+uj*OSDGRIDSIZE;
                LumaRect_top_left[uj*wSubcnt[0]+ui].u32Width=OSDGRIDSIZE;
                LumaRect_top_left[uj*wSubcnt[0]+ui].u32Height=OSDGRIDSIZE;
            }
        }
    stRegionInfo_top_left.pstRegion=(RECT_S*)(LumaRect_top_left);
    /* 获取区域亮度copy from suxuandong */
    wSubcnt[1]=osd_bottom_left_wh[0][0]/OSDGRIDSIZE;
    hSubcnt[1]=osd_bottom_left_wh[0][1]/OSDGRIDSIZE;
    stRegionInfo_bottom_left.u32RegionNum=wSubcnt[1]*hSubcnt[1];
    for(int uj=0;uj<hSubcnt[1];uj++)
        {
            for(int ui=0;ui<wSubcnt[1];ui++)
            {
                LumaRect_bottom_left[uj*wSubcnt[1]+ui].s32X=osd_bottom_left_xy[0][0]+ui*OSDGRIDSIZE;
                LumaRect_bottom_left[uj*wSubcnt[1]+ui].s32Y=osd_bottom_left_xy[0][1]+uj*OSDGRIDSIZE;
                LumaRect_bottom_left[uj*wSubcnt[1]+ui].u32Width=OSDGRIDSIZE;
                LumaRect_bottom_left[uj*wSubcnt[1]+ui].u32Height=OSDGRIDSIZE;
            }
        }
    stRegionInfo_bottom_left.pstRegion=(RECT_S*)(LumaRect_bottom_left);
    while(1)
    {
         sleep(5);
         HI_MPI_VPSS_GetRegionLuma(0, 0, &stRegionInfo_top_left,g_aRectLuma[0], GETLUMAMILISECS);
         HI_MPI_VPSS_GetRegionLuma(0, 0, &stRegionInfo_bottom_left,g_aRectLuma[1], GETLUMAMILISECS);
    }
}

 线程的打开在上面初始化做了,对于反色的处理,在叠加部分给出

效果

b78c5be671274adbb369c67d38ab5263.png


相关文章
|
数据安全/隐私保护 块存储
|
3月前
|
存储 搜索推荐 测试技术
深入探索装机设置:打造个性化与高性能并存的电脑系统
装机设置是一个涉及多个方面的复杂过程,需要我们在硬件选择、操作系统安装、软件安装、性能优化以及个性化设置等多个层面进行综合考虑与实施。通过本文的介绍与探讨,我们希望能够帮助读者打造一个既个性化又高性能的电脑系统,让电脑成为我们工作与生活中的得力助手。同时,我们也希望读者能够在装机过程中不断探索与实践,发掘更多有趣的功能与设置方法,让电脑系统更加符合自己的需求与期望。
40 7
|
3月前
|
存储 监控 搜索推荐
深度解析:装机设置全攻略,打造个性化高性能电脑
装机不仅仅是一个技术活,更是一个充满乐趣和创造性的过程。通过精心的硬件选择、兼容性的考虑、操作系统的安装与优化、个性化的设置以及性能测试与调优,你可以打造出一台符合自己使用习惯、性能出众的个性化电脑。同时,不要忽视备份与恢复策略的重要性,确保你的数据和系统安全无忧。希望本文能够为你提供有用的指导和启发,让你在装机的道路上更加得心应手。
43 1
|
3月前
|
运维 小程序 前端开发
好的商业模式-----小程序定制资料,加一张好看的海报,在推广中就可以找到用户中了,云服务部署收5000,部署是一种服务,定制化,游戏开发创者,仲裁劳务会剪视频好,提供服务,想增加一些新功能收费,会说
好的商业模式-----小程序定制资料,加一张好看的海报,在推广中就可以找到用户中了,云服务部署收5000,部署是一种服务,定制化,游戏开发创者,仲裁劳务会剪视频好,提供服务,想增加一些新功能收费,会说
|
4月前
|
传感器 安全 Go
程序与技术分享:3D打印机如何添加自动调平功能
程序与技术分享:3D打印机如何添加自动调平功能
77 0
|
缓存 负载均衡 NoSQL
山东布谷科技直播软件源码Nginx服务器横向扩展:搭建更稳定的平台服务
Nginx服务器横向扩展提高了[直播软件源码](https://developer.aliyun.com/article/1302799?spm=a2c6h.13148508.setting.15.65934f0e6yi0Cp)性能,使直播软件源码平台性容错性、负载能力、处理高并发能力等能力有了极大地提升,确保了平台向着更高心梗、更稳定的方向发展,并且这样,使用户的体验大大增加,增加用户黏性,增多了用户的数量。
山东布谷科技直播软件源码Nginx服务器横向扩展:搭建更稳定的平台服务
|
网络协议 网络虚拟化
中兴设备show命令大全,涉及中兴业务的网络工程师可以着重了解一下!
中兴设备show命令大全,涉及中兴业务的网络工程师可以着重了解一下!
789 0
|
BI 数据库 C语言
西门子PCS7系统中央归档服务器、维护站、OpenPCS7站的作用是什么?如何安装?
今天我们简单介绍一下西门子PCS7系统中央归档服务器、维护站、OpenPCS7站的作用是什么以及如何安装。
西门子PCS7系统中央归档服务器、维护站、OpenPCS7站的作用是什么?如何安装?
下一篇
无影云桌面