您的位置:首页 > 其它

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

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

项目如图:



程序效果如图:







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

部分源码分析:

[cpp] view
plaincopy

//创建发送和接受流

void MainFrame::OnMenuPreferencesClick( wxCommandEvent& event )

{

if ( m_streamer_thread == NULL ) {

m_streamer_thread = new StreamerCtrlThread( this );

}

if ( m_receiver_thread == NULL ) {

m_receiver_thread = new ReceiverCtrlThread( this );

}

DialogOptions* window = new DialogOptions(this, m_streamer_thread, m_receiver_thread, this,

ID_OPTIONS, _("Preferences..."));

window->Show(true);

}

[cpp] view
plaincopy

//创建发送和接受流

void MainFrame::OnMenuPreferencesClick( wxCommandEvent& event )

{

if ( m_streamer_thread == NULL ) {

m_streamer_thread = new StreamerCtrlThread( this );

}

if ( m_receiver_thread == NULL ) {

m_receiver_thread = new ReceiverCtrlThread( this );

}

DialogOptions* window = new DialogOptions(this, m_streamer_thread, m_receiver_thread, this,

ID_OPTIONS, _("Preferences..."));

window->Show(true);

}

[cpp] view
plaincopy

//关闭 则释放资源

void MainFrame::OnCloseWindow( wxCloseEvent& event )

{

// provide a clean deletion of objects.

if ( m_receiver_thread && m_receiver_thread->isReceiving() ) {

wxMessageDialog dlg1( this,

wxT("Please stop by hand the receiver, then close.") , wxT( "Warning" ), wxOK );

dlg1.ShowModal();

return;

}

if ( m_streamer_thread && m_streamer_thread->isStreaming() ) {

wxMessageDialog dlg1( this,

wxT("Please stop by hand the server streaming, then close."), wxT( "Warning" ), wxOK );

dlg1.ShowModal();

return;

}

destroy_garbage_collector_for_images ();

wxWindow* window = this;

window->Destroy();

event.Skip();

}

[cpp] view
plaincopy

//停止服务

void MainFrame::OnMenuitemActionsStopServerClick( wxCommandEvent& event )

{

if ( m_streamer_thread != NULL ) {

if ( m_streamer_thread->isStreaming() ) {

m_streamer_thread->stopStreaming();

PrintStatusBarMessage( wxT( "Streaming stopped" ), 0 );

// no need to delete the object! Being a thread it will auto-destroy after

// its exiting

// recreate a new ojbect

m_streamer_thread = new StreamerCtrlThread( this );

}

else {

wxMessageDialog dlg1( this, wxT( "Server is not running" ), wxT( "Info" ), wxOK );

dlg1.ShowModal();

delete m_streamer_thread;

m_streamer_thread = new StreamerCtrlThread( this );

}

}

else {

wxMessageDialog dlg1( this, wxT( "Server is not running" ), wxT( "Info" ), wxOK );

dlg1.ShowModal();

}

}

[cpp] view
plaincopy

//停止接收

void MainFrame::OnMenuitemActionsStopReceivingClick( wxCommandEvent& event )

{

if ( m_receiver_thread != NULL ) {

if ( m_receiver_thread->isReceiving() ) {

m_receiver_thread->StopReceiving();

PrintStatusBarMessage( wxT( "Receiving stopped" ), 1 );

}

else {

wxMessageDialog dlg1( this, wxT( "Receiver is not running" ), wxT( "Info" ), wxOK );

dlg1.ShowModal();

delete m_receiver_thread;

m_receiver_thread = new ReceiverCtrlThread( this );

}

}

else {

wxMessageDialog dlg1( this, wxT( "Receiver is not running" ), wxT( "Info" ), wxOK );

dlg1.ShowModal();

}

}

[cpp] view
plaincopy

//接收完毕则释放资源

void MainFrame::OnReceiverCtrlThreadEnd()

{

// provide a stop for the face_detecting/tracking class if it's available

if ( face_detect ) {

if ( gcard_use == true ) {

if ( ctrl_gcard ) {

ctrl_gcard->loop_stop();

delete ctrl_gcard;

ctrl_gcard = NULL;

}

if ( ctrl_vr_gcard ) {

ctrl_vr_gcard->loop_stop();

delete ctrl_vr_gcard;

ctrl_vr_gcard = NULL;

}

}

else {

if ( ctrl_lookup ) {

ctrl_lookup->loop_stop();

delete ctrl_lookup;

ctrl_lookup = NULL;

}

if ( ctrl_vr_lookup ) {

ctrl_vr_lookup->loop_stop();

delete ctrl_vr_lookup;

ctrl_vr_lookup = NULL;

}

}

ctrl_initialized = false;

face_detect = false;

}

// important!: set to null our class, so that we can recreate it when necessary

m_receiver_thread = NULL;

reset_displayed_image_vector();

clear_garbage_collector_for_images();

video_received_window = false;

}

omnistuff测试代码:

[cpp] view
plaincopy

