00001
00002
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _PANODATA_MASK_H
00028 #define _PANODATA_MASK_H
00029
00030 #include <hugin_shared.h>
00031 #include "hugin_utils/utils.h"
00032 #include "hugin_math/hugin_math.h"
00033
00034 namespace HuginBase
00035 {
00036 namespace PTools { class Transform; }
00037
00038 using namespace hugin_utils;
00039
00041 typedef std::vector<FDiff2D> VectorPolygon;
00042
00046 const int maskOffset=100;
00047
00054 class IMPEX MaskPolygon
00055 {
00056 public:
00058 enum MaskType
00059 {
00060 Mask_negative=0,
00061 Mask_positive=1,
00062 Mask_Stack_negative=2,
00063 Mask_Stack_positive=3,
00064 Mask_negative_lens=4
00065 };
00067 MaskPolygon() : m_maskType(Mask_negative), m_imgNr(0), m_invert(false) {};
00069 bool isInside(const FDiff2D p) const;
00071 int getWindingNumber(const FDiff2D p) const;
00073 int getTotalWindingNumber() const;
00074
00075
00077 MaskType getMaskType() const { return m_maskType; };
00079 void setMaskType(const MaskType newType) { m_maskType=newType; };
00081 bool isPositive() const;
00083 VectorPolygon getMaskPolygon() const { return m_polygon; };
00085 void setMaskPolygon(const VectorPolygon newMask);
00087 unsigned int getImgNr() const { return m_imgNr; };
00089 void setImgNr(const unsigned int newImgNr) { m_imgNr=newImgNr; };
00091 void setInverted(const bool inverted) { m_invert = inverted; };
00093 bool isInverted() const { return m_invert; };
00094
00095
00097 void addPoint(const FDiff2D p);
00099 void insertPoint(const unsigned int index, const FDiff2D p);
00101 void removePoint(const unsigned int index);
00103 void movePointTo(const unsigned int index, const FDiff2D p);
00105 void movePointBy(const unsigned int index, const FDiff2D diff);
00107 void scale(const double factorx, const double factory);
00109 void scale(const double factor) { scale(factor,factor);} ;
00111 void transformPolygon(const PTools::Transform &trans);
00113 bool clipPolygon(const vigra::Rect2D rect);
00115 bool clipPolygon(const FDiff2D center, const double radius);
00117 void rotate90(bool clockwise,unsigned int maskWidth,unsigned int maskHeight);
00119 void subSample(const double max_distance);
00120
00122 unsigned int FindPointNearPos(const FDiff2D p, const double tol);
00123
00124
00126 MaskPolygon &operator=(const MaskPolygon otherPoly);
00128 const bool operator==(const MaskPolygon &otherPoly) const;
00129
00130
00132 bool parsePolygonString(const std::string polygonStr);
00136 void printPolygonLine(std::ostream & o, const unsigned int newImgNr) const;
00137
00138 private:
00140 void calcBoundingBox();
00141
00142 MaskType m_maskType;
00143 VectorPolygon m_polygon;
00144 unsigned int m_imgNr;
00145 bool m_invert;
00146 vigra::Rect2D m_boundingBox;
00147 };
00148
00149 typedef std::vector<MaskPolygon> MaskPolygonVector;
00150
00152 IMPEX void LoadMaskFromStream(std::istream& stream, vigra::Size2D& imageSize, MaskPolygonVector &newMasks, size_t imgNr);
00154 IMPEX void SaveMaskToStream(std::ostream& stream, vigra::Size2D imageSize, MaskPolygon &maskToWrite, size_t imgNr);
00155
00156 };
00157
00158 namespace vigra_ext
00159 {
00160
00161 template <class SrcImageIterator, class SrcAccessor>
00162 void applyMask(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img, HuginBase::MaskPolygonVector masks)
00163 {
00164 vigra::Diff2D imgSize = img.second - img.first;
00165
00166 if(masks.size()<1)
00167 return;
00168
00169 SrcImageIterator yd(img.first);
00170
00171 for(int y=0; y < imgSize.y; ++y, ++yd.y)
00172 {
00173
00174 SrcImageIterator xd(yd);
00175 for(int x=0; x < imgSize.x; ++x, ++xd.x)
00176 {
00177 HuginBase::FDiff2D newPoint(x,y);
00178 bool insideMasks=false;
00179 unsigned int i=0;
00180 while(!insideMasks && (i<masks.size()))
00181 {
00182 insideMasks=masks[i].isInside(newPoint);
00183 i++;
00184 };
00185 if(insideMasks)
00186 *xd=0;
00187 }
00188 }
00189 }
00190
00191 }
00192 #endif // _PANODATA_MASK_H