ACT-CV - Machine Vision for Cognitive Modeling
server-main.cpp
Go to the documentation of this file.
1 // -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; coding: iso-8859-1; -*-
2 
3 /*
4 ACT-CV - Machine Vision for Cognitive Modeling
5 Copyright (c) 2008 Marc Halbruegge
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
22 
27 #include <map>
28 #include <thread>
29 
30 // MH 20110313 TODO check OS X compability
31 #ifdef _WINDOWS
32 #define DLLFUNC __declspec(dllexport)
33 #else
34 #define DLLFUNC
35 #endif
36 
37 #include <vision/FrameSource.h>
38 #include <vision/QtFrameSource.h>
42 #include <Robot.h>
43 
44 #include <Threads/Condition.h>
46 
47 #include <tests/TestFrameSource.h>
48 
49 #include <FrameLoop.h>
50 
51 extern "C" {
52 #include "ACT-CV.i"
53 }
54 
55 #include "ResultHolder.h"
56 
57 using namespace std;
58 using namespace mhthreads;
59 
60 // --------------------------------------------------------------------
61 // globals
62 
73 Robot *robot = nullptr;
75 QtFrameSource *qt = nullptr;
76 
77 
80 
87 
92 
93 
100 
101 
106 
107 
110 
112 bool exitFlag=false;
114 std::mutex threadMutex;
115 
116 thread *bgThread = nullptr;
117 
122 struct Job {
123  void (*nullary_fn)();
124  void (*unary_fn)(int);
125  int val;
126 
128 
129  Job() : nullary_fn(0), unary_fn(0), val(0), completed(0) {}
130  Job(void (*nfn)()) : nullary_fn(nfn), unary_fn(0), val(0), completed(0) {}
131  Job(void (*ufn)(int), int v) : nullary_fn(0), unary_fn(ufn), val(v), completed(0) {}
132  Job(void (*nfn)(),mhthreads::Condition *c)
133  : nullary_fn(nfn), unary_fn(0), val(0), completed(c) {}
134  Job(void (*ufn)(int), int v, mhthreads::Condition *c)
135  : nullary_fn(0), unary_fn(ufn), val(v), completed(c) {}
136 };
139 
141  lock_guard<mutex> lock(threadMutex);
142  frameLoop = new FrameLoopImpl();
143  attLocObs = new AttendedLocObs();
144  frameLoop->AddObserver(&*attLocObs);
145 }
146 
148  lock_guard<mutex> lock(threadMutex);
149  frameLoop = nullptr;
150  attLocObs = nullptr;
151  lineObs = nullptr;
152  matchObs = nullptr;
153  textObs = nullptr;
154 }
155 
156 void SelectSourceInternal(int vidSource) {
157  lock_guard<mutex> lock(threadMutex);
158 
159  video_source vs = static_cast<video_source>(vidSource);
160 
161  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
162  switch(vs) {
163  case s_robot:
164  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
165 #if 1
167 #else
168  if (robot==nullptr) {
169 #if 1
170  robot = new Robot();
171  RobotFrameSource *robotFS = new RobotFrameSource(robot);
172  robotFS->SetSize(0,50,
173  robot->GetScreenWidth()/2-1,
174  robot->GetScreenHeight()/2-1);
175  frameSource=robotFS;
176 #else
177  // test code
178  JVM *jvm = new JVM();
179  delete jvm;
180  frameSource = new TestFrameSource(cvSize(400,300));
181 #endif
182  }
183 #endif
184  break;
185  case s_cam:
186  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
188  break;
189  case s_file:
190  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
192  break;
193  case s_web:
194  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
196  qt = static_cast<QtFrameSource*>(&*frameSource);
197  break;
198  case s_singleImage:
199  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
201  break;
202  case s_test:
203  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
204  frameSource = new TestFrameSource(cvSize(400,300));
205  break;
206  }
207 
208  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
209 }
210 
211 extern "C" DLLFUNC
213  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
214 #if 0
216 #else
217  mhthreads::Condition waitForCompletion;
218  jobs.push(Job(&SelectSourceInternal, vs, &waitForCompletion));
219  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
220  waitForCompletion.Wait(); // Race Condition here :(
221 #endif
222  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
223 }
224 
225 extern "C" DLLFUNC
226 void SelectFileBasedSource(const char *filename, video_source vs)
227 {
228  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
229  // copy name to static variable
230  frameSourceFileName = new GCString(filename);
231  mhthreads::Condition waitForCompletion;
232  jobs.push(Job(&SelectSourceInternal, vs, &waitForCompletion));
233  waitForCompletion.Wait(); // Race Condition here :(
234 
235  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
236 }
237 
238 
240  lock_guard<mutex> lock(threadMutex);
241 
242  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
243  if(&*frameSource == qt) {
244  qt = nullptr;
245  }
246  frameSource = nullptr;
247 #if 0
248  frameLoop = nullptr;
249  lineObs = nullptr;
250  attLocObs = nullptr;
251  // Problem: AttachCurrentThread aufgerufen!
252  if (robot) {
253  delete robot;
254  robot=nullptr;
255  }
256 #endif
257  // highgui ein wenig laufen lassen
258  cvWaitKey(50);
259  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
260 }
261 
262 extern "C" DLLFUNC
264  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
265  mhthreads::Condition waitForCompletion;
266  jobs.push(Job(&ReleaseSourceInternal, &waitForCompletion));
267  waitForCompletion.Wait(); // Race Condition here :(
268  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
269 }
270 
271 
273 static void BGFunc() {
274 
276 
277  for (;;) {
278 
279  {
280  lock_guard<mutex> lock(threadMutex);
281  if (exitFlag) {
282  break;
283  }
284  }
285 
286  while (!jobs.empty()) {
287  Job job=jobs.pop();
288  if (job.nullary_fn) (* job.nullary_fn)();
289  if (job.unary_fn) (* job.unary_fn)(job.val);
290 
291  if (job.completed) job.completed->Signal();
292  }
293 
294 
295  if(frameSource && (lineObs || textObs || matchObs)) {
296  lock_guard<mutex> lock(threadMutex);
297  if (frameSource) frameLoop->SingleFrame(&*frameSource);
298  }
299  }
300 
302 }
303 
306 extern "C" DLLFUNC
307 void ActCvInit() {
308  lock_guard<mutex> lock(threadMutex);
309 
310  if(bgThread != nullptr) {
311  MHDBGMSG(__FILE__,__LINE__,"background thread is already running");
312  return;
313  }
314 
315  exitFlag=false;
316  bgThread = new thread(BGFunc);
317 }
318 
319 extern "C" DLLFUNC
321  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
322 
323  try {
324  frameLoop->WaitForNextFrame();
325  } catch (...) {
326  // no new frame
327  }
328 }
329 
330 extern "C" DLLFUNC
331 void ActCvDeInit() {
332 
333  {
334  lock_guard<mutex> lock(threadMutex);
335  if(bgThread == nullptr || !bgThread->joinable()) {
336  return;
337  }
338  exitFlag=true;
339  }
340 
341  bgThread->join();
342  delete bgThread;
343 
344  bgThread = nullptr;
345 }
346 
347 void AddRecognitionInternal(int cvAlgo) {
348  cv_algorithm a = static_cast<cv_algorithm>(cvAlgo);
349 
350  lock_guard<mutex> lock(threadMutex);
351 
352  switch (a) {
353  case a_match:
354  if (&*matchDefFileName == 0) throw runtime_error("Match definition filename not set");
355  if (&*matchObs==nullptr) matchObs = new MatchObs(matchDefFileName->GetString());
356  frameLoop->AddObserver(&*matchObs);
357  frameLoop->AddObserver(new FrameObsWindow("input video"));
358  break;
359  case a_text:
360  if (&*textObs==nullptr) textObs = new TextObs();
361  frameLoop->AddObserver(&*textObs);
362  break;
363  case a_oflow:
364  frameLoop->AddObserver(new OFlowObs());
365  break;
366  case a_lines:
367  if (&*lineObs==nullptr) lineObs = new LineObs();
368  frameLoop->AddObserver(&*lineObs);
369  //lineObs = &*(frameLoop->FindObserver(lineObs->GetName()));
370  break;
371  }
372 }
373 
374 extern "C" DLLFUNC
376  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
377 #if 0
379 #else
380  mhthreads::Condition waitForCompletion;
381  jobs.push(Job(&AddRecognitionInternal, a, &waitForCompletion));
382  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
383  waitForCompletion.Wait(); // Race Condition here :(
384 #endif
385  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
386 }
387 
388 extern "C" DLLFUNC
389 void SetMatchDefFile(const char *s) {
390  matchDefFileName = new GCString(s);
391 }
392 
393 
395 extern "C" DLLFUNC
397 }
398 
399 extern "C" DLLFUNC
400 void UpdateAttendedLoc(int x, int y) {
401 #if 1
402  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
403  attLocObs->UpdateAttendedLoc(x,y);
404  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
405 #endif
406 }
407 
408 
409 extern "C" DLLFUNC
410 void MoveMouseTo(int x, int y) {
411  if(qt) {
412  qt->SetMousePos(x,y);
413  }
414  attLocObs->UpdateMousePos(x,y);
415 }
416 
417 
418 extern "C" DLLFUNC
419 void MouseClick(int button) {
420  if(qt) {
421  qt->DoClick(button);
422  }
423 }
424 
425 extern "C" DLLFUNC
426 void PressKey(int key) {
427  if(qt) {
428  qt->DoPressKey(key);
429  }
430 }
431 
432 // - line grabbing --------------------------------------------------
433 extern "C" DLLFUNC
435  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
436  if (&*lineObs == nullptr) {
437  MHDBGMSG(__FILE__,__LINE__,"no line observer");
438  return 0;
439  }
440  if (&*lineResult == nullptr) {
442  }
443 
444  return lineResult->FindFirst();
445 }
446 
447 extern "C" DLLFUNC
448 int FindNextLine(int handle, struct Line *line) {
449  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
450  return lineResult->FindNext(handle, line);
451 }
452 
453 extern "C" DLLFUNC
454 void LineFindFinish(int handle) {
455  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
456  lineResult->FindFinish(handle);
457  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
458 }
459 
460  // - matching ------------------------------------------------------
461 
462 extern "C" DLLFUNC
464  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
465  if (&*matchObs == nullptr) return 0;
466  if (&*matchResult == nullptr) {
468  }
469 
470  return matchResult->FindFirst();
471 }
472 
473 extern "C" DLLFUNC
474 int FindNextMatch(int handle, struct ObjectPosition *pos) {
475  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
476  return matchResult->FindNext(handle, pos);
477 }
478 
479 extern "C" DLLFUNC
480 void MatchFindFinish(int handle) {
481  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
482  matchResult->FindFinish(handle);
483  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
484 }
485 
486 
487 // - textual features ------------------------------------------------------
488 
489 extern "C" DLLFUNC
491  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
492  if (&*textObs == nullptr) return 0;
493  if (&*textResult == nullptr) {
495  }
496 
497  return textResult->FindFirst();
498 }
499 
500 extern "C" DLLFUNC
501 int FindNextText(int handle, struct ObjectPosition *pos) {
502  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
503  return textResult->FindNext(handle, pos);
504 }
505 
506 extern "C" DLLFUNC
507 void TextFindFinish(int handle) {
508  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
509  textResult->FindFinish(handle);
510  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
511 }
512 
513 // usw.
514 
515 


ACT-CV - Machine Vision for Cognitive Modeling
© 2015 Marc Halbruegge (actcvlibrary@googlemail.com)