int main(int argc, char**argv ) {

/* ok, hardcode them for now... */

double min_radius = 40;

double max_radius = 220;

double omni_center_x = 326;

double omni_center_y = 250;

OmniAlgoSimpleDetection<OmniGCardConverter, double, IplImage, CvPoint> *ctrl;

OmniConversion<OmniGCardConverter, double, IplImage, CvPoint> *conv;

bool ctrl_initialized = false;

IplImage *frame;

// init capturing

CvCapture* capture = 0;

#ifdef WIN32

char* filename = "..\\..\\data\\videos\\video_test-1-divx5.avi";

#else

char* filename = "../../data/videos/video_test-1-divx5.avi";

#endif

// hardcoding... it ugly but this is a sample test file

const int c_array_length = 2;

const char *c_array[c_array_length];

#ifdef WIN32

// this seems to be the best Haar-cascade combination: it gives the lowest number of false-positive

// Anyway improving the xml's with a good haar learning can rise up the performances.

c_array[0] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_upperbody.xml";

c_array[1] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_frontalface_default.xml";

#else

c_array[0] = "../../omnistuff/data/haarcascades/haarcascade_upperbody.xml";

c_array[1] = "../../omnistuff/data/haarcascades/haarcascade_frontalface_default.xml";

#endif

if ( argc != 2 ) {

printf( "To play a different file read below.\n" );

printf( "usage: %s <avi file>\n", argv[0] );

printf( "Now using %s\n", filename );

}

else {

filename = argv[1];

printf( "Now using %s\n", filename );

}

capture = cvCaptureFromAVI( filename );

while ( 1 ) {

frame = cvQueryFrame( capture );

if( !frame ) {

printf( "Some error occurred or end of video reached\n");

break;

}

if ( !ctrl_initialized ) {

conv = new OmniConversion<OmniGCardConverter, double, IplImage, CvPoint>(

new OmniGCardConverter( min_radius,

max_radius,

omni_center_x,

omni_center_y,

640,

480,

"omnigcardo",

"../../omnistuff/data/shaders/vertex_shader.cg",

"vertex_shader_main",

"../../omnistuff/data/shaders/pixel_shader.cg",

"pixel_shader_main") );

if ( conv->is_initialized () ) {

printf("great, gcard is initialized and ready to use...\n");

ctrl_initialized = true;

}

else {

printf( "some problem occurred: no gcard available...\n");

exit(-1);

}

ctrl = new OmniAlgoSimpleDetection<OmniGCardConverter, double, IplImage, CvPoint>( conv,

frame,

(const char**)c_array,

c_array_length,

FREEZE_FRAME_BOUND,

TRACK_WINDOW_HITRATE);

}

ctrl->loop_next_frame( frame );

cvWaitKey ( WAIT_KEY_VALUE );

}

cvReleaseCapture( &capture );

return 0;

}

omnitest测试代码:

[cpp] view
plaincopy

int main( int argc, char** argv ) {

#ifdef WIN32

char* filename = "..\\..\\data\\videos\\video_test-1-divx5.avi";

#else

char* filename = "../../data/videos/video_test-1-divx5.avi";

#endif

if ( argc != 2 ) {

printf( "To play a different file read below.\n" );

printf( "usage: %s <avi file>\n", argv[0] );

printf( "Now using %s\n", filename );

}

else {

filename = argv[1];

printf( "Now using %s\n", filename );

}

MyTimer timer;

// hardcoding... it ugly but this is a sample test file

const int c_array_length = 2;

const char *c_array[c_array_length];

#ifdef WIN32

// this seems to be the best Haar-cascade combination: it gives the lowest number of false-positive

// Anyway improving the xml's with a good haar learning can rise up the performances.

c_array[0] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_upperbody.xml";

c_array[1] = "..\\..\\omnistuff\\data\\haarcascades\\haarcascade_frontalface_default.xml";

#else

c_array[0] = "../../omnistuff/data/haarcascades/haarcascade_upperbody.xml";

c_array[1] = "../../omnistuff/data/haarcascades/haarcascade_frontalface_default.xml";

#endif

// Our OmniCtrl class.

OmniLoopCtrl *ctrl;

bool ctrl_initialized = false;

// one second of timeout

timer.Start(1000);

IplImage *frame;

// init capturing

CvCapture* capture = 0;

capture = cvCaptureFromAVI( filename );

while ( 1 ) {

frame = cvQueryFrame( capture );

if( !frame ) {

printf( "Some error occurred or end of video reached\n");

break;

}

if ( !ctrl_initialized ) {

ctrl = new OmniLoopCtrl( frame,

1/(double)RADIUS_MAX,

RADIUS_MIN,

RADIUS_MAX,

CENTER_X,

CENTER_Y,

c_array,

c_array_length,

FREEZE_FRAME_BOUND,

TRACK_WINDOW_HITRATE );

ctrl_initialized = true;

}

ctrl->loop_next_frame( frame );

timer.frame_per_second++;

}

cvReleaseCapture( &capture );

timer.Stop();

if ( ctrl_initialized ) {

ctrl->loop_stop();

delete ctrl;

}

return 0;

}

