开源项目之视频会议程序 Omnimeeting

Omnimeeting是一个多平台的Ç+ +视频会议程序,使用库如 LiveMedia、OpenCv、DevIL、WxWidgets、ffmpeg等库,通过RTSP协议在互联网做到实时的摄像/音频流传输。它采用了流媒体的协议有:MJPEG、H263+、MP3、MP3ADU等等,它可以得到360度全方位影像和做一张脸检测/跟踪运动检测。一种新的算法,也可以做一个直接的全方位图像的人脸检测(支持人脸识别和跟踪提供I转换/发送全方位图像的API)。

项目如图:


程序效果如图:





omnimeeting提供的软件包包括omnistuff、streaming、gui三个主要文件和数据示例文件。

部分源码分析:

  1. //创建发送和接受流  
  2. void MainFrame::OnMenuPreferencesClick( wxCommandEvent& event )  
  3. {  
  4.   
  5.     if ( m_streamer_thread == NULL ) {  
  6.         m_streamer_thread = new StreamerCtrlThread( this );  
  7.     }  
  8.   
  9.     if ( m_receiver_thread == NULL ) {  
  10.         m_receiver_thread = new ReceiverCtrlThread( this );  
  11.     }  
  12.   
  13.       
  14.     DialogOptions* window = new DialogOptions(this, m_streamer_thread, m_receiver_thread, this,  
  15.         ID_OPTIONS, _("Preferences..."));  
  16.     window->Show(true);  
  17.   
  18. }  

  1. //创建发送和接受流  
  2. void MainFrame::OnMenuPreferencesClick( wxCommandEvent& event )  
  3. {  
  4.   
  5.     if ( m_streamer_thread == NULL ) {  
  6.         m_streamer_thread = new StreamerCtrlThread( this );  
  7.     }  
  8.   
  9.     if ( m_receiver_thread == NULL ) {  
  10.         m_receiver_thread = new ReceiverCtrlThread( this );  
  11.     }  
  12.   
  13.       
  14.     DialogOptions* window = new DialogOptions(this, m_streamer_thread, m_receiver_thread, this,  
  15.         ID_OPTIONS, _("Preferences..."));  
  16.     window->Show(true);  
  17.   
  18. }  

  1. //关闭 则释放资源  
  2. void MainFrame::OnCloseWindow( wxCloseEvent& event )  
  3. {  
  4.     // provide a clean deletion of objects.  
  5.     if ( m_receiver_thread && m_receiver_thread->isReceiving() ) {  
  6.         wxMessageDialog dlg1( this,   
  7.             wxT("Please stop by hand the receiver, then close.") , wxT( "Warning" ), wxOK );  
  8.         dlg1.ShowModal();  
  9.         return;  
  10.     }  
  11.   
  12.     if ( m_streamer_thread && m_streamer_thread->isStreaming() ) {  
  13.         wxMessageDialog dlg1( this,   
  14.             wxT("Please stop by hand the server streaming, then close."), wxT( "Warning" ), wxOK );  
  15.         dlg1.ShowModal();  
  16.         return;  
  17.     }  
  18.   
  19.     destroy_garbage_collector_for_images ();  
  20.   
  21.     wxWindow* window = this;  
  22.     window->Destroy();  
  23.   
  24.     event.Skip();  
  25. }  

  1. //停止服务  
  2. void MainFrame::OnMenuitemActionsStopServerClick( wxCommandEvent& event )  
  3. {  
  4.     if ( m_streamer_thread != NULL ) {  
  5.         if (  m_streamer_thread->isStreaming() ) {  
  6.             m_streamer_thread->stopStreaming();  
  7.   
  8.             PrintStatusBarMessage( wxT( "Streaming stopped" ), 0 );  
  9.   
  10.             // no need to delete the object! Being a thread it will auto-destroy after  
  11.             // its exiting  
  12.             // recreate a new ojbect  
  13.             m_streamer_thread = new StreamerCtrlThread( this );  
  14.         }  
  15.         else {  
  16.             wxMessageDialog dlg1( this, wxT( "Server is not running" ), wxT( "Info" ), wxOK );  
  17.             dlg1.ShowModal();  
  18.   
  19.             delete m_streamer_thread;  
  20.             m_streamer_thread = new StreamerCtrlThread( this );  
  21.         }  
  22.     }  
  23.     else {    
  24.         wxMessageDialog dlg1( this, wxT( "Server is not running" ), wxT( "Info" ), wxOK );  
  25.         dlg1.ShowModal();  
  26.     }  
  27. }  

  1. //停止接收  
  2. void MainFrame::OnMenuitemActionsStopReceivingClick( wxCommandEvent& event )  
  3. {  
  4.     if ( m_receiver_thread != NULL ) {  
  5.         if ( m_receiver_thread->isReceiving() ) {  
  6.             m_receiver_thread->StopReceiving();  
  7.   
  8.             PrintStatusBarMessage( wxT( "Receiving stopped" ), 1 );  
  9.         }  
  10.         else {  
  11.             wxMessageDialog dlg1( this, wxT( "Receiver is not running" ), wxT( "Info" ), wxOK );  
  12.             dlg1.ShowModal();  
  13.   
  14.             delete m_receiver_thread;  
  15.             m_receiver_thread = new ReceiverCtrlThread( this );  
  16.         }  
  17.     }  
  18.     else {    
  19.         wxMessageDialog dlg1( this, wxT( "Receiver is not running" ), wxT( "Info" ), wxOK );  
  20.         dlg1.ShowModal();  
  21.     }  
  22. }  

  1. //接收完毕则释放资源  
  2. void MainFrame::OnReceiverCtrlThreadEnd()   
  3. {  
  4.     // provide a stop for the face_detecting/tracking class if it's available  
  5.     if ( face_detect ) {  
  6.         if ( gcard_use == true ) {  
  7.             if ( ctrl_gcard ) {  
  8.                 ctrl_gcard->loop_stop();  
  9.   
  10.                 delete ctrl_gcard;  
  11.                 ctrl_gcard = NULL;  
  12.             }  
  13.   
  14.             if ( ctrl_vr_gcard ) {  
  15.                 ctrl_vr_gcard->loop_stop();  
  16.   
  17.                 delete ctrl_vr_gcard;  
  18.                 ctrl_vr_gcard = NULL;  
  19.             }  
  20.         }  
  21.         else {  
  22.             if ( ctrl_lookup ) {  
  23.                 ctrl_lookup->loop_stop();  
  24.   
  25.                 delete ctrl_lookup;  
  26.                 ctrl_lookup = NULL;  
  27.             }  
  28.             if ( ctrl_vr_lookup ) {  
  29.                 ctrl_vr_lookup->loop_stop();  
  30.   
  31.                 delete ctrl_vr_lookup;  
  32.                 ctrl_vr_lookup = NULL;  
  33.             }  
  34.   
  35.         }  
  36.   
  37.         ctrl_initialized = false;  
  38.         face_detect = false;  
  39.     }  
  40.   
  41.     // important!: set to null our class, so that we can recreate it when necessary  
  42.     m_receiver_thread = NULL;  
  43.   
  44.     reset_displayed_image_vector();  
  45.   
  46.     clear_garbage_collector_for_images();  
  47.   
  48.     video_received_window = false;  
  49. }  

