cmvision.h
00001 /*=========================================================================
00002     CMVision.h
00003   -------------------------------------------------------------------------
00004     API definition for the CMVision real time Color Machine Vision library
00005   -------------------------------------------------------------------------
00006     Copyright 1999, 2000         #### ### ### ## ## ## #### ##  ###  ##  ##
00007     James R. Bruce              ##    ####### ## ## ## ##   ## ## ## ######
00008     School of Computer Science  ##    ## # ## ## ## ##  ### ## ## ## ## ###
00009     Carnegie Mellon University   #### ##   ##  ###  ## #### ##  ###  ##  ##
00010   -------------------------------------------------------------------------
00011     This library is free software; you can redistribute it and/or
00012     modify it under the terms of the GNU Lesser General Public
00013     License as published by the Free Software Foundation; either
00014     version 2.1 of the License, or (at your option) any later version.
00015 
00016     This library is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019     Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public
00022     License along with this library; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00024   =========================================================================*/
00025 
00026 #ifndef __CMVISION_H__
00027 #define __CMVISION_H__
00028 
00029 // uncomment if your compiler supports the "restrict" keyword
00030 // #define restrict __restrict__
00031 #define restrict
00032 
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <stdio.h>
00036 
00037 /*
00038 Ultra-fast intro to processing steps:
00039  - Color segmentation
00040    - load / save
00041    - set new values
00042    - process frame
00043  - Connected Regions
00044    - RLE
00045    - merge
00046    - extract blobs
00047    - separate blobs
00048    - sort blobs
00049    - merge blobs
00050  - Blob merging (not currently in release)
00051    - merge by area occupied
00052 
00053 Options File Format: (RGB merge name)
00054 [Colors]
00055 (00,00,00) 0.95 'Orange'
00056 (00,00,00) 0.00 'Pink'
00057 (00,00,00) 0.00 'Red'
00058 (00,00,00) 0.00 'DarkBlue'
00059 (00,00,00) 0.00 'Blue'
00060 
00061 [Thresholds]
00062 (<lo>:<hi>,<lo>:<hi>,<lo>:<hi>)
00063 (<lo>:<hi>,<lo>:<hi>,<lo>:<hi>)
00064 (<lo>:<hi>,<lo>:<hi>,<lo>:<hi>)
00065 */
00066 
00067 #define CMV_COLOR_LEVELS  256
00068 #define CMV_MAX_COLORS     32
00069 
00070 // sets tweaked optimal values for image size
00071 #define CMV_DEFAULT_WIDTH  320
00072 #define CMV_DEFAULT_HEIGHT 240
00073 
00074 // values may need tweaked, although these seem to work usually
00075 #define CMV_MAX_RUNS     (CMV_DEFAULT_WIDTH * CMV_DEFAULT_HEIGHT) / 4
00076 #define CMV_MAX_REGIONS  CMV_MAX_RUNS / 4
00077 #define CMV_MIN_AREA     20
00078 
00079 #define CMV_NONE ((unsigned)(-1))
00080 
00081 #ifndef NULL
00082 #define NULL (0)
00083 #endif
00084 
00085 struct yuv{
00086   unsigned char y,u,v;
00087 };
00088 
00089 struct yuv422{
00090   unsigned char y1,u,y2,v;
00091 };
00092 
00093 struct uyvy{
00094   unsigned char u,y1,v,y2;
00095 };
00096 
00097 #ifdef USE_METEOR
00098   typedef struct uyvy image_pixel;
00099 #else
00100   typedef struct yuv422 image_pixel;
00101 #endif
00102 
00103 #ifndef RGB_STRUCT
00104 #define RGB_STRUCT
00105 struct rgb{
00106   unsigned char red,green,blue;
00107 };
00108 #endif
00109 
00110 // Options for level of processing
00111 //   use enable()/disable() to change 
00112 #define CMV_THRESHOLD      0x01
00113 #define CMV_COLOR_AVERAGES 0x02
00114 #define CMV_DUAL_THRESHOLD 0x04
00115 #define CMV_DENSITY_MERGE  0x08
00116 
00117 #define CMV_VALID_OPTIONS  0x0F
00118 
00119 
00120 class CMVision{
00121 public:
00122   struct region{
00123     int color;          // id of the color
00124     int area;           // occupied area in pixels
00125     int x1,y1,x2,y2;    // bounding box (x1,y1) - (x2,y2)
00126     float cen_x,cen_y;  // centroid
00127     yuv average;        // average color (if CMV_COLOR_AVERAGES enabled)
00128 
00129     int sum_x,sum_y,sum_z; // temporaries for centroid and avg color
00130     // int area_check; // DEBUG ONLY
00131 
00132     region *next;       // next region in list
00133 
00134     // int number; // DEBUG ONLY
00135   };
00136 
00137   struct rle{
00138     unsigned color;     // which color(s) this run represents
00139     int length;         // the length of the run (in pixels)
00140     int parent;         // run's parent in the connected components tree
00141   };
00142 
00143   struct color_info{
00144     rgb color;          // example color (such as used in test output)
00145     char *name;         // color's meaninful name (e.g. ball, goal)
00146     double merge;       // merge density threshold
00147     int expected_num;   // expected number of regions (used for merge)
00148     int y_low,y_high;   // Y,U,V component thresholds
00149     int u_low,u_high;
00150     int v_low,v_high;
00151   };
00152 
00153   struct point{
00154     double x,y;
00155   };
00156 
00157   struct line{
00158     point a,b;
00159   };
00160 
00161   struct rectangle{
00162     int x,y,w,h;
00163   };
00164 
00165 protected:
00166   unsigned y_class[CMV_COLOR_LEVELS];
00167   unsigned u_class[CMV_COLOR_LEVELS];
00168   unsigned v_class[CMV_COLOR_LEVELS];
00169 
00170   region region_table[CMV_MAX_REGIONS];
00171   region *region_list[CMV_MAX_COLORS];
00172   int region_count[CMV_MAX_COLORS];
00173 
00174   rle rmap[CMV_MAX_RUNS];
00175 
00176   color_info colors[CMV_MAX_COLORS];
00177   int width,height;
00178   unsigned *map;
00179 
00180   unsigned options;
00181 
00182   int cmv_min_area;
00183   int cmv_max_area;
00184 
00185 protected:
00186 // Private functions
00187   void classifyFrame(image_pixel * restrict img,unsigned * restrict map);
00188   int  encodeRuns(rle * restrict out,unsigned * restrict map);
00189   void connectComponents(rle * restrict map,int num);
00190   int  extractRegions(region * restrict reg,rle * restrict rmap,int num);
00191   void calcAverageColors(region * restrict reg,int num_reg,
00192                          image_pixel * restrict img,
00193                          rle * restrict rmap,int num_runs);
00194   int  separateRegions(region * restrict reg,int num);
00195   region *sortRegionListByArea(region * restrict list,int passes);
00196   void sortRegions(int max_area);
00197 
00198   // density based merging support
00199   int mergeRegions(region *p,int num,double density_thresh);
00200   int mergeRegions();
00201 
00202   void clear();
00203 
00204 public:
00205   CMVision()  {clear();}
00206   ~CMVision() {close();}
00207 
00208   bool initialize(int nwidth,int nheight);
00209   bool loadOptions(char *filename);
00210   bool saveOptions(char *filename);
00211   bool enable(unsigned opt);
00212   bool disable(unsigned opt);
00213   void close();
00214 
00215   bool testClassify(rgb * restrict out,image_pixel * restrict image);
00216   bool getThreshold(int color,
00217          int &y_low,int &y_high,
00218          int &u_low,int &u_high,
00219          int &v_low,int &v_high);
00220   bool setThreshold(int color,
00221          int y_low,int y_high,
00222          int u_low,int u_high,
00223          int v_low,int v_high);
00224 
00225   unsigned *getMap()
00226     {return(map);}
00227 
00228   char *getColorName(int color)
00229     {return(colors[color].name);}
00230   rgb getColorVisual(int color)
00231     {return(colors[color].color);}
00232 
00233   color_info *getColorInfo(int color)
00234     {return(&colors[color]);}
00235   void getColorInfo(int color,color_info &info)
00236     {info = colors[color];}
00237   void setColorInfo(int color,color_info &info)
00238     {colors[color] = info;}
00239 
00240   bool processFrame(image_pixel *image);
00241   bool processFrame(unsigned *map);
00242   int numRegions(int color_id);
00243   region *getRegions(int color_id);
00244   void set_cmv_min_area(int area) { cmv_min_area = area; }
00245   void set_cmv_max_area(int area) { cmv_max_area = area; }
00246 };
00247 
00248 #endif