MaintenanceApp.cpp
上传用户:lijia5631
上传日期:2008-11-10
资源大小:1214k
文件大小:15k
源码类别:

视频捕捉/采集

开发平台:

MultiPlatform

  1. /**   * HandVu - a library for computer vision-based hand gesture   * recognition.   * Copyright (C) 2004 Mathias Kolsch, matz@cs.ucsb.edu   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License   * as published by the Free Software Foundation; either version 2   * of the License, or (at your option) any later version.   *   * This program is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details.   *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place - Suite 330,    * Boston, MA  02111-1307, USA.   *   * $Id: MaintenanceApp.cpp,v 1.12 2005/10/30 23:00:43 matz Exp $ **/ #include "StdAfx.h" #include <initguid.h>
  2. #include "Common.h"
  3. #include "iHandVuFilter.h"
  4. #include "MaintenanceApp.h" #include "HandVu.h" CMaintenanceApp::CMaintenanceApp() : m_img_width(0),   m_img_height(0),   m_active_app(0),   m_last_ptr1_type(""),   m_last_ptr1_recognized(false),   m_voicerec_default_x(0),   m_voicerec_ctr_y(0),   m_imgcap_ctr_x(0),   m_imgcap_default_y(0),   m_woselect_ctr_x(0),   m_show_hand_location(true),   m_switchpos_x(0),   m_switchpos_y(0) {   m_time_last_app_switch.time = 0;   m_time_last_app_switch.millitm = 0; } CMaintenanceApp::~CMaintenanceApp() { } void CMaintenanceApp::Initialize(int img_width, int img_height) {   if (img_height<0) {
  5.     throw HVException("shouldn't be upside down anymore at this point");   }
  6.   m_img_width = img_width;   m_img_height = img_height;   BuildIconGroups(); } /** gesture event handler - select a button, switch applications, * draw the right hand pointer or detection aid */ void CMaintenanceApp::Tracked(const COverlayEvent& event) {   ASSERT(!event.m_ptr1_tracked     || (0.0<=event.m_ptr1_x && event.m_ptr1_x<1.0         && 0.0<=event.m_ptr1_y && event.m_ptr1_y<1.0));   m_event = event;   if (event.m_ptr1_tracked) {     m_group_shown[IG_HAND_FLAT] = false;   } else {     // not detected      ShowGroupExclusive(IG_HAND_FLAT);
  7.     return;
  8.   }   int x = cvRound(m_event.m_ptr1_x*(m_img_width-1));   int y = cvRound(m_event.m_ptr1_y*(m_img_height-1));   int orig_x = x, orig_y = y;   if (m_event.m_ptr1_tracked) {     PointerOver(&x, &y);   }   // reset selection   for (int grpcnt=0; grpcnt<(int)m_icon_groups.size(); grpcnt++) {     if (m_group_shown[grpcnt]) {       m_icon_groups[grpcnt].ResetSelection();     }   }   if (m_event.m_ptr1_recognized) {     if (m_event.m_ptr1_type=="Lback") {
  9.       Select(x, y);
  10.     } else if (m_event.m_ptr1_type=="victory" || m_event.m_ptr1_type=="open") {
  11.       // how long ago was the last switch?
  12.       Time currtime;
  13.       _ftime(&currtime);
  14.       unsigned int d_t = 1000*(unsigned int)(currtime.time-m_time_last_app_switch.time);
  15.       d_t += (currtime.millitm-m_time_last_app_switch.millitm);
  16.       // or was the last recognized gesture something else but task switch?
  17.       if (d_t>MIN_TIME_BTW_APP_SWITCH
  18.           || (m_last_ptr1_type!=m_event.m_ptr1_type 
  19.               && m_last_ptr1_recognized))
  20.       {
  21.         SwitchApplications();
  22.         m_switchpos_x = orig_x;         m_switchpos_y = orig_y;         m_time_last_app_switch = currtime;       }     } else if (m_event.m_ptr1_type=="sidepoint") {
  23.     }     m_last_ptr1_type = m_event.m_ptr1_type;   }   m_last_ptr1_recognized = m_event.m_ptr1_recognized; }    void CMaintenanceApp::PointerOver(int* pX, int* pY) {   const double scale = 2.0;   const CRect& old_hand = m_icon_groups[IG_HAND_POINTER].m_areas[0];   int width = old_hand.right-old_hand.left;   int height = old_hand.bottom-old_hand.top;   int halfwidth = width/2;   int halfheight = height/2;   switch (m_active_app) {     case 0: // no app       break;     case 1: // voice recorder       // constrain to movements in horizontal, scale horizontal       *pX = (int)(m_img_width*m_voicerec_default_x)+(int)(scale*(double)(*pX-m_switchpos_x));       *pY = (int)(m_img_height*m_voicerec_ctr_y)+halfheight;        break;     case 2: // img/vid cap       // constrain to movements in vertical, scale vertical       *pX = (int)(m_img_width*m_imgcap_ctr_x);       *pY = (int)((double)m_img_height*m_imgcap_default_y + scale*(double)(*pY-m_switchpos_y));       break;     case 3: // WO select       // for now: constrain to movements in vertical       *pX = (int)(m_img_width*m_woselect_ctr_x);       break;     case 4: // number select       break;     case 5: //        break;     default:        ASSERT(0);   }     for (int grpcnt=0; grpcnt<(int)m_icon_groups.size(); grpcnt++) {     if (!m_group_shown[grpcnt]) {       continue;     }     m_icon_groups[grpcnt].PointerOver(*pX, *pY);   }   int area_left = *pX-halfwidth;   int area_top = *pY-halfheight;   area_left = max(0, area_left);   area_top = max(0, area_top);   area_left = min(m_img_width-width-1, area_left);   area_top = min(m_img_height-height-1, area_top);   ASSERT(0<=area_left && area_left+width<m_img_width);   ASSERT(0<=area_top && area_top+height<m_img_height);   m_icon_groups[IG_HAND_POINTER].m_areas[0] =     CRect(area_left, area_top, area_left+width, area_top+height); } void CMaintenanceApp::Select(int x, int y) {   bool got_one = false;   for (int grpcnt=0; grpcnt<(int)m_icon_groups.size(); grpcnt++) {     if (!m_group_shown[grpcnt]) {       continue;     }     bool this_one = m_icon_groups[grpcnt].Select(x, y);     if (this_one) got_one = true;   }   if (got_one) {     // Beep(800, 70);
  24.   } } void CMaintenanceApp::SwitchApplications() {   m_active_app++;   if (m_active_app>NUM_APPS) {     m_active_app = 0;   }   switch (m_active_app) {     case 0: HideAllGroups(); break;     case 1: ShowGroupExclusive(IG_VOICE_RECORDER); break;     case 2: ShowGroupExclusive(IG_IMG_VID_CAP); break;     case 3: ShowGroupExclusive(IG_WO_SELECT); break;     case 4: ShowGroupExclusive(IG_NUM_SELECT); break;     case 5: HideAllGroups(); break;     default: ASSERT(0);   }   if (m_active_app==1 || m_active_app==2 || m_active_app==4) {     m_group_shown[IG_HAND_POINTER] = true;   } else {     m_group_shown[IG_HAND_POINTER] = false;   }   m_show_hand_location = true;   if (m_active_app==4) {     m_show_hand_location = false;   }   if (m_active_app==5) {     hvStartRecognition(1);   } else if (m_active_app==0) {     hvStopRecognition(1);   } } void CMaintenanceApp::Draw(IplImage* out_img) {   for (int grpcnt=0; grpcnt<(int)m_icon_groups.size(); grpcnt++) {     if (!m_group_shown[grpcnt]) {       continue;     }     for (int imgcnt=0; imgcnt<(int)m_icon_groups[grpcnt].m_images.size(); imgcnt++) {       if (!m_icon_groups[grpcnt].m_display_icon[imgcnt]) {         continue;       }       const CRect& area = m_icon_groups[grpcnt].m_areas[imgcnt];       IplImage* img = m_icon_groups[grpcnt].m_images[imgcnt];       ASSERT(img);       bool brighten = m_icon_groups[grpcnt].m_is_selected[imgcnt];       // left upper corner is origin       for (int y=area.top; y<area.bottom; y++) {         RGBTRIPLE* pDst = (RGBTRIPLE*) out_img->imageData;         pDst += y*out_img->width + area.left;         RGBTRIPLE* pSrc = (RGBTRIPLE*) cvPtr2D(img, y-area.top, 0);         for (int x=area.left; x<area.right; x++) {           BYTE r, b, g;           r = pSrc->rgbtRed;            g = pSrc->rgbtGreen;            b = pSrc->rgbtBlue;            if (r>0 || g>0 || b>0) {             if (brighten) {               pDst->rgbtRed = min(255, r*2);               pDst->rgbtGreen = min(255, g*2);               pDst->rgbtBlue = min(255, b*2);             } else {               pDst->rgbtRed = r;               pDst->rgbtGreen = g;               pDst->rgbtBlue = b;             }           }           pSrc++;           pDst++;         }       }       if (m_icon_groups[grpcnt].m_highlight_active[imgcnt]           && !(grpcnt==IG_WO_SELECT)) { // hack         cvRectangle (out_img, cvPoint(area.left+3, area.top+3),
  25.           cvPoint(area.right-4, area.bottom-4), CV_RGB(255,0,0), 5);
  26.       }       // hack:       if (grpcnt==IG_WO_SELECT && imgcnt==1) {         cvRectangle (out_img, cvPoint(area.left+3, area.top+3),
  27.           cvPoint(area.right-4, area.bottom-4), CV_RGB(255,0,0), 5);
  28.       }     }   }   int x = cvRound(m_event.m_ptr1_x*(m_img_width-1));   int y = cvRound(m_event.m_ptr1_y*(m_img_height-1));   // second pointer/hand    if (m_active_app==5) {     hvState state;     hvGetState(1, state);     if (state.tracked) {       int green_pos_x = cvRound(state.center_xpos*(m_img_width-1));       int green_pos_y = cvRound(state.center_ypos*(m_img_height-1));       CRect area(min(x, green_pos_x), min(y, green_pos_y), max(x, green_pos_x), max(y, green_pos_y));       DimEverythingBut(out_img, area);       cvRectangle(out_img, cvPoint(area.left, area.top),
  29.         cvPoint(area.right, area.bottom), CV_RGB(255,255,0), 3);
  30.       cvCircle(out_img, cvPoint(green_pos_x, green_pos_y), 10, CV_RGB(0,255,0), CV_FILLED);
  31.     }
  32.   }   if (m_show_hand_location && m_event.m_ptr1_tracked) {     cvCircle(out_img, cvPoint(x, y), 10, CV_RGB(255,0,0), CV_FILLED);
  33.   } } void CMaintenanceApp::DimEverythingBut(IplImage* pImage, const CRect& area) {   const double dimfac = .5;   for (int y=0; y<pImage->height; y++) {     RGBTRIPLE* pDst = (RGBTRIPLE*) pImage->imageData;
  34.     pDst += y*pImage->width;
  35.     for (int x=0; x<pImage->width; x++, pDst++) {       if (area.top<=y && y<area.bottom && area.left<=x && x<area.right) {         continue;       }       pDst->rgbtRed = (BYTE)((double)pDst->rgbtRed*dimfac);       pDst->rgbtGreen = (BYTE)((double)pDst->rgbtGreen*dimfac);       pDst->rgbtBlue = (BYTE)((double)pDst->rgbtBlue*dimfac);     }   } } CRect CMaintenanceApp::AbsoluteArea(double left, double top,                                    double right, double bottom) {   CRect abs_area;   abs_area = CRect((int)(m_img_width*left),     (int)(m_img_height*top),     (int)(m_img_width*right),     (int)(m_img_height*bottom));   ASSERT(0<=abs_area.left && abs_area.left<=m_img_width);   ASSERT(0<=abs_area.top && abs_area.top<=m_img_height);   ASSERT(0<=abs_area.right && abs_area.right<=m_img_width);   ASSERT(0<=abs_area.bottom && abs_area.bottom<=m_img_height);   ASSERT(abs_area.left<abs_area.right);   ASSERT(abs_area.top<abs_area.bottom);   return abs_area; } void CMaintenanceApp::HideAllGroups() {   for (int g=0; g<(int)m_group_shown.size(); g++) {     m_group_shown[g] = false;   } } void CMaintenanceApp::ShowGroupExclusive(IconGroupID id) {   HideAllGroups();   m_group_shown[id] = true; } void CMaintenanceApp::BuildIconGroups() {   DbgLog((LOG_CUSTOM1, 4, "loading icons..."));
  36.   m_icon_groups.resize(IG_LEN);   m_group_shown.resize(IG_LEN);   // voice recorder group   double vr_left = .05;   double width = .28;   double hor_gap = .02;   m_voicerec_ctr_y = .11;   m_voicerec_default_x = .5;   double height = .18;   double vr_top = m_voicerec_ctr_y-height/2.0;   double vr_bottom = vr_top+height;   CRect abs_area;   abs_area = AbsoluteArea(vr_left, vr_top, vr_left+width, vr_bottom);   m_icon_groups[IG_VOICE_RECORDER].AddOverlay("$IT_DATA/Icons/record.bmp", abs_area, true); //  m_icon_groups[IG_VOICE_RECORDER].AddOverlay("$IT_DATA/Icons/play.bmp", abs_area, true);   vr_left += width+hor_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_left+width, vr_bottom);   m_icon_groups[IG_VOICE_RECORDER].AddOverlay("$IT_DATA/Icons/pause.bmp", abs_area, true);   vr_left += width+hor_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_left+width, vr_bottom);   m_icon_groups[IG_VOICE_RECORDER].AddOverlay("$IT_DATA/Icons/stop.bmp", abs_area, true);   m_group_shown[IG_VOICE_RECORDER] = false;   // image/video capture menu group   m_imgcap_ctr_x = .2;   m_imgcap_default_y = .5;   width = .3;   vr_left = m_imgcap_ctr_x-width/2.0;   double vr_right = vr_left+width;   double ver_gap = .02;   vr_top = .15;   height = .23;   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_top+height);   m_icon_groups[IG_IMG_VID_CAP].AddOverlay("$IT_DATA/Icons/snapshot.bmp", abs_area, true);   vr_top += height+ver_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_top+height);   m_icon_groups[IG_IMG_VID_CAP].AddOverlay("$IT_DATA/Icons/frame.bmp", abs_area, true);   vr_top += height+ver_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_top+height);   m_icon_groups[IG_IMG_VID_CAP].AddOverlay("$IT_DATA/Icons/liveVideo.bmp", abs_area, true);   m_group_shown[IG_IMG_VID_CAP] = false;   // image area snapshot   /*   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_bottom);   m_icon_groups[IG_IMG_AREA].AddOverlay("$IT_DATA/Icons/frame.bmp", abs_area, true);   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_bottom);   m_icon_groups[IG_IMG_AREA].AddOverlay("$IT_DATA/Icons/liveVideo.bmp", abs_area, true);   m_group_shown[IG_IMG_AREA] = false;   */   // work order selection   m_woselect_ctr_x = 0.5;   vr_top = 0.05;   double vr_arrow_left = m_woselect_ctr_x-.06;   double vr_arrow_right = m_woselect_ctr_x+.06;   ver_gap = .03;   height = .15;   abs_area = AbsoluteArea(vr_arrow_left, vr_top, vr_arrow_right, vr_bottom);   m_icon_groups[IG_WO_SELECT].AddOverlay("$IT_DATA/Icons/scrollup.bmp", abs_area, true);   vr_left = m_woselect_ctr_x-.38;   vr_right = m_woselect_ctr_x+.38;   vr_top += height+ver_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_top+height);   m_icon_groups[IG_WO_SELECT].AddOverlay("$IT_DATA/Icons/option1.bmp", abs_area, true);   vr_top += height+ver_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_top+height);   m_icon_groups[IG_WO_SELECT].AddOverlay("$IT_DATA/Icons/option2.bmp", abs_area, true);   vr_top += height+ver_gap;   abs_area = AbsoluteArea(vr_left, vr_top, vr_right, vr_top+height);   m_icon_groups[IG_WO_SELECT].AddOverlay("$IT_DATA/Icons/option3.bmp", abs_area, true);   vr_top += height+ver_gap;   abs_area = AbsoluteArea(vr_arrow_left, vr_top, vr_arrow_right, vr_top+height);   m_icon_groups[IG_WO_SELECT].AddOverlay("$IT_DATA/Icons/scrolldown.bmp", abs_area, true);   m_group_shown[IG_WO_SELECT] = false;   // number selector, a grid of numbers   double xmargin = .08;   double ymargin = .08;   ver_gap = .023;   hor_gap = .03;   int num_per_col = 5; // must be >1   width = (1.0-2*xmargin-(num_per_col-1)*ver_gap)/(double)num_per_col;   height = width*.85;   for (int number=0; number<18; number++) {     const int buflen = 16;     char buf[buflen]; //    StringCbPrintfA(buf, buflen*sizeof(char), "%d", (number+1));
  37.     sprintf(buf, "%d", (number+1));     string filename = "$IT_DATA/Icons/number";     filename.append(buf).append(".bmp");     // where?     int xpos = number%num_per_col;     int ypos = number/num_per_col;     vr_left = xmargin+xpos*(ver_gap+width);     vr_top = ymargin+ypos*(hor_gap+height);     abs_area = AbsoluteArea(vr_left, vr_top, vr_left+width, vr_top+height);     m_icon_groups[IG_NUM_SELECT].AddOverlay(filename, abs_area, true);   }   m_group_shown[IG_NUM_SELECT] = false;   // hand pointer   abs_area = AbsoluteArea(0, 0, 0.18, 0.18);   m_icon_groups[IG_HAND_POINTER].AddOverlay("$IT_DATA/Icons/hand_pointer.bmp", abs_area, false);   m_group_shown[IG_HAND_POINTER] = false;   // hand pointer   abs_area = AbsoluteArea(0.67, 0.47, 0.87, 0.78);   m_icon_groups[IG_HAND_FLAT].AddOverlay("$IT_DATA/Icons/hand_flat.bmp", abs_area, false);   m_group_shown[IG_HAND_FLAT] = false;   DbgLog((LOG_CUSTOM1, 4, "... done loading icons"));
  38. }