omnistuff测试代码:

  1. int main(int argc, char**argv ) {  
  2.   
  3.     /* ok, hardcode them for now... */  
  4.     double min_radius = 40;  
  5.     double max_radius = 220;  
  6.     double omni_center_x = 326;  
  7.     double omni_center_y = 250;  
  8.     OmniAlgoSimpleDetection<OmniGCardConverter, double, IplImage, CvPoint> *ctrl;  
  9.     OmniConversion<OmniGCardConverter, double, IplImage, CvPoint> *conv;  
  10.     bool ctrl_initialized = false;  
  11.     IplImage *frame;  
  12.   
  13.     // init capturing  
  14.     CvCapture* capture = 0;  
  15.   
  16. #ifdef WIN32  
  17.     char* filename = "..\\..\\data\\videos\\video_test-1-divx5.avi";  
  18. #else  
  19.     char* filename = "../../data/videos/video_test-1-divx5.avi";  
  20. #endif  
  21.   
  22.   
  23.     // hardcoding... it ugly but this is a sample test file  
  24.     const int c_array_length = 2;  
  25.     const char *c_array[c_array_length];  
  26.   
  27. #ifdef WIN32  
  28.     // this seems to be the best Haar-cascade combination: it gives the lowest number of false-positive  
  29.     // Anyway improving the xml's with a good haar learning can rise up the performances.  
  30.     c_array[0] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_upperbody.xml";  
  31.     c_array[1] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_frontalface_default.xml";  
  32. #else  
  33.     c_array[0] = "../../omnistuff/data/haarcascades/haarcascade_upperbody.xml";  
  34.     c_array[1] = "../../omnistuff/data/haarcascades/haarcascade_frontalface_default.xml";  
  35. #endif  
  36.   
  37.     if ( argc != 2 ) {  
  38.         printf( "To play a different file read below.\n" );  
  39.         printf( "usage: %s <avi file>\n", argv[0] );  
  40.         printf( "Now using %s\n", filename );  
  41.     }  
  42.     else {  
  43.         filename = argv[1];  
  44.         printf( "Now using %s\n", filename );  
  45.     }  
  46.   
  47.   
  48.   
  49.     capture = cvCaptureFromAVI( filename );   
  50.   
  51.     while ( 1 ) {  
  52.         frame = cvQueryFrame( capture );  
  53.         if( !frame ) {  
  54.             printf( "Some error occurred or end of video reached\n");  
  55.             break;  
  56.         }  
  57.   
  58.         if ( !ctrl_initialized ) {  
  59.             conv = new OmniConversion<OmniGCardConverter, double, IplImage, CvPoint>(  
  60.                 new OmniGCardConverter(  min_radius,   
  61.                                  max_radius,   
  62.                                  omni_center_x,   
  63.                                  omni_center_y,   
  64.                                  640,  
  65.                                  480,  
  66.                                  "omnigcardo",  
  67.                                  "../../omnistuff/data/shaders/vertex_shader.cg",  
  68.                                  "vertex_shader_main",  
  69.                                  "../../omnistuff/data/shaders/pixel_shader.cg",  
  70.                                  "pixel_shader_main") );  
  71.       
  72.             if ( conv->is_initialized () ) {  
  73.                 printf("great, gcard is initialized and ready to use...\n");  
  74.                 ctrl_initialized = true;  
  75.             }  
  76.             else {  
  77.                 printf( "some problem occurred: no gcard available...\n");  
  78.                 exit(-1);  
  79.             }  
  80.   
  81.             ctrl = new OmniAlgoSimpleDetection<OmniGCardConverter, double, IplImage, CvPoint>( conv,   
  82.                                                                             frame,   
  83.                                                                             (const char**)c_array,  
  84.                                                                             c_array_length,  
  85.                                                                             FREEZE_FRAME_BOUND,  
  86.                                                                             TRACK_WINDOW_HITRATE);  
  87.         }  
  88.   
  89.         ctrl->loop_next_frame( frame );  
  90.   
  91.         cvWaitKey ( WAIT_KEY_VALUE );  
  92.     }  
  93.   
  94.     cvReleaseCapture( &capture );  
  95.   
  96.     return 0;  
  97. }  


