FlexBox - A Flexible Primal-Dual ToolBox
flexSuperpixelOperator.h
1 #ifndef flexSuperpixelOperator_H
2 #define flexSuperpixelOperator_H
3 
4 #include <vector>
5 #include "flexLinearOperator.h"
6 
8 
11 template<typename T>
13 {
14 
15 #ifdef __CUDACC__
16  typedef thrust::device_vector<T> Tdata;
17 #else
18  typedef std::vector<T> Tdata;
19 #endif
20 
21 private:
22  std::vector<int> targetDimension;
23  T upsamplingFactor;
24 public:
25 
27 
32  flexSuperpixelOperator(std::vector<int> aTargetDimension, T aUpsamplingFactor, bool aMinus) : flexLinearOperator<T>((int)(vectorProduct(aTargetDimension)), (int)(vectorProduct(aTargetDimension)*aUpsamplingFactor*aUpsamplingFactor), superpixelOp, aMinus)
33  {
34  this->targetDimension.resize(aTargetDimension.size());
35  this->targetDimension = aTargetDimension;
36  this->upsamplingFactor = aUpsamplingFactor;
37  };
38 
40  {
41  return new flexSuperpixelOperator<T>(this->targetDimension, this->upsamplingFactor, this->isMinus);
42  }
43 
44 
45 
46  //to implement
47  void times(bool transposed, const Tdata &input, Tdata &output)
48  {
49 
50  }
51 
52  void timesPlus(bool transposed, const Tdata &input, Tdata &output)
53  {
54  if (this->isMinus)
55  {
56  doTimes(transposed,input,output, MINUS);
57  }
58  else
59  {
60  doTimes(transposed,input,output, PLUS);
61  }
62  }
63 
64  void timesMinus(bool transposed, const Tdata &input, Tdata &output)
65  {
66  if (this->isMinus)
67  {
68  doTimes(transposed,input,output, PLUS);
69  }
70  else
71  {
72  doTimes(transposed,input,output, MINUS);
73  }
74  }
75 
76  std::vector<T> getAbsRowSum(bool transposed)
77  {
78  if (transposed)
79  {
80  return std::vector<T>(this->getNumCols(), (T)1 / (T)(this->upsamplingFactor*this->upsamplingFactor));
81  }
82  else
83  {
84  return std::vector<T>(this->getNumRows(), (T)1);
85  }
86  }
87 
88  T getMaxRowSumAbs(bool transposed)
89  {
90  if (transposed)
91  {
92  return (T)1 / (T)(this->upsamplingFactor*this->upsamplingFactor);
93  }
94  else
95  {
96  return (T)1;
97  }
98  }
99 
100  #ifdef __CUDACC__
101  thrust::device_vector<T> getAbsRowSumCUDA(bool transposed)
102  {
103  Tdata result(this->getNumRows(),(T)1);
104 
105  return result;
106  }
107  #endif
108 
109  private:
110  int indexI(int index, int sizeX)
111  {
112  return index % sizeX;
113  }
114 
115  int indexJ(int index, int sizeX, int sizeY)
116  {
117  return (index / sizeX) % sizeY;
118  }
119 
120  int index2DtoLinear(int i, int j, int sizeY)
121  {
122  return (i*sizeY + j);
123  }
124 
125  void calcTimes(const Tdata &input, Tdata &output, mySign signRule)
126  {
127 
128  T factor = (T)1 / (this->upsamplingFactor*this->upsamplingFactor);
129 
130  int iOuterEnd = targetDimension[0];
131  int jOuterEnd = targetDimension[1];
132 
133  int sizeY = targetDimension[1] * (int)this->upsamplingFactor;
134 
135  #pragma omp parallel for
136  for (int i = 0; i < iOuterEnd; ++i)
137  {
138  for (int j = 0; j < jOuterEnd; ++j)
139  {
140  //printf("Output: (%d,%d) : %d\n", i, j, index2DtoLinear(i, j, this->targetDimension[1]));
141 
142  int outputIndex = index2DtoLinear(i, j, targetDimension[1]);
143 
144  int iInnerStart = i*(int)this->upsamplingFactor;
145  int iInnerEnd = (i + 1)*(int)this->upsamplingFactor;
146 
147  int jInnerStart = j*(int)this->upsamplingFactor;
148  int jInnerEnd = (j + 1)*(int)this->upsamplingFactor;
149 
150  T tmpResult = (T)0;
151 
152  for (int iInner = iInnerStart; iInner < iInnerEnd; ++iInner)
153  {
154  for (int jInner = jInnerStart; jInner < jInnerEnd; ++jInner)
155  {
156  int inputIndex = index2DtoLinear(iInner, jInner, sizeY);
157 
158  tmpResult += input[inputIndex];
159  /*printf("Inner: (%d,%d) : %d\n", iInner, jInner, inputIndex);
160 
161  int innerJ = indexI(inputIndex, this->targetDimension[0] * this->upsamplingFactor);
162  int innerI = indexJ(inputIndex, this->targetDimension[0] * this->upsamplingFactor, this->targetDimension[1] * this->upsamplingFactor);
163 
164  printf("Back: (%d,%d) \n", innerI, innerJ);
165 
166  int backI = innerI / this->upsamplingFactor;
167  int backJ = innerJ / this->upsamplingFactor;
168 
169  printf("BackInner: (%d,%d) \n", backI, backJ);
170 
171  if (backI != i || backJ != j)
172  {
173  mexErrMsgTxt("PROBLEM!!!\n");
174  }*/
175  }
176  }
177 
178  switch (signRule)
179  {
180  case PLUS:
181  {
182  output[outputIndex] += factor*tmpResult;
183  break;
184  }
185  case MINUS:
186  {
187  output[outputIndex] -= factor*tmpResult;
188  break;
189  }
190  case EQUALS:
191  {
192  output[outputIndex] = factor*tmpResult;
193  break;
194  }
195  }
196  }
197  }
198  }
199 
200  void calcTimesTransposed(const Tdata &input, Tdata &output, mySign signRule)
201  {
202  T factor = (T)1 / (this->upsamplingFactor*this->upsamplingFactor);
203 
204  int sizeX = targetDimension[0] * (int)this->upsamplingFactor;
205  int sizeY = targetDimension[1] * (int)this->upsamplingFactor;
206 
207  #pragma omp parallel for
208  for (int i = 0; i < sizeX; ++i)
209  {
210  for (int j = 0; j < sizeY; ++j)
211  {
212  int inputIndex = index2DtoLinear(i, j, sizeY);
213 
214  //int innerJ = indexI(inputIndex, this->targetDimension[0] * this->upsamplingFactor);
215  //int innerI = indexJ(inputIndex, this->targetDimension[0] * this->upsamplingFactor, this->targetDimension[1] * this->upsamplingFactor);
216 
217  //printf("Back: (%d,%d) \n", innerI, innerJ);
218 
219  int backI = i / (int)this->upsamplingFactor;
220  int backJ = j / (int)this->upsamplingFactor;
221 
222 
223  int outputIndex = index2DtoLinear(backI, backJ, targetDimension[1]);
224 
225  //printf("Back: (%d,%d) %d,%d \n", backI, backJ, inputIndex, outputIndex);
226 
227  switch (signRule)
228  {
229  case PLUS:
230  {
231  output[inputIndex] += factor*input[outputIndex];
232  break;
233  }
234  case MINUS:
235  {
236  output[inputIndex] -= factor*input[outputIndex];
237  break;
238  }
239  case EQUALS:
240  {
241  output[inputIndex] = factor*input[outputIndex];
242  break;
243  }
244  }
245  }
246  }
247  }
248 
249  void doTimes(bool transposed, const Tdata &input, Tdata &output, mySign signRule)
250  {
251  if (transposed)
252  {
253  calcTimesTransposed(input, output, signRule);
254  }
255  else
256  {
257  calcTimes(input, output, signRule);
258  }
259  }
260 };
261 
262 #endif
flexSuperpixelOperator(std::vector< int > aTargetDimension, T aUpsamplingFactor, bool aMinus)
initializes the superpixel operator. Downsamples image of size aUpsamplingFactor * aTargetDimension t...
Definition: flexSuperpixelOperator.h:32
int getNumRows() const
returns number of rows of the linear operator
Definition: flexLinearOperator.h:57
void timesMinus(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector and substracts its result from y
Definition: flexSuperpixelOperator.h:64
flexSuperpixelOperator< T > * copy()
copies the linear operator
Definition: flexSuperpixelOperator.h:39
bool isMinus
determines if operator is negated
Definition: flexLinearOperator.h:25
int getNumCols() const
returns number of columns of the linear operator
Definition: flexLinearOperator.h:48
thrust::device_vector< T > getAbsRowSumCUDA(bool transposed)
same function as getAbsRowSum() but implemented in CUDA
Definition: flexSuperpixelOperator.h:101
std::vector< T > getAbsRowSum(bool transposed)
returns a vector of sum of absolute values per row used for preconditioning
Definition: flexSuperpixelOperator.h:76
mySign
enum representing the type of concatenation
Definition: tools.h:56
void times(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector
Definition: flexSuperpixelOperator.h:47
void timesPlus(bool transposed, const Tdata &input, Tdata &output)
applies linear operator on vector and adds its result to y
Definition: flexSuperpixelOperator.h:52
abstract base class for linear operators
Definition: flexLinearOperator.h:12
T getMaxRowSumAbs(bool transposed)
returns the maximum sum of absolute values per row used for preconditioning
Definition: flexSuperpixelOperator.h:88
represents a superpixel operator
Definition: flexSuperpixelOperator.h:12