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

视频捕捉/采集

开发平台:

MultiPlatform

  1. /**
  2.   * HandVu - a library for computer vision-based hand gesture
  3.   * recognition.
  4.   * Copyright (C) 2004 Mathias Kolsch, matz@cs.ucsb.edu
  5.   *
  6.   * This program is free software; you can redistribute it and/or
  7.   * modify it under the terms of the GNU General Public License
  8.   * as published by the Free Software Foundation; either version 2
  9.   * of the License, or (at your option) any later version.
  10.   *
  11.   * This program is distributed in the hope that it will be useful,
  12.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.   * GNU General Public License for more details.
  15.   *
  16.   * You should have received a copy of the GNU General Public License
  17.   * along with this program; if not, write to the Free Software
  18.   * Foundation, Inc., 59 Temple Place - Suite 330, 
  19.   * Boston, MA  02111-1307, USA.
  20.   *
  21.   * $Id: HandVu_img.cpp,v 1.16 2005/10/30 21:16:04 matz Exp $
  22. **/
  23. #include "Common.h"
  24. #include "CubicleWrapper.h"
  25. #include "HandVu.hpp"
  26. #include "FileHandling.h"
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <highgui.h>
  30. #ifdef HAVE_UNISTD_H
  31. #include <unistd.h>
  32. #endif
  33. #ifdef HAVE_ERRNO_H
  34. #include <errno.h>
  35. #endif
  36. #ifdef HAVE_FLOAT_H
  37. #include <float.h>
  38. #endif
  39. #ifdef USE_MFC
  40. #ifdef _DEBUG
  41. #define new DEBUG_NEW
  42. #undef THIS_FILE
  43. static char THIS_FILE[] = __FILE__;
  44. #endif // _DEBUG
  45. #endif // USE_MFC
  46. /////////////////////////////////////////////////////////////////////////////
  47. // HandVu
  48. void HandVu::SaveScannedArea(IplImage* pImg, string& picfile)
  49. {
  50.   SaveImageArea(pImg, m_scan_area, picfile);
  51. }
  52. void HandVu::SaveImageArea(IplImage* pImg, CRect area, string& picfile)
  53. {
  54.   string extension = ".ppm";
  55.   if (picfile=="") {
  56.     if (m_img_fname_root=="") {
  57.       throw HVException("must SetSaveFilenameRoot if no filename given");
  58.     }
  59.     picfile = GetNextSnapshotFilename(m_img_fname_root, extension);
  60.   }
  61.   if (area.left>=area.right) { int t=area.left; area.left=area.right; area.right=t; }
  62.   if (area.top>=area.bottom) { int t=area.top; area.top=area.bottom; area.bottom=t; }
  63.   if (area.left<0) area.left = 0;
  64.   if (area.right>pImg->width) area.right = pImg->width;;
  65.   if (area.top<0) area.top = 0;;
  66.   if (area.bottom>pImg->height) area.bottom = pImg->height;
  67.   if (strcmp(pImg->channelSeq, "BGR")==0) {
  68.     WriteAreaAsPPM_BGR(pImg, area, picfile);
  69.   } else if (strcmp(pImg->channelSeq, "RGB")==0) {
  70.     WriteAreaAsPPM_RGB(pImg, area, picfile);
  71.   } else if (strcmp(pImg->channelSeq, "GRAY")==0) {
  72.     WriteAreaAsPGM_Gray(pImg, area, picfile);
  73.   } else {
  74.     throw HVException("can not write this image format");
  75.   }
  76. }
  77. void HandVu::WriteAreaAsBMP(IplImage* pImg, const CRect& area, const string& filename)
  78. {
  79.   IplImage* areaImg = 
  80.     cvCreateImage(cvSize(area.right-area.left, area.bottom-area.top),
  81.                   pImg->depth, pImg->nChannels);
  82.   cvResize(pImg, areaImg);
  83.   int success = cvSaveImage(filename.c_str(), areaImg);
  84.   if (!success) {
  85.     throw HVException(string("failure saving image to ") + filename);
  86.   }
  87. }
  88. // write binary color unsigned char PPM format (the most standard)
  89. void HandVu::WriteAreaAsPPM_BGR(IplImage* pImg, const CRect& area, const string& picfile)
  90. {
  91.   ASSERT(strcmp(pImg->channelSeq, "BGR")==0);
  92.   FILE *fp = fopen(picfile.c_str(), "wb");  // open for writing in binary format
  93.   if (!fp) {
  94.     throw HVEFile(picfile, "cannot open file for writing");
  95.   }
  96.   // allocate buffer
  97.   int width = area.right-area.left;
  98.   size_t total_size = width*(area.bottom-area.top)*3;
  99.   unsigned char* buf = (unsigned char*) alloca(total_size);
  100.   ASSERT(pImg->nChannels==3);
  101.   // fill buffer with image data
  102.   unsigned char* pPix = buf;
  103.   for (int y=area.top; y<area.bottom; y++) {
  104.     ColorBGR* pSrc = (ColorBGR*) pImg->imageData;
  105.     pSrc += y*pImg->width + area.left;
  106.     for (int x=area.left; x<area.right; x++) {
  107.       *pPix++ = (unsigned char) pSrc->red;
  108.       *pPix++ = (unsigned char) pSrc->green;
  109.       *pPix++ = (unsigned char) pSrc->blue;
  110.       pSrc++;
  111.     }
  112.   }
  113.   /*
  114.   CvPixelPosition8u position;
  115.   CV_INIT_PIXEL_POS(position, 
  116.                     (unsigned char*)(pImg->imageData),
  117.                     pImg->widthStep, 
  118.                     cvSize(pImg->width, pImg->height), 0, 0,
  119.                     pImg->origin);
  120.   for (int y=top; y<bottom; y++) {
  121.     CV_MOVE_TO(position, left, y, 3);
  122.     for (int x=left; x<right; x++) {
  123.       unsigned char* curr = CV_GET_CURRENT(position, 3);
  124.       *pPix++ = curr[1];
  125.       *pPix++ = curr[0];
  126.       *pPix++ = curr[2];
  127.       CV_MOVE_RIGHT(position, 3);
  128.     }
  129.   }
  130.   */
  131.   // write to file
  132.   // header
  133.   fprintf(fp, "P6n%d %dn%dn", width, area.bottom-area.top, 255);  // binary
  134.   // body
  135.   size_t cnt = fwrite((void *) buf, 1, total_size, fp);
  136.   fclose(fp);
  137.   if ((int)cnt!=total_size) {
  138.     throw HVEFile(picfile, "cannot write image data to file");
  139.   }
  140. }
  141. // write binary color unsigned char PPM format (the most standard)
  142. void HandVu::WriteAreaAsPPM_RGB(IplImage* pImg, const CRect& area, const string& picfile)
  143. {
  144.   ASSERT(strcmp(pImg->channelSeq, "BGR")==0);
  145.   FILE *fp = fopen(picfile.c_str(), "wb");  // open for writing in binary format
  146.   if (!fp) {
  147.     throw HVEFile(picfile, "cannot open file for writing");
  148.   }
  149.   // allocate buffer
  150.   int width = area.right-area.left;
  151.   size_t total_size = width*(area.bottom-area.top)*3;
  152.   unsigned char* buf = (unsigned char*) alloca(total_size);
  153.   ASSERT(pImg->nChannels==3);
  154.   // fill buffer with image data
  155.   unsigned char* pPix = buf;
  156.   for (int y=area.top; y<area.bottom; y++) {
  157.     ColorBGR* pSrc = (ColorBGR*) pImg->imageData;
  158.     pSrc += y*pImg->width + area.left;
  159.     for (int x=area.left; x<area.right; x++) {
  160.       *pPix++ = (unsigned char) pSrc->blue;
  161.       *pPix++ = (unsigned char) pSrc->green;
  162.       *pPix++ = (unsigned char) pSrc->red;
  163.       pSrc++;
  164.     }
  165.   }
  166.   /*
  167.   CvPixelPosition8u position;
  168.   CV_INIT_PIXEL_POS(position, 
  169.                     (unsigned char*)(pImg->imageData),
  170.                     pImg->widthStep, 
  171.                     cvSize(pImg->width, pImg->height), 0, 0,
  172.                     pImg->origin);
  173.   for (int y=top; y<bottom; y++) {
  174.     CV_MOVE_TO(position, left, y, 3);
  175.     for (int x=left; x<right; x++) {
  176.       unsigned char* curr = CV_GET_CURRENT(position, 3);
  177.       *pPix++ = curr[1];
  178.       *pPix++ = curr[0];
  179.       *pPix++ = curr[2];
  180.       CV_MOVE_RIGHT(position, 3);
  181.     }
  182.   }
  183.   */
  184.   // write to file
  185.   // header
  186.   fprintf(fp, "P6n%d %dn%dn", width, area.bottom-area.top, 255);  // binary
  187.   // body
  188.   size_t cnt = fwrite((void *) buf, 1, total_size, fp);
  189.   fclose(fp);
  190.   if ((int)cnt!=total_size) {
  191.     throw HVEFile(picfile, "cannot write image data to file");
  192.   }
  193. }
  194. // write binary gray unsigned char PGM format
  195. void HandVu::WriteAreaAsPGM_Gray(IplImage* pImg, const CRect& area, const string& picfile)
  196. {
  197.   ASSERT(strcmp(pImg->channelSeq, "GRAY")==0);
  198.   ASSERT(pImg->depth==IPL_DEPTH_32F);
  199.   FILE *fp = fopen(picfile.c_str(), "wb");  // open for writing in binary format
  200.   if (!fp) {
  201.     throw HVEFile(picfile, "cannot open file for writing");
  202.   }
  203.   // allocate buffer
  204.   int width = area.right-area.left;
  205.   size_t total_size = width*(area.bottom-area.top);
  206.   unsigned char* buf = (unsigned char*) alloca(total_size);
  207.   ASSERT(pImg->nChannels==1);
  208.   // get min and max
  209.   float min=FLT_MAX, max=FLT_MIN;
  210.   unsigned char* pPix = buf;
  211.   for (int y=area.top; y<area.bottom; y++) {
  212.     float* pSrc = (float*) pImg->imageData;
  213.     pSrc += y*pImg->width + area.left;
  214.     for (int x=area.left; x<area.right; x++) {
  215.       if (*pSrc<min) {
  216.         min = *pSrc;
  217.       }
  218.       if (*pSrc>max) {
  219.         max = *pSrc;
  220.       }
  221.       pSrc++;
  222.     }  }
  223.   float spread = max-min;
  224.   // fill buffer with image data
  225.   for (int y=area.top; y<area.bottom; y++) {
  226.     float* pSrc = (float*) pImg->imageData;
  227. //    unsigned char* pSrc = (unsigned char*) pImg->imageData;
  228.     pSrc += y*pImg->width + area.left;
  229.     for (int x=area.left; x<area.right; x++) {
  230.       *pPix++ = (unsigned char) (255.0 * (*pSrc-min)/spread);      pSrc++;
  231.     }  }
  232.   // write to file
  233.   // header
  234.   fprintf(fp, "P5n%d %dn%dn", width, area.bottom-area.top, 255);  // binary
  235.   // body
  236.   size_t cnt = fwrite((void *) buf, 1, total_size, fp);
  237.   fclose(fp);
  238.   if ((int)cnt!=total_size) {
  239.     throw HVEFile(picfile, "cannot write image data to file");
  240.   }
  241. }
  242. string HandVu::GetNextSnapshotFilename(const string& base,
  243.                                        const string& extension)
  244. {
  245.   static int g_last_archive_id=0;
  246.   ASSERT(base!="");
  247.   string next_name;
  248.   for (;;) {
  249.     g_last_archive_id++;
  250.     char id[10];
  251.     sprintf(id, "%d", g_last_archive_id);
  252.     // todo: should use snprintf (WIN32: _snprintf)
  253.     next_name = base + id + extension;
  254.     FILE* test = fopen(next_name.c_str(), "r");
  255.     if (test) {
  256.       fclose(test);
  257.     } else {
  258.       break;
  259.     }
  260.   }
  261.   
  262.   return next_name;
  263. }
  264. #if defined(STAT_MACROS_BROKEN) || !defined(HAVE_CONFIG_H) && defined(WIN32)
  265. #define S_ISDIR(mode) (mode&_S_IFDIR)
  266. #endif
  267. void HandVu::SetSaveFilenameRoot(const string& fname_root) 
  268. {
  269.   struct stat s;
  270.   int error = stat(fname_root.c_str(), &s);
  271. #ifdef HAVE_STAT_EMPTY_STRING_BUG
  272.   if (fname_root.length()==0) {
  273.     error = -1;
  274.     errno = ENOENT;
  275.   }
  276. #endif
  277.   if (error==-1 && errno==ENOENT) {
  278.     // file does not exist
  279.     // maybe fname_root is a combination of a 
  280.     // path and a partial file name?
  281.     string path, fname;
  282.     SplitPathFile(fname_root, path, fname);
  283.     error = stat(path.c_str(), &s);
  284. #ifdef HAVE_STAT_EMPTY_STRING_BUG
  285.     if (path.length()==0) {
  286.       error = -1;
  287.       errno = ENOENT;
  288.     }
  289. #endif
  290.     if (error!=0 && errno==ENOENT || !S_ISDIR(s.st_mode)) {
  291.       throw HVException(string("neither directory ") + fname_root +
  292.         " nor directory " + path + " exist, or they are not accessible");
  293.     }
  294.   } else if (error!=0 || !S_ISDIR(s.st_mode)) {
  295.     throw HVException(string("directory ") + fname_root +
  296.     " does not exist");
  297.   }
  298.   m_img_fname_root = fname_root;
  299. }