omnitest测试代码:

  1. int main( int argc, char** argv ) {  
  2.   
  3. #ifdef WIN32  
  4.     char* filename = "..\\..\\data\\videos\\video_test-1-divx5.avi";  
  5. #else  
  6.     char* filename = "../../data/videos/video_test-1-divx5.avi";  
  7. #endif  
  8.   
  9.     if ( argc != 2 ) {  
  10.         printf( "To play a different file read below.\n" );  
  11.         printf( "usage: %s <avi file>\n", argv[0] );  
  12.         printf( "Now using %s\n", filename );  
  13.     }  
  14.     else {  
  15.         filename = argv[1];  
  16.         printf( "Now using %s\n", filename );  
  17.     }  
  18.           
  19.     MyTimer timer;  
  20.       
  21.     // hardcoding... it ugly but this is a sample test file  
  22.     const int c_array_length = 2;  
  23.     const char *c_array[c_array_length];  
  24.   
  25. #ifdef WIN32  
  26.     // this seems to be the best Haar-cascade combination: it gives the lowest number of false-positive  
  27.     // Anyway improving the xml's with a good haar learning can rise up the performances.  
  28.     c_array[0] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_upperbody.xml";  
  29.     c_array[1] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_frontalface_default.xml";  
  30. #else  
  31.     c_array[0] = "../../omnistuff/data/haarcascades/haarcascade_upperbody.xml";  
  32.     c_array[1] = "../../omnistuff/data/haarcascades/haarcascade_frontalface_default.xml";  
  33. #endif  
  34.   
  35.   
  36.     // Our OmniCtrl class.  
  37.     OmniLoopCtrl *ctrl;  
  38.     bool ctrl_initialized = false;  
  39.   
  40.     // one second of timeout  
  41.     timer.Start(1000);  
  42.   
  43.     IplImage *frame;  
  44.   
  45.     // init capturing  
  46.     CvCapture* capture = 0;  
  47.     capture = cvCaptureFromAVI( filename );   
  48.   
  49.     while ( 1 ) {  
  50.         frame = cvQueryFrame( capture );  
  51.         if( !frame ) {  
  52.             printf( "Some error occurred or end of video reached\n");  
  53.             break;  
  54.         }  
  55.   
  56.         if ( !ctrl_initialized ) {  
  57.             ctrl = new OmniLoopCtrl( frame,   
  58.                                     1/(double)RADIUS_MAX,   
  59.                                     RADIUS_MIN,  
  60.                                     RADIUS_MAX,  
  61.                                     CENTER_X,  
  62.                                     CENTER_Y,  
  63.                                     c_array,  
  64.                                     c_array_length,  
  65.                                     FREEZE_FRAME_BOUND,  
  66.                                     TRACK_WINDOW_HITRATE );  
  67.             ctrl_initialized = true;  
  68.         }  
  69.   
  70.         ctrl->loop_next_frame( frame );  
  71.         timer.frame_per_second++;  
  72.     }  
  73.   
  74.     cvReleaseCapture( &capture );  
  75.     timer.Stop();  
  76.     if ( ctrl_initialized ) {  
  77.         ctrl->loop_stop();  
  78.         delete ctrl;  
  79.     }  
  80.       
  81.     return 0;  
  82. }  

