00001 #ifndef Impala_Core_Array_Trait_QbWatershedMarkers2_h
00002 #define Impala_Core_Array_Trait_QbWatershedMarkers2_h
00003
00004 #include "Core/Geometry/PointZ.h"
00005 #include "Core/Array/Pattern/FcvArray.h"
00006 #include "Core/Array/Pattern/QCollection.h"
00007 #include "Core/Array/Arrays.h"
00008 #include "Core/Array/Pattern/Array2D.h"
00009 #include "Core/Array/Element/E1Norm1.h"
00010
00011 namespace Impala
00012 {
00013 namespace Core
00014 {
00015 namespace Array
00016 {
00017 namespace Trait
00018 {
00019
00020
00021 template<class DstArrayT, class Src1ArrayT, class Src2ArrayT>
00022 class QbWatershedMarkers2 {
00023
00024 typedef typename DstArrayT::ArithType DstArithT;
00025 typedef typename Src1ArrayT::ArithType Src1ArithT;
00026 typedef typename Src2ArrayT::ArithType Src2ArithT;
00027
00028 public:
00029 typedef struct structPointValue {
00030 DstArithT arith;
00031 Src1ArithT img;
00032 Src2ArithT mask;
00033 Geometry::PointZ point;
00034 int cost;
00035
00036 bool
00037 less(const struct structPointValue& rhs) const
00038 {
00039 if (cost<rhs.cost)
00040 return true;
00041 if (cost>rhs.cost)
00042 return false;
00043
00044 return localOrderCounter<rhs.localOrderCounter;
00045 }
00046
00047 bool
00048 operator < (const struct structPointValue& rhs) const
00049 {
00050
00051 return less(rhs);
00052 }
00053
00054 unsigned localOrderCounter;
00055 } PointValueT;
00056
00057
00058 typedef Pattern::Qset<PointValueT> QT;
00059
00060 typedef struct {
00061 Geometry::PointZ point;
00062 DstArithT arith;
00063 Src1ArithT img;
00064 Src2ArithT mask;
00065 } NeighborsT;
00066
00067 typedef Pattern::FcvArray<NeighborsT> VecNeighborsT;
00068
00069 QbWatershedMarkers2(int width, int height, bool doLabelMask, int costMethod)
00070 : flagImage(width, height, false), costImage(width, height, INT_MAX)
00071 {
00072 labelcode=0;
00073 doLabel = doLabelMask;
00074 costmethod=costMethod;
00075 globalOrderCounter=0;
00076 }
00077
00078 ~QbWatershedMarkers2()
00079 {
00080 }
00081
00082 bool
00083 WantAnotherLoop()
00084 {
00085 return false;
00086 }
00087
00088 bool
00089 WantFreshStartLocalPixelInit()
00090 {
00091 return true;
00092 }
00093
00094 bool
00095 LocalPixelInit(PointValueT& vp, DstArithT&, Src1ArithT, Src2ArithT, bool& continueloop)
00096 {
00097 continueloop=false;
00098 return false;
00099 }
00100
00101 bool
00102 GlobalPixelInit(PointValueT& vp, DstArithT& arith, Src1ArithT img, Src2ArithT mask)
00103 {
00104 vp.arith=arith;
00105 vp.img=img;
00106 vp.mask=mask;
00107 bool q;
00108 if (vp.mask!=0) {
00109 q=true;
00110 costImage(vp.point.mX, vp.point.mY)=0;
00111 if (doLabel) {
00112 labelcode++;
00113 vp.arith=labelcode;
00114 } else {
00115 vp.arith=vp.mask;
00116 }
00117 } else {
00118 vp.arith=0;
00119 q=false;
00120 }
00121 if (q) {
00122 vp.localOrderCounter=globalOrderCounter++;
00123
00124 vp.cost=costImage(vp.point.mX, vp.point.mY);
00125 }
00126 arith=vp.arith;
00127 return q;
00128 }
00129
00130 void
00131 First(const PointValueT& val, DstArithT, Src1ArithT, Src2ArithT)
00132 {
00133 center=val;
00134 flagImage(val.point.mX, val.point.mY)=true;
00135 }
00136
00137 Pattern::QAction
00138 Result()
00139 {
00140 if (index>=neighboursout.size())
00141 return Pattern::STOP;
00142 resultVP=neighboursout[index];
00143 Pattern::QAction action=actionsout[index];
00144 index++;
00145 return action;
00146 }
00147
00148 void
00149 GetItemToQueue(PointValueT &vp)
00150 {
00151 vp=resultVP;
00152 }
00153
00154
00155
00156 void
00157 GetItemToRemove(PointValueT& lower, PointValueT& upper)
00158 {
00159 lower.cost=upper.cost=resultVP.cost;
00160 lower.localOrderCounter=0;
00161 upper.localOrderCounter=4000000000;
00162 }
00163
00164 bool
00165 KillThisOne(const PointValueT& vp)
00166 {
00167 if (resultVP.cost==vp.cost && resultVP.point==vp.point)
00168 return true;
00169 return false;
00170 }
00171
00172 void
00173 GetItemToWrite(Geometry::PointZ& point, DstArithT& arith)
00174 {
00175 point=resultVP.point;
00176 arith=resultVP.arith;
00177 }
00178
00179 void
00180 Calculate(VecNeighborsT& vecneighbors)
00181 {
00182 index=0;
00183 neighboursout.clear();
00184 actionsout.clear();
00185 for (int i=0; i<vecneighbors.size(); i++) {
00186 NeighborsT val=vecneighbors[i];
00187 PointValueT neighbor;
00188 neighbor.point=val.point;
00189 neighbor.arith=val.arith;
00190 neighbor.img=val.img;
00191 neighbor.mask=val.mask;
00192 if (flagImage(neighbor.point.mX, neighbor.point.mY)==false) {
00193 int c=costImage(center.point.mX, center.point.mY);
00194 int f=costImage(neighbor.point.mX, neighbor.point.mY);
00195 int w;
00196 if (costmethod==0) {
00197 w=neighbor.img;
00198 } else if (costmethod==1) {
00199 w=Element::E1Norm1(center.img-neighbor.img);
00200 }
00201
00202
00203 int maxval=(c>w?c:w);
00204 if (maxval<f) {
00205
00206
00207 neighbor.cost=costImage(neighbor.point.mX, neighbor.point.mY);
00208 neighbor.localOrderCounter=0;
00209 neighboursout.push_back(neighbor);
00210 actionsout.push_back(Pattern::REMOVE);
00211
00212
00213
00214 neighbor.arith=center.arith;
00215 costImage(neighbor.point.mX, neighbor.point.mY)=maxval;
00216 neighbor.localOrderCounter=globalOrderCounter++;
00217
00218 neighbor.cost=maxval;
00219 neighboursout.push_back(neighbor);
00220 actionsout.push_back(Pattern::WRITE);
00221 neighboursout.push_back(neighbor);
00222 actionsout.push_back(Pattern::QUEUE);
00223 }
00224 }
00225 }
00226 }
00227
00228 private:
00229 PointValueT center;
00230 Pattern::FcvArray<PointValueT> neighboursout;
00231 Pattern::FcvArray<Pattern::QAction> actionsout;
00232 int index;
00233 int labelcode;
00234 bool doLabel;
00235 int costmethod;
00236 PointValueT resultVP;
00237 unsigned globalOrderCounter;
00238 Pattern::Array2D<bool> flagImage;
00239 Pattern::Array2D<int> costImage;
00240
00241 };
00242
00243 }
00244 }
00245 }
00246 }
00247
00248 #endif