#ifndef _OTB_TRISKELE_ARRAY_TREE_WEIGHT_HPP #define _OTB_TRISKELE_ARRAY_TREE_WEIGHT_HPP #include #include #include "triskeleBase.hpp" #include "triskeleArrayTreeBase.hpp" namespace otb { namespace triskele { namespace arrayTree { class GraphWalker; /*! Structure définissant la base d'un poids entre les pixels */ template struct WeightBase { protected: const PixelT *pixels; const Size size; DimNodeId pointIdx (const Point &p) const { return point2idx (size, p); } PixelT halfPixel, maxPixel; public: const Size &getSize () const { return size; } const PixelT &getValue (const DimImg &idx) const { return pixels[idx]; } const PixelT &getValue (const Point &p) const { return getValue (pointIdx (p)); } bool getDecr () const { return false; } const PixelT &getMaxPixel () const { return maxPixel; } const PixelT &getHalfPixel () const { return halfPixel; } PixelT *allocAP (const DimNodeId &nodeCapacity) const { return new PixelT [nodeCapacity]; } WeightBase (const PixelT *pixels, const Size &size) : pixels (pixels), size (size) { maxPixel = std::numeric_limits::max (); // only if unsigned halfPixel = maxPixel / 2; if (typeid (PixelT) != typeid (float)) halfPixel++; } }; template struct WeightBase2 : public WeightBase { typedef WeightBase WB; WeightBase2 (const PixelT *pixels, const Size &size) : WB (pixels, size) {} static bool isWeightInf (const WeightT &a, const WeightT &b) { return a < b; } static bool isEdgeInf (const Edge &a, const Edge &b) { return isWeightInf (a.weight, b.weight); } static void sort (Edge *edges, DimEdge count) { std::sort (edges, edges+count, isEdgeInf); } void copyPixelsBound (PixelT *leafAPTree, const DimImg &minVal, const DimImg &maxVal) const { for (DimImg i = minVal; i < maxVal; ++i) leafAPTree[i] = WB::pixels [i]; } void weight2valueBound (PixelT *compAPTree, const WeightT *compWeights, const DimImg &minVal, const DimImg &maxVal) const { //memcpy (compAPTree+minVal, compWeights+minVal, maxVal-minVal); for (DimImg compIdx = minVal; compIdx < maxVal; ++compIdx) compAPTree[compIdx] = compWeights[compIdx]; } }; /*! Structure intégrant la façon dont est géré un poids pour un MinTree */ template struct MinWeight : public WeightBase2 { typedef WeightBase2 WB; bool getDecr () const { return true; } static bool isWeightInf (const WeightT &a, const WeightT &b) { return a > b; } static bool isEdgeInf (const Edge &a, const Edge &b) { return isWeightInf (a.weight, b.weight); } static void sort (Edge *edges, DimEdge count) { std::sort (edges, edges+count, isEdgeInf); } MinWeight (const PixelT *pixels, const Size &size) : WB (pixels, size) {} WeightT getWeight (const DimImg &idx) const { return WB::getValue (idx); } WeightT getWeight (const Point &a, const Point &b) const { return std::min (getWeight (WB::pointIdx (a)), getWeight (WB::pointIdx (b))); } }; // ======================================== /*! Structure intégrant la façon dont est géré un poids pour un MaxTree */ template struct MaxWeight : public WeightBase2 { typedef WeightBase2 WB; MaxWeight (const PixelT *pixels, const Size &size) : WB (pixels, size) {} WeightT getWeight (const DimImg &idx) const { return WB::getValue (idx); } WeightT getWeight (const Point &a, const Point &b) const { return std::max (getWeight (WB::pointIdx (a)), getWeight (WB::pointIdx (b))); } }; // ======================================== /*! Structure intégrant la façon dont est géré un poids pour un AlphaTree */ template struct DiffWeight : public WeightBase2 { typedef WeightBase2 WB; DiffWeight (const PixelT *pixels, const Size &size) : WB (pixels, size) {} WeightT getWeight (const DimImg &idx) const { return 0; } WeightT getWeight (const Point &a, const Point &b) const { PixelT va = WB::getValue (a), vb = WB::getValue (b); return std::max (va, vb) - std::min (va, vb); } }; // ======================================== /*! Structure intégrant la façon dont est géré un poids pour un TreeOfShape */ template struct MedianWeight : public WeightBase2 { typedef WeightBase2 WB; protected: PixelT median, thresholdPixel; WeightT thresholdWeight; public: bool getDecr () const { return true; } static bool isWeightInf (const WeightT &a, const WeightT &b) { return a > b; } static bool isEdgeInf (const Edge &a, const Edge &b) { return isWeightInf (a.weight, b.weight); } static void sort (Edge *edges, DimEdge count) { std::sort (edges, edges+count, isEdgeInf); } const PixelT &getMedian () const { return median; } const PixelT &getThresholdPixel () const { return thresholdPixel; } const WeightT &getThresholdWeight () const { return thresholdWeight; } WeightT value2weight (const PixelT &val) const { if (median < WB::halfPixel) { if (val >= thresholdPixel) return val; return val < median ? (median-val)*2 - 1 : (val-median)*2; } if (val < thresholdPixel) return WB::maxPixel - val; return val < median ? (median-val)*2 - 1 : (val-median)*2; } PixelT weight2value (const WeightT &weight) const { if (median < WB::halfPixel) { if (weight >= thresholdWeight) return weight; return int (weight) % 2 ? median - 1 - weight/2 : median + weight/2; } if (weight > thresholdWeight) return WB::maxPixel - weight; return int (weight) % 2 ? median - weight/2 : median + weight/2; } inline MedianWeight (const PixelT *pixels, const GraphWalker &graphWalker); WeightT getWeight (const DimImg &idx) const { return value2weight (WB::getValue (idx)); } WeightT getWeight (const Point &a, const Point &b) const { return std::min (getWeight (WB::pointIdx (a)), getWeight (WB::pointIdx (b))); } void weight2valueBound (PixelT *compAPTree, const WeightT *compWeights, const DimImg &minVal, const DimImg &maxVal) const { for (DimImg compIdx = minVal; compIdx < maxVal; ++compIdx) compAPTree[compIdx] = weight2value (compWeights[compIdx]); } }; } // arrayTree } // triskele } // otb #include "GraphWalker.hpp" namespace otb { namespace triskele { namespace arrayTree { #include "Weight.tpp" } // arrayTree } // triskele } // otb #endif // _OTB_TRISKELE_ARRAY_TREE_WEIGHT_HPP