root / trunk / CCV2.0 / src / CCVApp.cpp @ 119
View | Annotate | Download (7.7 KB)
| 1 | /////////////////////////////////////////////////////////////////////////////
|
|---|---|
| 2 | // Name: src/main.cpp
|
| 3 | // Purpose: Provide the entrance of the application
|
| 4 | // Author: Jimbo Zhang
|
| 5 | // Copyright: (c) 2011 NUI Group
|
| 6 | /////////////////////////////////////////////////////////////////////////////
|
| 7 | |
| 8 | /*! \mainpage Introduction
|
| 9 | * |
| 10 | * Community Core Vision, CCV for short (aka tbeta), is a open |
| 11 | * source/cross-platform solution for computer vision and machine sensing. |
| 12 | * It takes an video input stream and outputs tracking data (e.g. coordinates |
| 13 | * and blob size) and events (e.g. finger down, moved and released) that are |
| 14 | * used in building multi-touch applications. CCV can interface with various |
| 15 | * web cameras and video devices as well as connect to various TUIO/OSC/XML |
| 16 | * enabled applications and supports many multi-touch lighting techniques |
| 17 | * including: FTIR, DI, DSI, and LLP with expansion planned for the future |
| 18 | * vision applications (custom modules/filters). |
| 19 | * |
| 20 | * This version of CCV is based on OpenCV, Movid and wxWidgets. |
| 21 | */ |
| 22 | |
| 23 | #include <wx/wx.h> |
| 24 | #include <wx/thread.h> |
| 25 | #include <wx/app.h> |
| 26 | #include <cstdio> |
| 27 | #include "CCVCommon.h" |
| 28 | #include "CCVWorkerEngine.h" |
| 29 | #include "CCVMainFrame.h" |
| 30 | #include "CCVMiniFrame.h" |
| 31 | #include "tinyxml.h" |
| 32 | #include "ofxXmlSettings.h" |
| 33 | |
| 34 | //
|
| 35 | // CCVApp is the class that provides the main application.
|
| 36 | //
|
| 37 | class CCVApp : public wxApp |
| 38 | {
|
| 39 | virtual bool OnInit();
|
| 40 | virtual int OnExit();
|
| 41 | int FilterEvent(wxEvent& event);
|
| 42 | |
| 43 | private:
|
| 44 | bool use_Mainframe;
|
| 45 | CCVMainFrame *mainframe; |
| 46 | CCVMiniFrame *miniframe; |
| 47 | CCVWorkerEngine *movidthread; |
| 48 | CCVGlobalParam *param; |
| 49 | FILE* logFp; |
| 50 | |
| 51 | int LoadConfigXml(CCVGlobalParam *, std::string filename);
|
| 52 | int SetInitPipeline();
|
| 53 | }; |
| 54 | |
| 55 | IMPLEMENT_APP(CCVApp) |
| 56 | |
| 57 | /**
|
| 58 | The entrance of the application. Set mainframe and miniframe. |
| 59 | */ |
| 60 | bool CCVApp::OnInit()
|
| 61 | {
|
| 62 | param = new CCVGlobalParam; |
| 63 | LoadConfigXml(param, "config.xml");
|
| 64 | |
| 65 | param->backgroundsub_enabled = true;
|
| 66 | param->amplify_enabled = true;
|
| 67 | param->highpass_enabled = false;
|
| 68 | param->smooth_enabled = false;
|
| 69 | |
| 70 | movidthread = new CCVWorkerEngine(); |
| 71 | |
| 72 | if (SetInitPipeline()==CCV_SUCCESS) {
|
| 73 | movidthread->procGraph->start(); |
| 74 | } |
| 75 | else {
|
| 76 | wxLogMessage(wxT("ERROR SetInitPipeline()!=CCV_SUCCESS"));
|
| 77 | return false; |
| 78 | } |
| 79 | |
| 80 | if (movidthread->Create() != wxTHREAD_NO_ERROR ) {
|
| 81 | wxLogMessage(wxT("ERROR movidthread->Create() != wxTHREAD_NO_ERROR"));
|
| 82 | return false; |
| 83 | } |
| 84 | if (movidthread->Run() != wxTHREAD_NO_ERROR) {
|
| 85 | wxLogMessage(wxT("ERROR movidthread->Run() != wxTHREAD_NO_ERROR"));
|
| 86 | return false; |
| 87 | } |
| 88 | |
| 89 | use_Mainframe = true;
|
| 90 | |
| 91 | mainframe = new CCVMainFrame(movidthread, param); |
| 92 | if (mainframe==NULL) |
| 93 | return false; |
| 94 | mainframe->Show(use_Mainframe); |
| 95 | |
| 96 | miniframe = new CCVMiniFrame(mainframe); |
| 97 | if (miniframe==NULL) |
| 98 | return false; |
| 99 | miniframe->Show(!use_Mainframe); |
| 100 | |
| 101 | return true; |
| 102 | } |
| 103 | |
| 104 | /**
|
| 105 | Switch between mainframe and miniframe when the spacebar was pressed. |
| 106 | */ |
| 107 | int CCVApp::FilterEvent(wxEvent& event)
|
| 108 | {
|
| 109 | if (event.GetEventType()==wxEVT_KEY_DOWN && ((wxKeyEvent&)event).GetKeyCode()==WXK_SPACE) {
|
| 110 | use_Mainframe = !use_Mainframe; |
| 111 | mainframe->Show(use_Mainframe); |
| 112 | miniframe->Show(!use_Mainframe); |
| 113 | return 0; |
| 114 | } |
| 115 | |
| 116 | return -1; |
| 117 | } |
| 118 | |
| 119 | int CCVApp::OnExit()
|
| 120 | {
|
| 121 | fclose(logFp); |
| 122 | if (movidthread->Pause() != wxTHREAD_NO_ERROR) {
|
| 123 | wxLogMessage(wxT("ERROR movidthread->Pause() != wxTHREAD_NO_ERROR"));
|
| 124 | } |
| 125 | return 0; |
| 126 | } |
| 127 | |
| 128 | int CCVApp::LoadConfigXml(CCVGlobalParam *in_param, std::string filename)
|
| 129 | {
|
| 130 | // Not means CCV2 depends oF.
|
| 131 | // Just use ofxXml, as ofxXml is easier to use than tinyxml.
|
| 132 | ofxXmlSettings XML; |
| 133 | if (! XML.loadFile("config.xml")) |
| 134 | return CCV_ERROR_FILE_CANNOT_FOUND;
|
| 135 | |
| 136 | in_param->initThreshold = XML.getValue("CONFIG:INIT:Threshold", 180); |
| 137 | in_param->initMinBlob = XML.getValue("CONFIG:INIT:MinBlob", 50); |
| 138 | in_param->initMaxBlob = XML.getValue("CONFIG:INIT:MaxBlob", 1000); |
| 139 | in_param->initHighpassBlur = XML.getValue("CONFIG:INIT:HighpassBlur", 100); |
| 140 | in_param->initHighpasSize = XML.getValue("CONFIG:INIT:HighpasSize", 20); |
| 141 | in_param->initAmplify = XML.getValue("CONFIG:INIT:Amplify", 20); |
| 142 | in_param->initSmooth = XML.getValue("CONFIG:INIT:Smooth", 10); |
| 143 | |
| 144 | in_param->videoFileName = XML.getValue("CONFIG:VIDEO:FILENAME", "RearDI.m4v"); |
| 145 | std::string logFileName = XML.getValue("CONFIG:LOG:FILENAME", "ccv2.log"); |
| 146 | logFp = fopen(logFileName.c_str(), "wt");
|
| 147 | in_param->logger = new wxLogStderr(logFp); |
| 148 | wxLog::SetActiveTarget(in_param->logger); |
| 149 | return CCV_SUCCESS;
|
| 150 | } |
| 151 | |
| 152 | int CCVApp::SetInitPipeline()
|
| 153 | {
|
| 154 | // Decide whether to use filters
|
| 155 | std::string bgModule = param->backgroundsub_enabled ? "bgSubtract" : "bgSubtract_dummy"; |
| 156 | std::string ampModule = param->amplify_enabled ? "amplify" : "amplify_dummy"; |
| 157 | std::string hpassModule = param->highpass_enabled ? "highpass" : "highpass_dummy"; |
| 158 | std::string smoothModule = param->smooth_enabled ? "smooth" : "smooth_dummy"; |
| 159 | |
| 160 | // Input Source
|
| 161 | movidthread->procGraph->AddModule("input_source", "Video")->property("filename").set(param->videoFileName); |
| 162 | param->input_source = VIDEO; |
| 163 | |
| 164 | // Background Subtract
|
| 165 | movidthread->procGraph->AddModule("bgSubtract", "BackgroundSubtract"); |
| 166 | movidthread->procGraph->AddModule("bgSubtract_dummy", "DoNothing"); |
| 167 | movidthread->procGraph->ConnectModules("input_source", bgModule);
|
| 168 | |
| 169 | // Amplify
|
| 170 | movidthread->procGraph->AddModule("amplify", "Amplify"); |
| 171 | movidthread->procGraph->AddModule("amplify_dummy", "DoNothing"); |
| 172 | movidthread->procGraph->ConnectModules(bgModule, ampModule); |
| 173 | |
| 174 | // Highpass
|
| 175 | movidthread->procGraph->AddModule("highpass", "Highpass"); |
| 176 | movidthread->procGraph->AddModule("highpass_dummy", "DoNothing"); |
| 177 | movidthread->procGraph->ConnectModules(ampModule, hpassModule); |
| 178 | |
| 179 | // Smooth
|
| 180 | movidthread->procGraph->AddModule("smooth", "Smooth"); |
| 181 | movidthread->procGraph->AddModule("smooth_dummy", "DoNothing"); |
| 182 | movidthread->procGraph->ConnectModules(hpassModule, smoothModule); |
| 183 | |
| 184 | // GrayScale
|
| 185 | movidthread->procGraph->AddModule("grayscale", "GrayScale"); |
| 186 | movidthread->procGraph->ConnectModules(smoothModule, "grayscale");
|
| 187 | |
| 188 | // Threshold
|
| 189 | movidthread->procGraph->AddModule("threshold", "Threshold")->property("threshold").set(param->initThreshold); |
| 190 | movidthread->procGraph->ConnectModules("grayscale", "threshold"); |
| 191 | |
| 192 | // BlobFinder
|
| 193 | movidthread->procGraph->AddModule("blobfinder", "BlobFinder")->property("min_size").set(param->initMinBlob); |
| 194 | movidthread->procGraph->getModuleById("blobfinder")->property("max_size").set(param->initMaxBlob); |
| 195 | movidthread->procGraph->ConnectModules("threshold", "blobfinder"); |
| 196 | |
| 197 | // In & Out Monitors
|
| 198 | movidthread->procGraph->AddModule("output_leftviewer", "Stream", true); |
| 199 | movidthread->procGraph->ConnectModules("input_source", "output_leftviewer"); |
| 200 | movidthread->procGraph->AddModule("output_rightviewer", "Stream", true); |
| 201 | movidthread->procGraph->ConnectModules("threshold", "output_rightviewer"); |
| 202 | |
| 203 | // Filter Monitors
|
| 204 | movidthread->procGraph->AddModule("output_background", "Stream", true); |
| 205 | movidthread->procGraph->ConnectModules(bgModule, "output_background");
|
| 206 | movidthread->procGraph->AddModule("output_amplify", "Stream", true); |
| 207 | movidthread->procGraph->ConnectModules(ampModule, "output_amplify");
|
| 208 | movidthread->procGraph->AddModule("output_highpass", "Stream", true); |
| 209 | movidthread->procGraph->ConnectModules(hpassModule, "output_highpass");
|
| 210 | movidthread->procGraph->AddModule("output_smooth", "Stream", true); |
| 211 | movidthread->procGraph->ConnectModules(smoothModule, "output_smooth");
|
| 212 | |
| 213 | return CCV_SUCCESS;
|
| 214 | } |
