appkit  1.5.1
RoadNarrows Robotics Application Kit
State.orig.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Application Tool Kit
4 //
5 // Library: librnr_appkit
6 //
7 // File: State.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2013-02-18 12:42:09 -0700 (Mon, 18 Feb 2013) $
12  * $Rev: 2691 $
13  *
14  * \brief State base class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  * \author Daniel Packard (daniel@roadnarrows.com)
18  *
19  * \par Copyright
20  * \h_copy 2012-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26 // Permission is hereby granted, without written agreement and without
27 // license or royalty fees, to use, copy, modify, and distribute this
28 // software and its documentation for any purpose, provided that
29 // (1) The above copyright notice and the following two paragraphs
30 // appear in all copies of the source code and (2) redistributions
31 // including binaries reproduces these notices in the supporting
32 // documentation. Substantial modifications to this software may be
33 // copyrighted by their authors and need not follow the licensing terms
34 // described here, provided that the new terms are clearly indicated in
35 // all files where they apply.
36 //
37 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS, EMPLOYEES or
38 // CONTRACTORS OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO
39 // ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
40 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
41 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
42 // THE POSSIBILITY OF SUCH DAMAGE.
43 //
44 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
45 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
46 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
47 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
48 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
49  * @EulaEnd@
50  */
51 //
52 ////////////////////////////////////////////////////////////////////////////////
53 
54 #include <stdio.h>
55 #include <stdarg.h>
56 #include <libgen.h>
57 
58 #include <vector>
59 
60 #include "rnr/rnrconfig.h"
61 #include "rnr/log.h"
62 
63 #include "opencv/cv.h"
64 #include "opencv/highgui.h"
65 
66 #include "WM/WM.h"
67 #include "WM/WMCamera.h"
68 #include "WM/WMWin.h"
69 #include "WM/WMLookFeel.h"
70 #include "WM/WMSession.h"
71 #include "WM/WMState.h"
72 
73 
74 using namespace std;
75 using namespace WM;
76 using namespace WMWin;
77 
78 
79 //------------------------------------------------------------------------------
80 // WMState Class
81 //------------------------------------------------------------------------------
82 
83 /*!
84  * \brief Default intialization constructor.
85  */
86 WMState::WMState(WMSession &session, int nInitAction)
87 {
88  m_pWin = session.m_pWin;
89  m_pMenu = NULL;
90  m_nInitAction = nInitAction;
91  m_nCurAction = WMUIActionNone;
92  m_bHardBttnEnable = true;
93  m_bFatal = false;
94  m_bModified = false;
95 }
96 
97 /*!
98  * \brief Default destructor.
99  */
100 WMState::~WMState()
101 {
102  destroyInterface();
103 }
104 
105  /*!
106  * \brief Get the next input action into this state.
107  *
108  * Actions: Soft button push.
109  *
110  * The retrieved next action becomes the current action.
111  *
112  * \param session Session data.
113  *
114  * \return Next action.
115  */
116 int WMState::getNextAction(WMSession &session, int nTimeoutMs)
117 {
118  session.m_pWin->WaitEvent(nTimeoutMs);
119 
120  // user action
121  if( m_pMenu != NULL )
122  {
123  m_nCurAction = m_pMenu->GetCurrentAction();
124  m_pMenu->SetCurrentAction(WMUIActionNone);
125  }
126  else
127  {
128  m_nCurAction = WMUIActionNone;
129  }
130  return m_nCurAction;
131 }
132 
133 void WMState::buildInterface(WMSession &session)
134 {
135  // one-time initialization of button menu
136  initButtonMenu();
137 
138  // bind menu to window and set initial action
139  if( m_pMenu != NULL )
140  {
141  m_pMenu->Bind(session.m_pWin);
142  m_nCurAction = m_pMenu->SetCurrentAction(m_nInitAction);
143  }
144 
145  // page identifier
146  session.m_pWin->ShowPageId(session.GetPageNum());
147 
148  // enable/disable/toggle menu button states
149  setMenuStates(session);
150 
151  // set local state context in session
152  session.SetContext(this);
153 }
154 
155 void WMState::destroyInterface()
156 {
157  if( m_pMenu != NULL )
158  {
159  m_pMenu->Unbind();
160  m_pMenu = NULL;
161  }
162 
163  // remove all widgets from workspace
164  m_pWin->WorkspaceRemoveAll();
165 }
166 
167 /*!
168  * \brief Test if hard button is pushed.
169  *
170  * \param session Session data.
171  *
172  * \return Returns true or false.
173  */
174 bool WMState::isHardButtonPushed(WMSession &session)
175 {
176 #ifdef WZCSB
177  uint_t key = session.m_pWin->GetLastKeyPress() & 0x00ff;
178  LOGDIAG4("Key 0x%x pressed. Camera key=0x%x.", key, WMHardButtonCtlKey);
179  return key == WMHardButtonCtlKey ? true: false;
180 #elif defined ARCH_overo
181  return WMHardButtonCtlGetState();
182 #else
183  uint_t key = session.m_pWin->GetLastKeyPress() & 0x00ff;
184  LOGDIAG4("Key 0x%x pressed. Camera key=0x%x.", key, WMHardButtonCtlKey);
185  return key == (uint_t)'c' ? true: false; // click
186 #endif // ARCH_OVERO
187 }
188 
189 
190 //------------------------------------------------------------------------------
191 // WMStateImage Class
192 //------------------------------------------------------------------------------
193 
194 /*!
195  * \brief Default intialization constructor.
196  */
197 WMStateImage::WMStateImage(WMSession &session,
198  const CvSize &sizeDisplay,
199  const CvSize &sizeIoI,
200  int nInitAction) :
201  WMState(session, nInitAction)
202 {
203  m_pImgIoI = NULL;
204  m_pImgShadow = NULL;
205  m_pImgMarked = NULL;
206  m_pImgDisplay = NULL;
207  m_sizeDisplay = sizeDisplay;
208  m_sizeIoI = sizeIoI;
209  m_pTransIoI = NULL;
210  m_pTransShadow = NULL;
211  m_bIoICanZoomIn = true;
212  m_bIoICanZoomOut = false;
213  m_bIoIIsPanning = false;
214  m_bShadowChanged = false;
215 }
216 
217 /*!
218  * \brief Default destructor.
219  */
220 WMStateImage::~WMStateImage()
221 {
222  destroyInterface();
223 }
224 
225 /*!
226  * \brief Get the next input action into this state.
227  *
228  * Actions: Soft button push.
229  * Actions: Mouse-over-image click and drag events.
230  *
231  * The retrieved next action becomes the current action.
232  *
233  * \param session Session data.
234  *
235  * \return Next action.
236  */
237 int WMStateImage::getNextAction(WMSession &session, int nTimeoutMs)
238 {
239  session.m_pWin->WaitEvent(nTimeoutMs);
240 
241  if( m_pMenu == NULL )
242  {
243  m_nCurAction = WMUIActionNone;
244  }
245  else
246  {
247  if( (m_nCurAction = m_pMenu->GetCurrentAction()) == WMUIActionNone )
248  {
249  m_nCurAction = m_mouse.GetCurrentAction();
250  }
251  m_pMenu->SetCurrentAction(WMUIActionNone);
252  m_mouse.SetCurrentAction(WMUIActionNone);
253  }
254  return m_nCurAction;
255 }
256 
257 void WMStateImage::buildInterface(WMSession &session)
258 {
259  // build base
260  WMState::buildInterface(session);
261 
262  // workspace is an opencv image
263  session.m_pWin->WorkspaceSetAsCvImage();
264 
265  // bind mouse to window workspace
266  m_mouse.Bind(session.m_pWin);
267 
268  // no current image of interest
269  m_pImgIoI = NULL;
270 
271  // shadow (low-res) image
272  m_pImgShadow = cvCreateImage(m_sizeDisplay, IPL_DEPTH_8U, 3);
273 
274  // image displayed to user
275  m_pImgDisplay = cvCreateImage(m_sizeDisplay, IPL_DEPTH_8U, 3);
276 
277  // clear display image
278  cvSet(m_pImgDisplay, GuiRgbImageBg);
279 
280  // show blank image
281  session.m_pWin->ShowCvImage(m_pImgDisplay);
282 
283  // no marked up image
284  m_pImgMarked = NULL;
285 
286  // image of interest default region of interest
287  m_rectIoIRoI = cvRect(0, 0, m_sizeIoI.width, m_sizeIoI.height);
288  m_bShadowChanged = true;
289 
290  // displayed image of interest window transformation object
291  m_pTransIoI = new WMWinIoI(m_sizeIoI, m_sizeDisplay,
292  WMImgTransRot, WMImgTransAlign, WMImgTransCrop);
293 
294  // displayed shadow window transformation object
295  m_pTransShadow = new WMWinIoI(m_sizeDisplay, m_sizeDisplay,
296  WMImgTransRot, WMImgTransAlign, WMImgTransCrop);
297 }
298 
299 void WMStateImage::destroyInterface()
300 {
301  m_mouse.Unbind();
302 
303  if( m_pImgShadow != NULL )
304  {
305  cvReleaseImage(&m_pImgShadow); // shadow (low-res) IoI
306  m_pImgShadow = NULL;
307  }
308 
309  if( m_pImgDisplay != NULL )
310  {
311  cvReleaseImage(&m_pImgDisplay); // release displayed image
312  m_pImgDisplay = NULL;
313  }
314 
315  if( m_pTransIoI != NULL )
316  {
317  delete m_pTransIoI;
318  m_pTransIoI = NULL;
319  }
320 
321  if( m_pTransShadow != NULL )
322  {
323  delete m_pTransShadow;
324  m_pTransShadow = NULL;
325  }
326 }
327 
328 /*!
329  * \brief Reset image view to defaults.
330  *
331  * All zoom and pan settings are set to normal.
332  *
333  * \param session Session data.
334  */
335 void WMStateImage::resetView(WMSession &session)
336 {
337  // image of interest default region of interest
338  m_rectIoIRoI = cvRect(0, 0, m_sizeIoI.width, m_sizeIoI.height);
339  m_bShadowChanged = true;
340 
341  // edit logic
342  m_bIoICanZoomIn = true;
343  m_bIoICanZoomOut = false;
344  m_bIoIIsPanning = false;
345 
346  // image tranformation parameters
347  m_pTransIoI->SetTransParams(m_sizeIoI,
348  m_rectIoIRoI,
349  m_sizeDisplay,
350  WMImgTransRot,
351  WMImgTransAlign,
352  WMImgTransCrop);
353 }
354 
355 /*!
356  * \brief Show pan region of interest
357  */
358 void WMStateImage::markupPanImg(WMSession &session)
359 {
360  CvRect shadowROI = mapRect(m_rectIoIRoI);
361  CvScalar brighter = cvScalar(80);
362 
363  cvSetImageROI(m_pImgMarked, shadowROI);
364  cvAddS(m_pImgMarked, brighter, m_pImgMarked);
365  cvResetImageROI(m_pImgMarked);
366 }
367 
368 /*!
369  * \brief Show transformed marked up image to display.
370  *
371  * Calls virtual function markupImg() to perform task
372  * specific markups.
373  *
374  * \param session Session data.
375  */
376 void WMStateImage::showMarkupImg(WMSession &session)
377 {
378  // if region of interest changed, copy new shadow image
379  if( m_bShadowChanged )
380  {
381  LOGDIAG3("Updating shadow image.");
382  if(m_bIoIIsPanning)
383  {
384  cvResize(m_pImgIoI, m_pImgShadow);
385  }
386  else
387  {
388  cvSetImageROI(m_pImgIoI, m_rectIoIRoI);
389  cvResize(m_pImgIoI, m_pImgShadow);
390  cvResetImageROI(m_pImgIoI);
391  }
392 
393  m_bShadowChanged = false;
394  }
395 
396  cvCopy(m_pImgShadow, m_pImgDisplay);
397  m_pImgMarked = m_pImgDisplay;
398 
399  // mark up
400  markupImg(session);
401 
402  if (m_bIoIIsPanning)
403  {
404  markupPanImg(session);
405  }
406 
407  // show
408  // DHP
409  // showImg(session, m_pImgMarked);
410  session.m_pWin->ShowCvImage(m_pImgDisplay);
411 }
412 
413 /*!
414  * \brief Show transformed image on display.
415  *
416  * \param session Session data.
417  * \param pImg Image.
418  */
419 void WMStateImage::showImg(WMSession &session, IplImage *pImg)
420 {
421  // clear display image
422  cvSet(m_pImgDisplay, GuiRgbImageBg);
423 
424  // transform and place captured frame on display image
425  if( pImg != NULL )
426  {
427  // m_pTransIoI->WMWinIoITrans(pImg, m_pImgDisplay);
428  LOGDIAG4("Resolution of displayed image: %d, %d",
429  pImg->width, pImg->height);
430  m_pTransShadow->WMWinIoITrans(pImg, m_pImgDisplay);
431  }
432 
433  // show image
434  session.m_pWin->ShowCvImage(m_pImgDisplay);
435 }
436 
437 /*
438  * \brief Translate image points from high-res to shadow image
439  *
440  * Transformation utility function.
441  *
442  * \param CvPoint& ptHiRes
443  */
444 CvPoint WMStateImage::mapPt(CvPoint& ptHiRes)
445 {
446  double fScale;
447  CvPoint ptShadow; ///< point in shadow image coordinates
448 
449  // subtract rectIoIRoI corner to get coords in rectIoIRoI
450  ptShadow.x = ptHiRes.x - m_rectIoIRoI.x;
451  ptShadow.y = ptHiRes.y - m_rectIoIRoI.y;
452 
453  // find scale from rect coords to shadow res
454  fScale = (1.0 * (double)m_sizeDisplay.width) / (double)m_rectIoIRoI.width;
455 
456  ptShadow.x = (int)(fScale*ptShadow.x);
457  ptShadow.y = (int)(fScale*ptShadow.y);
458 
459  return ptShadow;
460 }
461 
462 /*
463  * \brief Translate image points from high-res to panning shadow image
464  *
465  * Transformation utility function.
466  *
467  * \param CvPoint& ptHiRes
468  */
469 CvPoint WMStateImage::mapPtPan(CvPoint& ptHiRes)
470 {
471  double fScale ;
472  CvPoint ptShadow; ///< point in shadow image coordinates
473 
474  // find scale from rect coords to shadow res
475  fScale = (1.0 * m_sizeDisplay.width) / m_sizeIoI.width;
476 
477  ptShadow.x = (int)(fScale*ptHiRes.x);
478  ptShadow.y = (int)(fScale*ptHiRes.y);
479 
480  return ptShadow;
481 }
482 
483 /*
484  * \brief Translate CvRect from high-res to shadow image
485  *
486  * Transformation utility function.
487  *
488  * \param CvRect& rectHiRes
489  */
490 CvRect WMStateImage::mapRect(CvRect& rectHiRes)
491 {
492  double fScale;
493  CvRect rectShadow; ///< point in shadow image coordinates
494 
495  fScale = (1.0 * m_sizeDisplay.width) / m_sizeIoI.width;
496 
497  rectShadow.x = (int)(rectHiRes.x*fScale);
498  rectShadow.y = (int)(rectHiRes.y*fScale);
499  rectShadow.width = (int)(rectHiRes.width*fScale);
500  rectShadow.height = (int)(rectHiRes.height*fScale);
501 
502  return rectShadow;
503 }
504 
505 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
506 // State Trasition Functions
507 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
508 
509 /*!
510  * \brief Zoom in to the current marked up image.
511  *
512  * State transition function.
513  *
514  * \param session Session data.
515  */
516 void WMStateImage::transZoomIn(WMSession &session)
517 {
518  CvSize sizeZoom; ///< working zoom size
519  int x, y; ///< working coordinates
520 
521  if( !m_bIoICanZoomIn )
522  {
523  return;
524  }
525 
526  sizeZoom = ar43width((int)(m_rectIoIRoI.width * 0.9));
527 
528  if( (sizeZoom.width <= m_sizeDisplay.width) &&
529  (sizeZoom.height <= m_sizeDisplay.height) )
530  {
531  sizeZoom = ar43width(m_sizeDisplay);
532  m_bIoICanZoomIn = false;
533  }
534 
535  // x = (m_sizeIoI.width - sizeZoom.width) / 2;
536  // y = (m_sizeIoI.height - sizeZoom.height) / 2;
537 
538  x = m_rectIoIRoI.x + (m_rectIoIRoI.width / 2) - (sizeZoom.width /2);
539  y = m_rectIoIRoI.y + (m_rectIoIRoI.height/ 2) - (sizeZoom.height/2);
540 
541  m_rectIoIRoI = cvRect(x, y, sizeZoom.width, sizeZoom.height);
542  m_bShadowChanged = true;
543 
544  if ( !m_bIoIIsPanning )
545  {
546  m_pTransIoI->SetTransParams(m_sizeIoI,
547  m_rectIoIRoI,
548  m_sizeDisplay,
549  WMImgTransRot,
550  WMImgTransAlign,
551  WMImgTransCrop);
552  }
553 
554  showMarkupImg(session);
555 
556  m_bIoICanZoomOut = true;
557 
558  setModifiedState(true);
559 }
560 
561 /*!
562  * \brief Zoom out of the current marked up image.
563  *
564  * State transition function.
565  *
566  * \param session Session data.
567  */
568 void WMStateImage::transZoomOut(WMSession &session)
569 {
570  CvSize sizeZoom; ///< working zoom size
571  int x, y; ///< working coordinates
572 
573  if( !m_bIoICanZoomOut )
574  {
575  return;
576  }
577 
578  sizeZoom = ar43width((int)(m_rectIoIRoI.width * 1.1));
579 
580  if( (sizeZoom.width >= m_sizeIoI.width) ||
581  (sizeZoom.height >= m_sizeIoI.height) )
582  {
583  sizeZoom = m_sizeIoI;
584  m_bIoICanZoomOut = false;
585  }
586 
587  // RoI remains centered at current location
588  x = m_rectIoIRoI.x + (m_rectIoIRoI.width / 2) - (sizeZoom.width /2);
589  y = m_rectIoIRoI.y + (m_rectIoIRoI.height/ 2) - (sizeZoom.height/2);
590 
591  // UNLESS RoI goes outside bounds of image
592  if( x + sizeZoom.width > m_sizeIoI.width )
593  {
594  x = (m_sizeIoI.width - sizeZoom.width);
595  }
596  else if ( x < 0 )
597  {
598  x = 0;
599  }
600 
601  if( y + sizeZoom.height > m_sizeIoI.height )
602  {
603  y = (m_sizeIoI.height - sizeZoom.height);
604  }
605  else if ( y < 0 )
606  {
607  y = 0;
608  }
609 
610  m_rectIoIRoI = cvRect(x, y, sizeZoom.width, sizeZoom.height);
611  m_bShadowChanged = true;
612 
613  if ( !m_bIoIIsPanning )
614  {
615  m_pTransIoI->SetTransParams(m_sizeIoI,
616  m_rectIoIRoI,
617  m_sizeDisplay,
618  WMImgTransRot,
619  WMImgTransAlign,
620  WMImgTransCrop);
621  }
622 
623  showMarkupImg(session);
624 
625  m_bIoICanZoomIn = true;
626 
627  setModifiedState(true);
628 }
629 
630 /*!
631  * \brief Pan marked up image up/down and left/right.
632  *
633  * State transition function.
634  *
635  * \param session Session data.
636  */
637 void WMStateImage::transPan(WMSession &session)
638 {
639  CvPoint ptRaw; // this raw point position
640  CvPoint ptImg; // this transformed point position
641  int nAction; // current mouse action
642  int x, y; // working coordinates
643  CvRect shadowRoI; // RoI in shadow image
644 
645  ptRaw = m_mouse.GetMousePoint();
646 
647  // out of scope
648  if( (ptRaw.x < 0) || (ptRaw.x >= m_sizeDisplay.width) ||
649  (ptRaw.y < 0) || (ptRaw.y >= m_sizeDisplay.height) )
650  {
651  //DHP: log this
652  LOGDIAG4("Mouse pt out of scope for panning.");
653 
654  //DHP: show panning image for first pass through
655  showMarkupImg(session);
656  return;
657  }
658 
659  ptImg = m_pTransIoI->WMWinIoIMapPoint(ptRaw);
660  // ptImg = m_pTransShadow->WMWinIoIMapPoint(ptRaw);
661 
662  //cerr << "DBG: (" << ptRaw.x << "," << ptRaw.y << ") "
663  // << "==> (" << ptImg.x << "," << ptImg.y << ")" << endl;
664 
665  nAction = getCurAction();
666 
667  if( nAction == WMUIActionDragStart )
668  {
669  LOGDIAG4("Drag Start");
670  m_ptPanRaw = ptRaw;
671  m_ptPan = ptImg;
672  return;
673  }
674  else if( nAction == WMUIActionDragEnd )
675  {
676  LOGDIAG4("Drag End.");
677  return;
678  }
679 
680  // Ignore hover _near_ same spot
681  if(( abs(m_ptPanRaw.x - ptRaw.x) < 10 ) && (abs(m_ptPanRaw.y - ptRaw.y) < 10))
682  {
683  return;
684  }
685 
686  x = m_rectIoIRoI.x - m_ptPan.x + ptImg.x;
687  y = m_rectIoIRoI.y - m_ptPan.y + ptImg.y;
688 
689  if( x < 0 )
690  {
691  x = 0;
692  }
693  else if( x + m_rectIoIRoI.width > m_sizeIoI.width )
694  {
695  x = m_sizeIoI.width - m_rectIoIRoI.width;
696  }
697 
698  if( y < 0 )
699  {
700  y = 0;
701  }
702  else if( y + m_rectIoIRoI.height > m_sizeIoI.height )
703  {
704  y = m_sizeIoI.height - m_rectIoIRoI.height;
705  }
706 
707  m_rectIoIRoI.x = x;
708  m_rectIoIRoI.y = y;
709 
710  // while panning, set temporary RoI to entire high-res image
711  CvRect tmpRoI = cvRect(0,0, m_sizeIoI.width, m_sizeIoI.height);
712  m_pTransIoI->SetTransParams(m_sizeIoI,
713  tmpRoI,
714  m_sizeDisplay,
715  WMImgTransRot,
716  WMImgTransAlign,
717  WMImgTransCrop);
718 
719  m_ptPanRaw = ptRaw;
720  m_ptPan = ptImg;
721 
722  showMarkupImg(session);
723 
724  setModifiedState(true);
725 }
726 
727 
728 //------------------------------------------------------------------------------
729 // WMStateCvCamera Class
730 //------------------------------------------------------------------------------
731 
732 /*!
733  * \brief Default intialization constructor.
734  */
735 WMStateCvCamera::WMStateCvCamera(WMSession &session,
736  const CvSize &sizeDisplay,
737  const CameraRes eVideoRes,
738  const CameraRes eImageRes,
739  int nInitAction) :
740  WMState(session, nInitAction),
741  m_camera(session.m_sVidDevName, session.m_nVideoIndex, eVideoRes, eImageRes)
742 {
743  m_pImgMarked = NULL;
744  m_pImgDisplay = NULL;
745  m_sizeDisplay = sizeDisplay;
746  m_eVideoRes = eVideoRes;
747  m_pTransIoI = NULL;
748  m_bHardBttnEnable = true;
749  m_bPaused = false;
750 }
751 
752 /*!
753  * \brief Default destructor.
754  */
755 WMStateCvCamera::~WMStateCvCamera()
756 {
757  destroyInterface();
758 }
759 
760 /*!
761  * \brief Get the next input action into this state.
762  *
763  * Actions: Soft button push.
764  * Actions: Hard button push.
765  *
766  * The retrieved next action becomes the current action.
767  *
768  * \param session Session data.
769  *
770  * \return Next action.
771  */
772 int WMStateCvCamera::getNextAction(WMSession &session, int nTimeoutMs)
773 {
774  session.m_pWin->WaitEvent(nTimeoutMs);
775 
776  if( m_pMenu == NULL )
777  {
778  m_nCurAction = WMUIActionNone;
779  }
780  else
781  {
782  if( (m_nCurAction = m_pMenu->GetCurrentAction()) == WMUIActionNone )
783  {
784  if( m_bHardBttnEnable && isHardButtonPushed(session) )
785  {
786  m_nCurAction = WMUIActionHardButtonPush;
787  }
788  }
789  m_pMenu->SetCurrentAction(WMUIActionNone);
790  }
791  return m_nCurAction;
792 }
793 
794 void WMStateCvCamera::buildInterface(WMSession &session)
795 {
796  // build base
797  WMState::buildInterface(session);
798 
799  // workspace is an opencv image
800  session.m_pWin->WorkspaceSetAsCvImage();
801 
802  // image displayed to user
803  m_pImgDisplay = cvCreateImage(m_sizeDisplay, IPL_DEPTH_8U, 3);
804 
805  // clear display image
806  cvSet(m_pImgDisplay, GuiRgbImageBg);
807 
808  // show blank image
809  session.m_pWin->ShowCvImage(m_pImgDisplay);
810 
811  // no marked up image
812  m_pImgMarked = NULL;
813 
814  // start video capture
815  m_camera.startCamera(m_eVideoRes);
816 
817  if( m_camera.isCameraRunning() )
818  {
819  m_pTransIoI = new WMWinIoI(m_camera.getVideoResolution(),
820  m_sizeDisplay,
821  WMImgTransRot,
822  WMImgTransAlign,
823  WMImgTransCrop);
824  }
825 
826  else
827  {
828  m_pTransIoI = NULL;
829  setFatal();
830  }
831 }
832 
833 void WMStateCvCamera::destroyInterface()
834 {
835  if( m_pImgMarked != NULL )
836  {
837  cvReleaseImage(&m_pImgMarked); // laser marked image
838  m_pImgMarked = NULL;
839  }
840 
841  if( m_pImgDisplay != NULL )
842  {
843  cvReleaseImage(&m_pImgDisplay); // release displayed image
844  m_pImgDisplay = NULL;
845  }
846 
847  if( m_pTransIoI != NULL )
848  {
849  delete m_pTransIoI;
850  m_pTransIoI = NULL;
851  }
852 }
853 
854 /*!
855  * \brief Clone current video frame.
856  *
857  * \param session Session data.
858  */
859 void WMStateCvCamera::cloneFrame(WMSession &session)
860 {
861  IplImage *pImgFrame;
862 
863  // released old marked up image
864  if( m_pImgMarked != NULL )
865  {
866  cvReleaseImage(&m_pImgMarked);
867  m_pImgMarked = NULL;
868  }
869 
870  // clone calibration image
871  if( (pImgFrame = m_camera.getCurFrame()) != NULL )
872  {
873  m_pImgMarked = cvCloneImage(pImgFrame);
874  }
875 }
876 
877 /*!
878  * \brief Show transformed marked up video frame clone to display.
879  *
880  * Calls virtual function markupImg() to perform task specific markups.
881  *
882  * \param session Session data.
883  */
884 void WMStateCvCamera::showMarkupImg(WMSession &session)
885 {
886  // clone current calibration image
887  cloneFrame(session);
888 
889  // mark up
890  markupImg(session);
891 
892  // show
893  showImg(session, m_pImgMarked);
894 }
895 
896 /*!
897  * \brief Show transformed image on display.
898  *
899  * \param session Session data.
900  * \param pImg Image.
901  */
902 void WMStateCvCamera::showImg(WMSession &session, IplImage *pImg)
903 {
904  // clear display image
905  cvSet(m_pImgDisplay, GuiRgbImageBg);
906 
907  // transform and place captured frame on display image
908  if( pImg != NULL )
909  {
910  m_pTransIoI->WMWinIoITrans(pImg, m_pImgDisplay);
911  }
912 
913  // show image
914  session.m_pWin->ShowCvImage(m_pImgDisplay);
915 }
916 
917 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
918 // State Trasition Functions
919 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
920 
921 /*!
922  * \brief Show video frame to display.
923  *
924  * State transition function.
925  *
926  * \param session Session data.
927  */
928 void WMStateCvCamera::transRunVideo(WMSession &session)
929 {
930  IplImage *pImgFrame;
931 
932  if( (pImgFrame = m_camera.grabFrame()) == NULL )
933  {
934  session.PushFatalState("Failed to grab video frame.");
935  }
936  else
937  {
938  showImg(session, pImgFrame);
939  }
940 }
941 
942 /*!
943  * \brief Show video frame with markup overlay to display.
944  *
945  * State transition function.
946  *
947  * \param session Session data.
948  */
949 void WMStateCvCamera::transRunMarkupVideo(WMSession &session)
950 {
951  IplImage *pImgFrame;
952 
953  if( (pImgFrame = m_camera.grabFrame()) == NULL )
954  {
955  session.PushFatalState("Failed to grab video frame.");
956  }
957  else
958  {
959  showMarkupImg(session);
960  }
961 }
962 
963 /*!
964  * \brief Stop video.
965  *
966  * State transition function.
967  *
968  * \param session Session data.
969  */
970 void WMStateCvCamera::transStopVideo(WMSession &session)
971 {
972  m_camera.stopCamera();
973 }
974 
975 
976 //------------------------------------------------------------------------------
977 // WMStateGstCamera Class
978 //------------------------------------------------------------------------------
979 
980 /*!
981  * \brief Default intialization constructor.
982  */
983 WMStateGstCamera::WMStateGstCamera(WMSession &session,
984  const CvSize &sizeDisplay,
985  const CameraRes eVideoRes,
986  const CameraRes eImageRes,
987  int nInitAction) :
988  WMState(session, nInitAction),
989  m_camera(session.m_sVidDevName, session.m_nVideoIndex, eVideoRes, eImageRes)
990 {
991  m_sizeVidWin = sizeDisplay;
992  m_bHardBttnEnable = true;
993  m_bPaused = false;
994 }
995 
996 /*!
997  * \brief Default destructor.
998  */
999 WMStateGstCamera::~WMStateGstCamera()
1000 {
1001  destroyInterface();
1002 }
1003 
1004 /*!
1005  * \brief Get the next input action into this state.
1006  *
1007  * Actions: Soft button push.
1008  * Actions: Hard button push.
1009  *
1010  * The retrieved next action becomes the current action.
1011  *
1012  * \param session Session data.
1013  *
1014  * \return Next action.
1015  */
1016 int WMStateGstCamera::getNextAction(WMSession &session, int nTimeoutMs)
1017 {
1018  session.m_pWin->WaitEvent(nTimeoutMs);
1019 
1020  if( m_pMenu == NULL )
1021  {
1022  m_nCurAction = WMUIActionNone;
1023  }
1024  else
1025  {
1026  if( (m_nCurAction = m_pMenu->GetCurrentAction()) == WMUIActionNone )
1027  {
1028  if( m_bHardBttnEnable && isHardButtonPushed(session) )
1029  {
1030  m_nCurAction = WMUIActionHardButtonPush;
1031  }
1032  }
1033  m_pMenu->SetCurrentAction(WMUIActionNone);
1034  }
1035  return m_nCurAction;
1036 }
1037 
1038 void WMStateGstCamera::buildInterface(WMSession &session)
1039 {
1040  // build base
1041  WMState::buildInterface(session);
1042 
1043  // workspace is an opencv image
1044  session.m_pWin->WorkspaceSetAsGstWin(m_sizeVidWin);
1045 
1046  // set camera's X-window view window id
1047  m_camera.setXid(session.m_pWin->GetGstXid());
1048 
1049  // start video capture
1050  m_camera.startCamera();
1051 }
1052 
1053 void WMStateGstCamera::destroyInterface()
1054 {
1055 }
1056 
1057 /*!
1058  * \brief Clone current video frame.
1059  *
1060  * \todo Clone GST frame.
1061  *
1062  * \param session Session data.
1063  */
1064 void WMStateGstCamera::cloneFrame(WMSession &session)
1065 {
1066 }
1067 
1068 /*!
1069  * \brief Show transformed marked up video frame clone to display.
1070  *
1071  * Calls virtual function markupImg() to perform task specific markups.
1072  *
1073  * \param session Session data.
1074  */
1075 void WMStateGstCamera::showMarkupImg(WMSession &session)
1076 {
1077  // mark up and show
1078  markupImg(session);
1079 }
1080 
1081 /*!
1082  * \brief Show transformed image on display.
1083  *
1084  * \param session Session data.
1085  * \param pImg Image.
1086  */
1087 void WMStateGstCamera::showImg(WMSession &session, IplImage *pImg)
1088 {
1089 }
1090 
1091 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1092 // State Trasition Functions
1093 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1094 
1095 /*!
1096  * \brief Show video frame to display.
1097  *
1098  * State transition function.
1099  *
1100  * \param session Session data.
1101  */
1102 void WMStateGstCamera::transRunVideo(WMSession &session)
1103 {
1104  // nothing to do: its all done with gobject callbacks
1105 }
1106 
1107 /*!
1108  * \brief Show video frame with markup overlay to display.
1109  *
1110  * State transition function.
1111  *
1112  * \param session Session data.
1113  */
1114 void WMStateGstCamera::transRunMarkupVideo(WMSession &session)
1115 {
1116 }
1117 
1118 /*!
1119  * \brief Stop video.
1120  *
1121  * State transition function.
1122  *
1123  * \param session Session data.
1124  */
1125 void WMStateGstCamera::transStopVideo(WMSession &session)
1126 {
1127  m_camera.stopCamera();
1128 }
int m_nCurAction
current state input action
Definition: State.orig.h:196
bool m_bPaused
capturing images is [not] paused
Definition: State.orig.h:344
Menu * m_pMenu
button menu
Definition: State.orig.h:194
bool m_bHardBttnEnable
enable/disable hard button input
Definition: State.orig.h:199
cv::Size ar43width(cv::Size &siz)
Calculate the nearest 4:3 aspect ratio from the width component of the target size.
Definition: WinOpenCv.h:272
GstCamera m_camera
video camera instance
Definition: State.orig.h:343
CvSize m_sizeVidWin
size of video window
Definition: State.orig.h:345
int getCurAction()
Get the currently retrieved input action.
Definition: State.orig.h:128