网络视频监控与人脸识别

明天又要去面试了,趁次机会也将以前做的东西总结一下,为以后理解提供方便,也再加深下印象。

网络视频监控与人脸识别主要由三个程序组成:1、视频采集与传输程序;2、接受与显示程序;3、人脸识别程序。下面就分别来分析一下这三个程序。

一、视频采集与传输程序(Servfox)

网络视频监控与人脸识别_第1张图片

关键部分解析:

1、视频数据采集(可采用共享内存方式和读方式)

int v4lGrab (struct vdIn *vd )
{
  static	int frame = 0;		
  int len;
  int size;
  int erreur = 0;
  int jpegsize = 0;

  struct frame_t *headerframe;
  double timecourant =0;
  double temps = 0;
  timecourant = ms_time();
  
  if (vd->grabMethod)  /*共享内存方式*/
    {
      vd->vmmap.height = vd->hdrheight;
      vd->vmmap.width = vd->hdrwidth;
      vd->vmmap.format = vd->formatIn;
	  
     /*该函数成功返回则表示一帧采集已完成,采集到的图像数据放到
     起始地址为 vd->map+vd->mbuf.offsets[vd->frame]
     的内存区中,读取该内存区中的数据便可得到图像数据。
     接着可以做下一次的 VIDIOCMCAPTURE。*/
      if (ioctl (vd->fd, VIDIOCSYNC, &vd->vmmap.frame) < 0)  

	{
	  perror ("cvsync err\n");
	  erreur = -1;
	}
     
	/* Is there someone using the frame */  
    while((vd->framelock[vd->frame_cour] != 0) && vd->signalquit)
   	usleep(1000);
	pthread_mutex_lock (&vd->grabmutex);
         temps = ms_time();
	/*采集完成,进行jpeg压缩处理,里面大有文章*/
	 jpegsize= convertframe(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),
	 		vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame],
			vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn);
	/*填充数据帧信息头*/
	 headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour];
	 snprintf(headerframe->header,5,"%s","SPCA"); 
	 headerframe->seqtimes = ms_time();
	 headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant); 
	 headerframe->w = vd->hdrwidth;
	 headerframe->h = vd->hdrheight;
	 headerframe->size = (( jpegsize < 0)?0:jpegsize);
	 headerframe->format = vd->formatIn;
	 headerframe->nbframe = frame++; 
	// printf("compress frame %d times %f\n",frame, headerframe->seqtimes-temps);
	
	pthread_mutex_unlock (&vd->grabmutex); 
	/************************************/
	
      if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0)
	{
	  perror ("cmcapture");
	  if(debug) printf (">>cmcapture err \n");
	  erreur = -1;
	}
      vd->vmmap.frame = (vd->vmmap.frame + 1) % vd->videombuf.frames;
      vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB;
      //if(debug) printf("frame nb %d\n",vd->vmmap.frame);

    }
  else     /* 读方式*/
     {
      size = vd->framesizeIn;
      len = read (vd->fd, vd->pFramebuffer, size);
      if (len < 0 )
	{
	  if(debug) printf ("v4l read error\n");
	  if(debug) printf ("len %d asked %d \n", len, size);
	  return 0;
	}
	
      /* Is there someone using the frame */
       while((vd->framelock[vd->frame_cour] != 0)&& vd->signalquit)
   	usleep(1000);
	pthread_mutex_lock (&vd->grabmutex);
          temps = ms_time();
	 jpegsize= convertframe(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),
	 		vd->pFramebuffer ,
			vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn); 
	
	 headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour];
	 snprintf(headerframe->header,5,"%s","SPCA"); 
	 headerframe->seqtimes = ms_time();
	 headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant); 
	 headerframe->w = vd->hdrwidth;
	 headerframe->h = vd->hdrheight;
	 headerframe->size = (( jpegsize < 0)?0:jpegsize); 
	 headerframe->format = vd->formatIn; 
	 headerframe->nbframe = frame++; 
	 //  if(debug) printf("compress frame %d times %f\n",frame, headerframe->seqtimes-temps);
	
	vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB;  
	pthread_mutex_unlock (&vd->grabmutex); 
      /************************************/
     
    }
  return erreur;
}


2、数据通过socket通信方式发送

for (;;)
    {   
          memset(&message,0,sizeof(struct client_t));
	/*接受网络数据,保存在message 结构体中*/
	 ret = read(sock,(unsigned char*)&message,sizeof(struct client_t)); 
           /*根据接受到的控制信息进行控制*/
           /*大小调节*/
	 else if (message.updosize){ //compatibility FIX chg quality factor ATM
	 	switch (message.updosize){
		case 1: qualityUp(&videoIn);
		break;
		case 2: qualityDown(&videoIn);
		break;
		}
		ack = 1;
	} 
	 /*帧数调节*/
	 else if (message.fps){
	 	switch (message.fps){
		case 1: timeDown(&videoIn);
		break;
		case 2: timeUp(&videoIn);
		break;
		}
		ack = 1;
	} 
	 /*睡眠控制*/
	 else if (message.sleepon){
		ack = 1;
	 } 
	 else ack =0;
       while ((frameout == videoIn.frame_cour) && videoIn.signalquit)   usleep(1000);
       if (videoIn.signalquit){
	videoIn.framelock[frameout]++;
     	  headerframe = (struct frame_t *) videoIn.ptframe[frameout];
	  headerframe->acknowledge = ack;
	  headerframe->bright = bright;
	  headerframe->contrast = contrast;
	  headerframe->wakeup = wakeup;
	  /*发送数据帧头信息*/
	 ret = write_sock(sock, (unsigned char *)headerframe, sizeof(struct frame_t)) ;	 
	 if(!wakeup)	
	 /*发送数据帧信息*/
	 ret = write_sock(sock,(unsigned char*)(videoIn.ptframe[frameout]+sizeof(struct frame_t)),headerframe->size);	 
	 videoIn.framelock[frameout]--;
	 frameout = (frameout+1)%4;     
      } else {
       if(debug) printf("reader %d going out \n",*id);
	break;
      }
    }
  close_sock(sock);
  pthread_exit(NULL);
}


二、接受与显示程序
1、JPEG图片压缩原理

实际上,一个平面的图像,可以理解为除了水平 X 和垂直 Y 以外,还有一个色彩值的 Z 的三维的系统。Z 代表了三元色中各个分支 R/G/B 的混合时所占的具体数值大小,每个像素的 RGB 的混合值可能都有所不同,各个值有大有小,但临近的两个点的 R/G/B 三个值会比较接近。两个相邻的点,会有很多的色彩是很接近的,那么如何能在最后得到的图片中,尽量少得记录这些不需要的数据, 也即达到了压缩的效果。
 

 

你可能感兴趣的:(网络,struct,socket,面试,null,人脸识别)