vrfilter_test测试代码:

  1. int main( int argc, char** argv )  
  2. {  
  3.     //time for fps  
  4.     double now_time, end_time ;  
  5.     char fps_buff [20];  
  6.     CvPoint fps_point = cvPoint(10, 450);  
  7.     CvFont font;  
  8.     cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX, 0.6f, 0.6f, 0.0f, 2, CV_AA);  
  9.     CvVideoWriter *avi_writer = NULL;  
  10.       
  11. #ifdef  USE_GRAPHIC_CARD  
  12.     OmniConversion<OmniGCardConverter, double, IplImage, CvPoint> *conv_gcard;  
  13.     OmniAlgoVRFilterDetection<OmniGCardConverter, double, IplImage, CvPoint> *ctrl_gcard;   
  14. #else  
  15.     OmniConversion<OmniFastLookupTable, int, IplImage, CvPoint> *conv_lu;  
  16.     OmniAlgoVRFilterDetection<OmniFastLookupTable, int, IplImage, CvPoint> *ctrl_lu;  
  17. #endif        
  18.       
  19.     /* ok, hardcode them for now... */  
  20.     int min_radius = 55;  
  21.     int max_radius = 220;  
  22.     int omni_center_x = 320;  
  23.     int omni_center_y = 255;  
  24.           
  25.     CvCapture* capture = 0;  
  26.     char *filename = NULL;    
  27.       
  28.     cvNamedWindow( "face_window", 1 );  
  29.       
  30.     if ( argc != 2 )  
  31.         filename =   
  32. #ifdef WIN32  
  33.         "..\\..\\data\\videos\\video_test-3-xvid.avi";  
  34. #else  
  35.         "../../data/videos/video_test-3-xvid.avi";  
  36. #endif  
  37.     else  
  38.         filename  = argv[1];  
  39. #ifdef SHOW_FPS_ON_IMAGE      
  40.     int fps = 0;  
  41.     int rate = 0;  
  42. #endif  
  43.   
  44.     capture = cvCaptureFromAVI( filename );   
  45.     printf("Using %s as omnidirectional video...\n", filename);  
  46.       
  47.     if( !capture )  
  48.     {  
  49.         fprintf(stderr,"Could not initialize capturing...\n");  
  50.         return -1;  
  51.     }  
  52.   
  53.     now_time = (double) clock ();  
  54.     end_time = (double) clock () + (1 * CLOCKS_PER_SEC);  
  55.     sprintf(fps_buff, " %d FPS", fps);  
  56.           
  57.     bool initialized = false;  
  58.   
  59.       
  60.     while ( 1 )  
  61.     {  
  62.         IplImage* frame = 0;  
  63.           
  64.         frame = cvQueryFrame( capture );  
  65.   
  66.         if( !frame )  
  67.             break;  
  68.   
  69.         if ( !initialized ) {  
  70. #ifdef  USE_GRAPHIC_CARD              
  71.             conv_gcard = new OmniConversion<OmniGCardConverter, double, IplImage, CvPoint>(  
  72.                     new OmniGCardConverter(min_radius,   
  73.                              max_radius,   
  74.                              omni_center_x,   
  75.                              omni_center_y,   
  76.                              640,  
  77.                              480,  
  78.                              "omnigcardo",  
  79.                              "../../omnistuff/data/shaders/vertex_shader.cg",  
  80.                              "vertex_shader_main",  
  81.                              "../../omnistuff/data/shaders/pixel_shader.cg",  
  82.                              "pixel_shader_main",  
  83.                              true));  
  84.             ctrl_gcard = new OmniAlgoVRFilterDetection<OmniGCardConverter, double, IplImage, CvPoint>( conv_gcard,              
  85.                                                                                                       frame );  
  86. #else  
  87.             conv_lu = new OmniConversion<OmniFastLookupTable, int, IplImage, CvPoint>(  
  88.                     new OmniFastLookupTable(min_radius,  
  89.                                             max_radius,  
  90.                                             omni_center_x,  
  91.                                             omni_center_y,  
  92.                                             0.0,  
  93.                                             true ));  
  94.             ctrl_lu = new OmniAlgoVRFilterDetection<OmniFastLookupTable, int, IplImage, CvPoint>( conv_lu,   
  95.                                                                                     frame );  
  96.               
  97. #endif  /* USE_GRAPHIC_CARD */  
  98.   
  99.                                                                                       
  100.   
  101. #ifdef SAVE_PROCESSED_VIDEO  
  102.             // FIXME: change that -1 value to a fourcc value to work with linux  
  103.             avi_writer = cvCreateAVIWriter( PROCESSED_VIDEO_PATH, CV_FOURCC('X''V''I''D') , PROCESSED_VIDEO_FPS,  
  104.                     cvSize(frame->width, frame->height) );  
  105. #endif /* SAVE_PROCESSED_VIDEO */             
  106.               
  107.             initialized = true;  
  108.         }  
  109.           
  110. #ifdef  USE_GRAPHIC_CARD          
  111.         ctrl_gcard->loop_next_frame( frame );  
  112. #else         
  113.         ctrl_lu->loop_next_frame( frame );  
  114. #endif  
  115.           
  116. #ifdef SHOW_FPS_ON_IMAGE  
  117.         now_time = (double) clock ();  
  118.         if (end_time - now_time > DBL_EPSILON){  
  119.             fps++;  
  120.         }  
  121.         else{  
  122.             sprintf(fps_buff, " %d FPS", fps);  
  123.             end_time = (double) clock () + (1 * CLOCKS_PER_SEC);  
  124.             fps = 0;  
  125.         }  
  126.   
  127.         cvPutText( frame, fps_buff , fps_point, &font, CV_RGB(0,255,0) );  
  128.   
  129.         rate++;  
  130. #endif  /* SHOW_FPS_ON_IMAGE */  
  131.           
  132.         cvShowImage( "face_window", frame);  
  133.           
  134. #ifdef SAVE_PROCESSED_VIDEO  
  135.         cvWriteToAVI (avi_writer, frame);  
  136. #endif /* SAVE_PROCESSED_VIDEO */  
  137.         cvWaitKey( WAIT_KEY_VALUE );  
  138.   
  139.     }  
  140.       
  141.     cvReleaseCapture( &capture );  
  142.   
  143. #ifdef SAVE_PROCESSED_VIDEO  
  144.     if (avi_writer != NULL)  
  145.         cvReleaseVideoWriter(&avi_writer);  
  146. #endif /* SAVE_PROCESSED_VIDEO */  
  147.       
  148. }  

学习的目标是成熟!~~~
原文地址:https://www.cnblogs.com/weinyzhou/p/4983366.html