这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 基于OK113i网页视频监控项目

共4条 1/1 1 跳转至

基于OK113i网页视频监控项目

工程师
2025-02-21 19:26:58     打赏

1.开发板简介
    OK113i-S开发板采用核心板+底板的结构形式,基于全志T113-i处理器设计开发,处理器为ARMCortex-A7, RISCV, HiFi4 DSP多核异构架构,主频1.2GHz,核心板有两种规格,分别是512MB DDR3L内存加8GB eMMC版本和256MB DDR3L内存加256MB SPI Nand版本。OK113i-S开发板将核心板的功能接口资源丰富、提供多种外设接口,如网卡、CPU内置音频Codec、ADC、TF Card、LVDS、RGB、WIFI、4G等功能接口。
2.硬件开发平台

开发平台:Linux-5.4
编译器:arm-linux-gnueabi-gcc 7.3.1
USB摄像头

OK113i开发板



实现功能:通过OK113i飞凌嵌入式开发板,采用USB设备头,通过V4L2框架实现视频图像采集。创建摄像头图像采集线程,搭建HTTP服务器,固定端口号为8080,建立HTTP长连接,实现网页视频监控。

3.功能实现
    1.移植交叉编译器arm-linux-gnueabi-gcc。
    2.移植矢量字库freetye。
    3.初始化摄像头,通过V4L2驱动框架实现摄像头编程;
    4.创建摄像头采集线程,搭建HTTP服务器,多线程处理http客户端数据请求,建立http长连接;
    5.采用互斥锁+条件变量方式实现多线程间资源保护,将摄像头采集图像实时上传至网页端;
4.矢量字库编译与移植

    FreeType 库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,可以非常方便我们开发字体显示相关的程序功能。它支持单色位图、反走样位图的渲染。 FreeType 库是高度模块化的程序库,虽然它是使用 ANSI C开发,但是采用面向对象的思想,因此, FreeType 的用户可以灵活地对它进行裁剪。关于freetype 的详细信息可以参考 freetype 的官方网站:https://www.freetype.org/来获取更多相关的信息。

  1. [wbyq@wbyq src_pack]$ tar xvf /mnt/hgfs/ubuntu/software_pack/freetype-2.4.10.tar.bz2

  2. [wbyq@wbyq src_pack]$ cd freetype-2.4.10/

  3. [wbyq@wbyq freetype-2.4.10]$ ./configure --prefix=$PWD/_install --host=arm-linux

  4. [wbyq@wbyq freetype-2.4.10]$ make && make install

5.V4L2摄像头编程

      V4L2 是 Video for linux2 的简称,为 linux 中关于视频设备的内核驱动。在 Linux 中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。V4L2 是针对 uvc 免驱 usb 设备的编程框架,主要用于采集 usb 摄像头等,编程模式如下:



摄像头初始化示例如下:

  1. /*


  2. 摄像头初始化


  3. 返回值:成功返回摄像头描述符,失败返回负数


  4. */


  5. int Video_Init(struct CAMERA *camera)


  6. {


  7.     int video_fd;


  8.     int i=0;


  9.         /*1.打开设备节点*/


  10.         video_fd=open(VIDEO_DEV,O_RDWR);


  11.         if(video_fd==-1)return -1;


  12.         /*2.设置摄像头格式*/


  13.         struct v4l2_format format;


  14.         memset(&format,0,sizeof(format));


  15.         format.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式


  16.         format.fmt.pix.width=800;


  17.         format.fmt.pix.height=480;


  18.         format.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;//图像数据格式yuyv


  19.         if(ioctl(video_fd,VIDIOC_S_FMT,&format))return -2;


  20.         printf("图像尺寸:%d * %dn",format.fmt.pix.width,format.fmt.pix.height);


  21.         camera->image_w=format.fmt.pix.width;


  22.         camera->image_h=format.fmt.pix.height;


  23.         /*3.向内核请求缓冲区*/


  24.         struct v4l2_requestbuffers reqbuf;


  25.         memset(&reqbuf,0,sizeof(reqbuf));


  26.         reqbuf.count=4;/*缓冲区个数*/


  27.         reqbuf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式


  28.         reqbuf.memory=V4L2_MEMORY_MMAP;/*内存映射*/


  29.         if(ioctl(video_fd,VIDIOC_REQBUFS,&reqbuf))return -3;


  30.         printf("缓冲区个数:%dn",reqbuf.count);


  31.         /*4.将缓冲区映射到进程空间*/


  32.         struct v4l2_buffer quebuff;


  33.         for(i=0;i< reqbuf.count;i++)


  34.         {


  35.                 memset(&quebuff,0,sizeof(quebuff));


  36.                 quebuff.index=i;//缓冲区数组下标


  37.                 quebuff.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式


  38.                 quebuff.memory=V4L2_MEMORY_MMAP;/*内存映射*/


  39.                 if(ioctl(video_fd,VIDIOC_QUERYBUF,&quebuff))return -4;


  40.                camera- >mamp_buff[i]=mmap(NULL,quebuff.length,PROT_READ|PROT_WRITE,MAP_SHARED,video_fd,quebuff.m.offset);


  41.                 printf("buff[%d]=%pn",i,camera->mamp_buff[i]);


  42.                 camera->mmap_size=quebuff.length;


  43.         }


  44.         /*5.将缓冲区添加到采集队列*/


  45.         for(i=0;i< reqbuf.count;i++)


  46.         {


  47.                 memset(&quebuff,0,sizeof(quebuff));


  48.                 quebuff.index=i;//缓冲区数组下标


  49.                 quebuff.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式


  50.                 quebuff.memory=V4L2_MEMORY_MMAP;/*内存映射*/


  51.                 if(ioctl(video_fd,VIDIOC_QBUF,&quebuff))return -5;


  52.         }


  53.         /*6.开启摄像头*/


  54.         int type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式


  55.         if(ioctl(video_fd,VIDIOC_STREAMON,&type))return -6;


  56.         return video_fd;


  57. }

6.搭建HTTP服务器
      HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World WideWeb )服务器传输超文本到本地浏览器的传送协议。
      HTTP 是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。一个 HTTP"客户端"是一个应用程序(Web 浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个 HTTP 的请求的目的。一个 HTTP"服务器"同样也是一个应用程序通过接收客户端的请求并向客户端发送 HTTP 响应数据。HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
HTTP服务器创建示例:

  1. /*1.创建网络套接字*/

  2.     sockfd=socket(AF_INET,SOCK_STREAM,0);

  3.     if(sockfd==-1)

  4.          {

  5.                  printf("创建socket套接字失败n");

  6.                  return 0;

  7.          }

  8.      /*允许绑定已使用的端口号*/


  9.          int on = 1;


  10.          setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));


  11.          /*2.绑定端口号*/


  12.          struct sockaddr_in addr=

  13.          {

  14.                 .sin_family=AF_INET,//IPV4

  15.                 .sin_port=htons(HTTP_SERVER_PORT),//端口号

  16.                 .sin_addr.s_addr=INADDR_ANY,//本地所有IP

  17.          };

  18.          if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr)))

  19.          {

  20.                  printf("绑定端口号失败n");

  21.                  return 0;

  22.          }

  23.          /*设置监听数量*/

  24.          listen(sockfd,100);

  25.          /*等待客户端连接*/

  26.          struct sockaddr_in c_addr;

  27.          socklen_t addrlen=sizeof(c_addr);

  28.          int c_fd;

  29.          int *p;

  30.          while(1)

  31.          {

  32.                  c_fd=accept(sockfd, (struct sockaddr *)&c_addr,&addrlen);

  33.                  if(c_fd==-1)continue;

  34.                  printf("%d 客户端连接成功%s:%dn",c_fd,inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));

  35.                  p=malloc(sizeof(int));

  36.                  *p=c_fd;

  37.                  pthread_create(&pthid,NULL,pth_work,p);

  38.                  pthread_detach(pthid);//设置分离属性

  39.          }  

7.网页视频监控处理

      创建摄像头采集线程,将采集的图像进行JPG格式编码,挺添加时间水印信息。摄像头处理线程如下:

  1. /*摄像头处理函数*/

  2. void *pth_camera_work(void *arg)

  3. {

  4.     LCD_Init();//LCD初始化

  5.     video_fd=Video_Init(&camera);//摄像初始化

  6.     if(video_fd< 0)

  7.     {

  8.         printf("摄像头初始化失败res=%dn",video_fd);

  9.         sig_work(2);

  10.     }

  11.     unsigned char *rgb_buff=malloc(camera.image_w*camera.image_h*3);//保存RGB颜色数据

  12.     jpg_buffer=malloc(camera.image_w*camera.image_h*3);//保存JPG图像数据

  13.     if(rgb_buff==NULL || jpg_buffer==NULL)

  14.     {

  15.         close(video_fd);

  16.         sig_work(2);

  17.     }

  18.     if(InitConfig_FreeType("simkai.ttf"))//矢量字库初始化失败

  19.     {

  20.         close(video_fd);

  21.         sig_work(2);

  22.     }

  23.     printf("摄像头开始采集数据n");

  24.     struct v4l2_buffer dqbuff;

  25.     time_t sec;

  26.     struct tm time_s;

  27.     char buff[100];

  28.     wchar_t wcs[200];

  29.     struct ImageDecodingInfo imagedata;

  30.     imagedata.Width=camera.image_w;

  31.     imagedata.Height=camera.image_h;

  32.     while(1)

  33.     {

  34.         memset(&dqbuff,0,sizeof(dqbuff));

  35.                 dqbuff.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//视频捕获格式

  36.                 dqbuff.memory=V4L2_MEMORY_MMAP;/*内存映射*/

  37.                 if(ioctl(video_fd,VIDIOC_DQBUF,&dqbuff))break;

  38.                 //printf("图像数据:mamp_buff[%d]=%pn",dqbuff.index,camera.mamp_buff[dqbuff.index]);

  39.         /*数据处理*/

  40.         sec=time(NULL); //获取系统秒单位时间

  41.         sec-=8*60*60;

  42.             localtime_r(&sec,&time_s);//将秒时间转换为时间结构体

  43.         strftime(buff,sizeof(buff),"%Y/%m/%d %k:%M:%S",&time_s);

  44.         swprintf(wcs,sizeof(wcs),L"时间:%s",buff);

  45.         yuv_to_rgb(camera.mamp_buff[dqbuff.index],rgb_buff,camera.image_w,camera.image_h);

  46.         imagedata.rgb=rgb_buff;

  47.         LCD_DrawText(10,10,35,L"凌嵌入式OK113i",camera.image_w,camera.image_h,rgb_buff);

  48.          LCD_DrawText(350,410,25,L"--基于嵌入式的居家安防报警系统设计",camera.image_w,camera.image_h,rgb_buff);

  49.         LCD_DrawText(10,50,29,wcs,camera.image_w,camera.image_h,rgb_buff);

  50.         LCD_Image(&imagedata);//图像显示

  51.         if(hasr051_stat)//JPG图片保存

  52.         {

  53.             strftime(buff,sizeof(buff),"%Y%m%d%k%M%S",&time_s);

  54.             char file_name[100];

  55.             snprintf(file_name,sizeof(file_name),"photo/%s.jpg",buff);

  56.             //printf("buff=%sn",buff);

  57.             SaveJPGImage(rgb_buff,camera.image_w,camera.image_h,file_name);//保存JPG图片

  58.         }

  59.         pthread_mutex_lock(&fastmutex);//互斥锁上锁

  60.         jpg_image_size=rgb_to_jpeg(camera.image_w,camera.image_h,camera.image_w*camera.image_h*3,rgb_buff,jpg_buffer,80);

  61.         pthread_cond_broadcast(&cond);//广播唤醒所有线程

  62.         pthread_mutex_unlock(&fastmutex);//互斥锁上锁

  63.         if(ioctl(video_fd,VIDIOC_QBUF,&dqbuff))break ;/*将缓冲区添加回采集队列*/

  64.     }

  65.     close(video_fd);

  66.     free(rgb_buff);

  67.     exit(0);

  68. }

8.运行效果

图片.png




关键词: OK113i     视频监控    

专家
2025-02-21 23:03:17     打赏
2楼

vv感谢分享


专家
2025-02-22 08:42:43     打赏
3楼

谢谢楼主分享


院士
2025-02-23 16:07:59     打赏
4楼

HTTP 协议: Hyper Text Transfer Protocol(超文本传输协议)。

谢谢分享。


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]