Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示

您所在的位置:网站首页 香橙派嵌入式linux Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示

Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示

2023-07-14 05:22| 来源: 网络整理| 查看: 265

项目场景:

项目需求,需要做一个基于边缘端的人脸识别远程监控摄像头并在网页前端展示 ,这里采用国产香橙派作为边缘计算终端,安装ubuntu系统,系统中采用v4l2接口对摄像头进行获取,当客户端通过网页进行请求时,服务器通过http服务的形式将一帧帧图像发送给客户端,只要一秒钟能够传送25帧左右,展示效果就是在网页端播放视频:

问题描述1

怎样从摄像头里面获取帧数据,这里我们将USB摄像头连接在开发板上:

 可以看到,确实是有video0这个摄像头,该摄像头就是外接的USB摄像头

解决方案1:

采用V4L2接口通过中断将内核状态读取到的数据映射到用户空间:

 以下代码是将内核空间与用户空间进行映射

for(int i = 0; i 动态显示当前时间的钟表 canvas{ border: 1px solid black; } (function(){ //cavas元素对象 var canvas=null; //canvas的3d上下文 var ctx=null; //cavan的尺寸 var cw=0; var ch=0; /** * 页面导入时的事件处理 */ window.addEventListener("load",function(){ canvas=document.getElementById("sample"); ctx=canvas.getContext("2d"); cw=parseInt(canvas.width); ch=parseInt(canvas.height); ctx.translate(cw/2, ch/2); //绘制时钟 draw_watch(); },false); /** * 绘制时钟 */ function draw_watch(){ //清空Canvas ctx.clearRect(-cw/2,-ch/2,cw,ch); //计算针的最大长度 var len=Math.min(cw, ch)/2; //绘制刻度盘 var tlen=len*0.85; ctx.font="14px 'Arial'"; ctx.fillStyle="black"; ctx.textAlign="center"; ctx.textBaseLine="middle"; for(var i=1; i12 ){ h=h-12; } //绘制时针 var angle1 = Math.PI * 2 *(3 - (h+ m/60))/12; var length1=len * 0.5; var width1=5; var color1="#000000"; drawhand(angle1,length1,width1,color1); //绘制分针 var angle2 = Math.PI * 2 *(15 - (m+ s/60))/60; var length2=len * 0.7; var width2=3; var color2="#555555"; drawhand(angle2,length2,width2,color2); //绘制秒针 var angle3 = Math.PI * 2 *(15 - s)/60; var length3=len * 0.8; var width3=1; var color3="#aa0000"; drawhand(angle3,length3,width3,color3); //设置timer setTimeout(draw_watch,1000); } /** * 针绘制函数 */ function drawhand(angle,len,width,color){ //计算针端的坐标 var x=len*Math.cos(angle); var y=-len * Math.sin(angle); //绘制针 ctx.strokeStyle=color; ctx.lineWidth=width; ctx.lineCap="round"; ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(x,y); ctx.stroke(); } })();

 

最后附上总代码 #include #include #include #include #include #include #include #include #include #include /* superset of previous */ #include #include "sd_usb_pic.h" #include #include #include #include #include #include #include /* See NOTES */ #include #include #define HTTP_PORT 8080 //HTTP服务器端口号 pthread_mutex_t mutex; pthread_cond_t hasNode = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; char jpg_buff[614400]; //保存从USB摄像头读取的图像矩阵 int send_html_cnt = 0 ; /* 服务端响应客户端请求 "HTTP/1.1 200 OK\r\n" "Content-type:image/jpeg\r\n" "Content-Length:1234\r\n" "\r\n" 形参:c_fd --客户端套接字 type --文件类型 file --要发送的文件 返回值:0成功,其它失败 */ void *ppp_tr = NULL; int fd_fb; static struct fb_var_screeninfo var; /* LCD可变参数 */ static unsigned int *fb_base = NULL; /* Framebuffer映射基地址 */ int lcd_w = 800 ,lcd_h= 480; //定义显示器分辨率 /* 形参:c_fd --客户端套接字 type --文件类型 file --要发送的文件 返回值:0成功,其它失败 */ int Http_SendData(int c_fd,const char *type,const char *file) { int fd=open(file,O_RDONLY);//打开文件 if(fd= 614400 ) {break;}//发送完成 } pthread_mutex_unlock(&mutex); return 0; } /* HTTP长连接处理客户端请求 "HTTP/1.0 200 OK\r\n" "Server: wbyq\r\n" "Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n" "\r\n" "--boundarydonotcross\r\n" */ int Http_Content(int c_fd) { char buff[1024]={0}; /*建立长连接*/ snprintf(buff,sizeof(buff),"HTTP/1.0 200 OK\r\n" "Server: wbyq\r\n" "Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n" "\r\n" "--boundarydonotcross\r\n"); if(write(c_fd,buff,strlen(buff))!=strlen(buff))return -1;//发送报文头失败 int jpe_image_size = 614400;//保存jpeg图像大小 //int send_html_cnt = 0 ; clock_t t1; t1 = clock(); char save_name[10]; int save_idx = 0 ; struct timeval start_time, end_time; while(1) { //auto beg = clock(); t1 = clock(); pthread_cond_wait(&hasNode,&lock); //printf("wait time is %d us \n", (clock() - t1) ); auto beg = clock(); gettimeofday(&start_time, NULL); /* (1)响应报文头 "Content-type:image/jpeg\r\n" "Content-Length:666\r\n" "\r\n" */ snprintf(buff,sizeof(buff), "Content-type:image/jpeg\r\n" "Content-Length:%d\r\n" "\r\n",jpe_image_size); if(write(c_fd,buff,strlen(buff))!=strlen(buff)) { return -2;//响应报文头失败 } /*发送jpg图像数据*/ //pthread_mutex_lock(&mutex);//互斥锁上锁 //pthread_cond_wait(&hasNode,&lock); void *ppptr = jpg_buff; //void *ppptr = ppp_tr; //sprintf(save_name,"my_%d.jpg",save_idx++); //FILE *file=fopen(save_name, "w"); //fwrite(ppptr , 614400, 1,file); //close(file); int cnt = 0 ; while(1) { int size= 1024 * 600; //int size= 1024 ; int wt_len = write(c_fd,ppptr,size);//发送失败 cnt += wt_len ; ppptr += wt_len ; if(cnt >= 614400 ) {break;}//发送完成 } //pthread_mutex_unlock(&mutex);//互斥锁上锁 //pthread_mutex_unlock(&lock); //sleep(20); /* (3)发送间隔字符串 "\r\n" "--boundarydonotcross\r\n" */ strcpy(buff,"\r\n--boundarydonotcross\r\n"); if(write(c_fd,buff,strlen(buff))!=strlen(buff)) { break;//发送间隔符失败 } auto end = clock(); gettimeofday(&end_time, NULL); double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0; //printf("sendtime is %d us \n", (end - beg) ); //printf("send cnt is %d us \n", send_html_cnt ); send_html_cnt++; //pthread_mutex_unlock(&lock); //usleep(40000); //auto beg = clock(); //printf("sendtime is %d ms \n", (end - beg) ); printf("sendtime is %d ms \n", timeuse ); pthread_mutex_unlock(&lock); usleep(1); } return -4;//发送图像数据失败 } /*线程工作函数*/ void *pth_work(void *arg) { int c_fd=*(int *)arg; free(arg); char buff[1024]={0}; int size; size=read(c_fd,buff,sizeof(buff)-1); if(size


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3