vrfilter_test测试代码:

[cpp] view
plaincopy

int main( int argc, char** argv )

{

//time for fps

double now_time, end_time ;

char fps_buff [20];

CvPoint fps_point = cvPoint(10, 450);

CvFont font;

cvInitFont( &font, CV_FONT_HERSHEY_SIMPLEX, 0.6f, 0.6f, 0.0f, 2, CV_AA);

CvVideoWriter *avi_writer = NULL;

#ifdef USE_GRAPHIC_CARD

OmniConversion<OmniGCardConverter, double, IplImage, CvPoint> *conv_gcard;

OmniAlgoVRFilterDetection<OmniGCardConverter, double, IplImage, CvPoint> *ctrl_gcard;

#else

OmniConversion<OmniFastLookupTable, int, IplImage, CvPoint> *conv_lu;

OmniAlgoVRFilterDetection<OmniFastLookupTable, int, IplImage, CvPoint> *ctrl_lu;

#endif

/* ok, hardcode them for now... */

int min_radius = 55;

int max_radius = 220;

int omni_center_x = 320;

int omni_center_y = 255;

CvCapture* capture = 0;

char *filename = NULL;

cvNamedWindow( "face_window", 1 );

if ( argc != 2 )

filename =

#ifdef WIN32

"..\\..\\data\\videos\\video_test-3-xvid.avi";

#else

"../../data/videos/video_test-3-xvid.avi";

#endif

else

filename = argv[1];

#ifdef SHOW_FPS_ON_IMAGE

int fps = 0;

int rate = 0;

#endif

capture = cvCaptureFromAVI( filename );

printf("Using %s as omnidirectional video...\n", filename);

if( !capture )

{

fprintf(stderr,"Could not initialize capturing...\n");

return -1;

}

now_time = (double) clock ();

end_time = (double) clock () + (1 * CLOCKS_PER_SEC);

sprintf(fps_buff, " %d FPS", fps);

bool initialized = false;

while ( 1 )

{

IplImage* frame = 0;

frame = cvQueryFrame( capture );

if( !frame )

break;

if ( !initialized ) {

#ifdef USE_GRAPHIC_CARD

conv_gcard = new OmniConversion<OmniGCardConverter, double, IplImage, CvPoint>(

new OmniGCardConverter(min_radius,

max_radius,

omni_center_x,

omni_center_y,

640,

480,

"omnigcardo",

"../../omnistuff/data/shaders/vertex_shader.cg",

"vertex_shader_main",

"../../omnistuff/data/shaders/pixel_shader.cg",

"pixel_shader_main",

true));

ctrl_gcard = new OmniAlgoVRFilterDetection<OmniGCardConverter, double, IplImage, CvPoint>( conv_gcard,

frame );

#else

conv_lu = new OmniConversion<OmniFastLookupTable, int, IplImage, CvPoint>(

new OmniFastLookupTable(min_radius,

max_radius,

omni_center_x,

omni_center_y,

0.0,

true ));

ctrl_lu = new OmniAlgoVRFilterDetection<OmniFastLookupTable, int, IplImage, CvPoint>( conv_lu,

frame );

#endif /* USE_GRAPHIC_CARD */

#ifdef SAVE_PROCESSED_VIDEO

// FIXME: change that -1 value to a fourcc value to work with linux

avi_writer = cvCreateAVIWriter( PROCESSED_VIDEO_PATH, CV_FOURCC('X', 'V', 'I', 'D') , PROCESSED_VIDEO_FPS,

cvSize(frame->width, frame->height) );

#endif /* SAVE_PROCESSED_VIDEO */

initialized = true;

}

#ifdef USE_GRAPHIC_CARD

ctrl_gcard->loop_next_frame( frame );

#else

ctrl_lu->loop_next_frame( frame );

#endif

#ifdef SHOW_FPS_ON_IMAGE

now_time = (double) clock ();

if (end_time - now_time > DBL_EPSILON){

fps++;

}

else{

sprintf(fps_buff, " %d FPS", fps);

end_time = (double) clock () + (1 * CLOCKS_PER_SEC);

fps = 0;

}

cvPutText( frame, fps_buff , fps_point, &font, CV_RGB(0,255,0) );

rate++;

#endif /* SHOW_FPS_ON_IMAGE */

cvShowImage( "face_window", frame);

#ifdef SAVE_PROCESSED_VIDEO

cvWriteToAVI (avi_writer, frame);

#endif /* SAVE_PROCESSED_VIDEO */

cvWaitKey( WAIT_KEY_VALUE );

}

cvReleaseCapture( &capture );

#ifdef SAVE_PROCESSED_VIDEO

if (avi_writer != NULL)

cvReleaseVideoWriter(&avi_writer);

#endif /* SAVE_PROCESSED_VIDEO */

}

学习的目标是成熟!~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: