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
}