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