#ifndef _OTB_TRISKELE_COMP_ATTRIBUTE_TPP #define _OTB_TRISKELE_COMP_ATTRIBUTE_TPP // ======================================== template inline vector CompAttribute::getScaledThresholds (const vector &thresholds, const AttrT &maxValue) { vector result; for (double percent : thresholds) result.push_back (percent*maxValue); return result; } template inline vector CompAttribute::getConvertedThresholds (const vector &thresholds) { vector result; for (double value : thresholds) result.push_back ((AttrT) value); return result; } // ======================================== template inline CompAttribute::CompAttribute (const Tree &tree, const bool &decr) : tree (tree), leafCount (0), values (), decr (decr) { updateTranscient (); } template inline CompAttribute::~CompAttribute () { } template inline void CompAttribute::updateTranscient () { // XXX max : leafCount-1 book (tree.getLeafCount ()); } template inline const AttrT * CompAttribute::getValues () const { return &values[0]; } template inline AttrT * CompAttribute::getValues () { return &values[0]; } template inline AttrT CompAttribute::getMaxValue () const { if (!leafCount) return 0; AttrT max = values[0]; CompAttribute::tree.forEachComp ([this, &max] (const DimImg &compId) { if (values[compId] > max) max = values[compId]; }); return max; } // ======================================== template template inline void CompAttribute::cut (vector > &allBands, const AttributeProfiles &attributeProfiles, const AttrT &pixelAttrValue, const vector &thresholds) const { DEF_LOG ("CompAttribute::cut", "coreCount:" << CompAttribute::tree.getCoreCount () << " thresholds:" << thresholds.size ()); dealThreadRange (CompAttribute::leafCount, CompAttribute::tree.getCoreCount (), [this, &allBands, &attributeProfiles, &pixelAttrValue, &thresholds] (const DimImg &leafId) { cutOnPos (allBands, attributeProfiles, leafId, pixelAttrValue, thresholds); }); } template template inline void CompAttribute::cutOnPos (vector > &allBands, const AttributeProfiles &attributeProfiles, const DimImg &leafId, const AttrT &pixelAttrValue, const vector &thresholds) const { // no debug (to many pixels) DimImg parentId = CompAttribute::tree.getLeafParent (leafId); DimChanel thresholdsSize = thresholds.size (); if (parentId == DimImg_MAX) { // border case for (DimChanel chanel = 0; chanel < thresholdsSize; ++chanel) allBands[chanel][leafId] = 0; return; } DimNodeId nodeId = leafId; DimImg curId = 0; AttrT curValue = pixelAttrValue; if (curValue == CompAttribute::values [parentId]) { // skip pixel on flat zone curId = parentId; nodeId = ((DimNodeId)curId)+CompAttribute::leafCount; parentId = CompAttribute::tree.getCompParent (curId); } const PixelT *apValues = attributeProfiles.getValues (); DimImg rootId = CompAttribute::tree.getCompRoot (); for (DimChanel chanel = 0; chanel < thresholdsSize; ++chanel) { AttrT ceil = thresholds[chanel]; for ( ; curId < rootId; ) { if (decr) { if (curValue < ceil) break; } else { if (curValue > ceil) break; } if (parentId == DimImg_MAX || curId >= parentId) { // cerr << "CompAttribute::cutOnPos find sub-root:" << rootId << " rootId:" << rootId << endl; // find root for (; chanel < thresholdsSize; ++chanel) allBands[chanel][leafId] = curValue; return; } nodeId = ((DimNodeId) CompAttribute::tree.getLeafParent (nodeId))+CompAttribute::leafCount; curId = parentId; curValue = CompAttribute::values [curId]; parentId = CompAttribute::tree.getCompParent (curId); } // XXX si valeur > root ? allBands[chanel][leafId] = apValues [nodeId]; } } // ======================================== template inline ostream & CompAttribute::print (ostream &out, const string &msg) const { cout << "values: " << msg << endl; const Size doubleSize (tree.getSize().width, 2*tree.getSize ().height); cout << printMap (&values[0], doubleSize, tree.getCompCount ()) << endl << endl; return out; } // ======================================== template inline void CompAttribute::free () { values = vector (); } template inline void CompAttribute::book (const DimImg &leafCount) { this->leafCount = leafCount; values.resize (leafCount); } // ======================================== template template inline void CompAttribute::computeSameCompLevel (const CumpFunctPSE &cumpFunctPSE) const { const vector &weightBounds (CompAttribute::tree.getWeightBounds ()); unsigned int coreCount = CompAttribute::tree.getCoreCount (); DEF_LOG ("CompAttribute::computeSameCompLevel", "coreCount:" << coreCount); if (!weightBounds.size () || CompAttribute::tree.getCompCount ()/weightBounds.size () < coreCount) { LOG ("CompAttribute::computeSameCompLevel: no thread"); CompAttribute::tree.forEachComp (cumpFunctPSE); return; } DimImg first = weightBounds [0]; for (DimImg curBound = 1; curBound < weightBounds.size (); curBound++) { DimImg next = weightBounds [curBound]; dealThreadRange (next-first, coreCount, [this, &first, &cumpFunctPSE] (const DimImg &id) { const DimImg parentId = id+first; cumpFunctPSE (parentId); }); first = next; } } // ======================================== #endif // _OTB_TRISKELE_COMP_ATTRIBUTE_TPP