Fawkes API  Fawkes Development Version
mirror_calib.h
00001 
00002 /***************************************************************************
00003  *  mirror_calib.h - Mirror calibration tool
00004  *
00005  *  Created: Fri Dec 07 18:34:50 2007
00006  *  Copyright  2007  Daniel Beck
00007  *  Copyright  2009  Christoph Schwering
00008  *
00009  ****************************************************************************/
00010 
00011 /*  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program 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
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL file in the doc directory.
00022  */
00023 
00024 #ifndef __FIREVISION_MODELS_MIRROR_MIRROR_CALIB_H_
00025 #define __FIREVISION_MODELS_MIRROR_MIRROR_CALIB_H_
00026 
00027 #if !defined(HAVE_IPP) and !defined(HAVE_OPENCV)
00028 #  error "Neither IPP nor OpenCV are installed."
00029 #endif
00030 
00031 #include <geometry/hom_point.h>
00032 #include <utils/math/angle.h>
00033 #include <fvutils/base/types.h>
00034 
00035 #include <fvmodels/mirror/bulb.h>
00036 
00037 #include <iostream>
00038 #include <vector>
00039 #include <map>
00040 #include <cassert>
00041 
00042 namespace firevision {
00043 
00044 class MirrorCalibTool
00045 {
00046  public:
00047   static void draw_line(unsigned char* yuv_buffer, double angle_deg,
00048                         int center_x, int center_y, int width, int height);
00049   void draw_mark_lines(unsigned char* yuv_buffer);
00050   static void draw_crosshair(unsigned char* yuv_buffer, int center_x,
00051                              int center_y, int width, int height);
00052 
00053   MirrorCalibTool();
00054   ~MirrorCalibTool();
00055 
00056   void load_mask(const char* mask_file_name);
00057   void push_back(const unsigned char* yuv_buffer,
00058                  size_t buflen,
00059                  int width,
00060                  int height,
00061                  double ori);
00062   void abort();
00063   void next_step();
00064   const unsigned char* get_last_yuv_buffer() const;
00065   const char* get_state_description() const;
00066 
00067   /** Sets preliminary center point.
00068    * @param x X-coordinate
00069    * @param y Y-coordinate  */
00070   inline void set_center(int x, int y) { 
00071     img_center_x_ = x;
00072     img_center_y_ = y;
00073   }
00074 
00075   /** Center X accessor.
00076    * @return center X value  */
00077   inline int center_x() const { return img_center_x_; }
00078   /** Center Y accessor.
00079    * @return center Y value  */
00080   inline int center_y() const { return img_center_y_; }
00081 
00082   void eval(unsigned int x,
00083             unsigned int y,
00084             float* x_ret,
00085             float* y_ret);
00086   
00087   void load(const char* filename);
00088   void save(const char* filename);
00089 
00090  private:
00091   class ConvexPolygon;
00092   class StepResult;
00093   typedef std::vector<StepResult> StepResultList;
00094   class Point;
00095   class PixelPoint;
00096   class CartesianPoint;
00097   class CartesianImage;
00098   class Hole;
00099   class Image;
00100   typedef std::vector<Hole> HoleList;
00101   typedef double PolarAngle;
00102   typedef int PolarRadius;
00103   typedef int RealDistance;
00104   typedef std::vector<PolarRadius> MarkList;
00105   typedef std::map<PolarAngle, MarkList> MarkMap;
00106   typedef std::pair<PolarAngle, PolarAngle> PolarAnglePair;
00107   typedef std::vector<Image> ImageList;
00108 
00109   class ConvexPolygon : public std::vector<PixelPoint> {
00110    public:
00111     bool contains(const CartesianImage& img, const CartesianPoint& r) const;
00112     bool contains(const PixelPoint& r) const;
00113   };
00114 
00115   enum StepName { SHARPENING, EDGE_DETECTION, COMBINATION, CENTERING,
00116                   PRE_MARKING, FINAL_MARKING, DONE };
00117   /// @cond INTERNALS
00118   struct CalibrationState {
00119     StepName              step;
00120     ImageList::size_type  image_index;
00121     bool                  centering_done;
00122     CalibrationState()
00123     : step(SHARPENING), image_index(0), centering_done(false) {};
00124   };
00125   /// @endcond
00126 
00127   void goto_next_state();
00128   void set_last_yuv_buffer(const unsigned char* last_buf);
00129   void draw_center(StepResult& result);
00130 
00131 
00132   static PolarAngle relativeOrientationToImageRotation(PolarAngle ori);
00133   static PolarAngle imageRotationToRelativeOrientation(PolarAngle ori);
00134 
00135   static void apply_sobel(unsigned char* src, unsigned char* dst,
00136                           int widt, int height,
00137                           orientation_t ori);
00138   static void apply_sharpen(unsigned char* src, unsigned char* dst,
00139                             int widt, int height);
00140   static void apply_median(unsigned char* src, unsigned char* dst,
00141                            int widt, int height, int i);
00142   static void apply_min(unsigned char* src, unsigned char* dst,
00143                         int widt, int height);
00144   static void apply_or(unsigned char* src1, unsigned char* src2,
00145                        unsigned char* dst, int widt, int height);
00146   static void make_contrast(unsigned char* buf, size_t buflen);
00147   static void make_grayscale(unsigned char* buf, size_t buflen);
00148   static MirrorCalibTool::MarkList premark(const StepResult& prev, const unsigned char* yuv_mask,
00149                           StepResult& result, PolarAngle phi,
00150                           const PixelPoint& center);
00151   static MirrorCalibTool::MarkList premark(const ConvexPolygon& polygon, const StepResult& prev,
00152                           const unsigned char* yuv_mask, StepResult& result,
00153                           PolarAngle phi, const PixelPoint& center);
00154   static HoleList search_holes(const MarkList& premarks);
00155   static HoleList filter_biggest_holes(const HoleList& holes, unsigned int n);
00156   static MarkList determine_marks(const HoleList& holes);
00157   static MarkList mark(const MarkList& premarks, const unsigned char* yuv_mask,
00158                        StepResult& result, PolarAngle phi,
00159                        const PixelPoint& center);
00160 
00161   static PixelPoint calculate_center(const ImageList& images);
00162   static RealDistance calculate_real_distance(int n);
00163   static PolarAnglePair find_nearest_neighbors(PolarAngle angle,
00164                                                const MarkMap& mark_map);
00165   static RealDistance interpolate(PolarRadius radius, const MarkList& marks);
00166   static Bulb generate(int width, int height,
00167                        const PixelPoint& center,
00168                        const MarkMap& mark_map);
00169 
00170   unsigned char*   img_yuv_buffer_;
00171   int              img_center_x_;
00172   int              img_center_y_;
00173   unsigned char*   img_yuv_mask_;
00174 
00175   ImageList        source_images_;
00176   CalibrationState state_;
00177   MarkList         premarks_;
00178   MarkMap          mark_map_; /** orientations wrt robot (i.e. Y axis) */
00179   
00180   const unsigned char* last_yuv_buffer_;
00181 
00182   Bulb* bulb_;
00183 };
00184 
00185 }
00186 
00187 #endif /*  __FIREVISION_MODELS_MIRROR_MIRROR_CALIB_H_ */
00188