PICCANTE  0.4
The hottest HDR imaging library!
mask.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_UTIL_MASK_HPP
19 #define PIC_UTIL_MASK_HPP
20 
21 #include "../base.hpp"
22 #include "../util/math.hpp"
23 #include "../util/buffer.hpp"
24 
25 namespace pic {
26 
27 class Mask: public Buffer<bool>
28 {
29 public:
38  static bool *removeIsolatedPixels(bool *dataOut, bool *dataIn,
39  int width, int height)
40  {
41  if(dataIn == NULL) {
42  return dataOut;
43  }
44 
45  if(dataOut == NULL) {
46  dataOut = new bool[width * height];
47  }
48 
49  #pragma omp parallel for
50 
51  for(int i = 0; i < height; i++) {
52  int ind = i * width;
53 
54  for(int j = 0; j < width; j++) {
55  int c = ind + j;
56 
57  int counter = 0;
58 
59  for(int k = -1; k <= 1; k++) {
60  int ci = CLAMP((i + k), height) * width;
61 
62  for(int l = -1; l <= 1; l++) {
63  if((l != 0) && (k != 0)) {
64  int cj = CLAMP((j + l), width);
65 
66  if(dataIn[ci + cj]) {
67  counter++;
68  }
69  }
70  }
71  }
72 
73  dataOut[c] = counter > 0;
74  }
75  }
76 
77  return dataOut;
78  }
79 
89  static bool *erode(bool *dataOut, bool *dataIn, int width, int height,
90  int kernelSize = 3)
91  {
92  if(dataIn == NULL) {
93  return dataOut;
94  }
95 
96  if(dataOut == NULL) {
97  dataOut = new bool[width * height];
98  }
99 
100  int halfKernelSize = kernelSize >> 1;
101 
102  #pragma omp parallel for
103 
104  for(int i = 0; i < height; i++) {
105  int ind = i * width;
106 
107  for(int j = 0; j < width; j++) {
108  int c = ind + j;
109 
110  bool out = false;
111 
112  for(int k = -halfKernelSize; k <= halfKernelSize; k++) {
113  int ci = CLAMP((i + k), height) * width;
114 
115  for(int l = -halfKernelSize; l <= halfKernelSize; l++) {
116  int cj = CLAMP((j + l), width);
117  out = out || (!dataIn[ci + cj]);
118  }
119  }
120 
121  dataOut[c] = !out;
122  }
123  }
124 
125  return dataOut;
126  }
127 
137  static bool *dilate(bool *dataOut, bool *dataIn, int width, int height,
138  int kernelSize = 3)
139  {
140  if(dataIn == NULL) {
141  return dataOut;
142  }
143 
144  if(dataOut == NULL) {
145  dataOut = new bool[width * height];
146  }
147 
148  int halfKernelSize = kernelSize >> 1;
149 
150  #pragma omp parallel for
151 
152  for(int i = 0; i < height; i++) {
153  int ind = i * width;
154 
155  for(int j = 0; j < width; j++) {
156  int c = ind + j;
157 
158  bool out = false;
159 
160  for(int k = -halfKernelSize; k <= halfKernelSize; k++) {
161  int ci = CLAMP((i + k), height) * width;
162 
163  for(int l = -halfKernelSize; l <= halfKernelSize; l++) {
164  int cj = CLAMP((j + l), width);
165  out = out || (dataIn[ci + cj]);
166  }
167  }
168 
169  dataOut[c] = out;
170  }
171  }
172 
173  return dataOut;
174  }
175 
183  static bool empty(bool *dataIn, int width, int height)
184  {
185  if(dataIn == NULL) {
186  return true;
187  }
188 
189  for(int i = 0; i < height; i++) {
190  int ind = i * width;
191 
192  for(int j = 0; j < width; j++) {
193  if(dataIn[ind + j]) {
194  return false;
195  }
196  }
197  }
198 
199  return true;
200  }
201 
209  static bool* thinning(bool *dataOut, bool *dataIn, int width, int height)
210  {
211  if(dataIn == NULL) {
212  return dataIn;
213  }
214 
215  dataOut = clone(dataOut, dataIn, width * height, 1);
216 
217  bool P[9];
218 
219  //first-pass
220  std::vector< int > list;
221  for(int i = 1; i < (height - 1); i++) {
222  int tmp = i * width;
223  for(int j = 1; j < (width - 1); j++) {
224  int index = tmp + j;
225 
226  if(!dataOut[index]) {
227  continue;
228  }
229 
230  P[0] = dataOut[index];
231  P[1] = dataOut[index + 1];
232  P[2] = dataOut[index - width + 1];
233  P[3] = dataOut[index - width];
234  P[4] = dataOut[index - width - 1];
235  P[5] = dataOut[index - 1];
236  P[6] = dataOut[index + width - 1];
237  P[7] = dataOut[index + width];
238  P[8] = dataOut[index + width + 1];
239 
240  int X_h = 0;
241  int n1 = 0;
242  int n2 = 0;
243  for(int k = 1; k <= 4; k++) {
244  int k_2 = k << 1;
245  bool x_2km1 = P[k_2 - 1];
246  bool x_2k = P[k_2 ];
247  bool x_2kp1 = P[k_2 + 1];
248 
249  if( !x_2km1 && (x_2k || x_2kp1) ) {
250  X_h++;
251  }
252 
253  if(x_2km1 || x_2k) {
254  n1++;
255  }
256 
257  if(x_2k || x_2kp1) {
258  n2++;
259  }
260  }
261 
262  int min_12 = MIN(n1, n2);
263 
264  bool G1 = (X_h == 1);
265  bool G2 = (min_12 > 1) && (min_12 < 4);
266  bool G3 = P[1] && ( P[2] || P[3] || !P[8]);
267 
268  if(G1 && G2 && G3) {
269  list.push_back(index);
270  }
271 
272  }
273  }
274 
275  for(unsigned int i = 0; i < list.size(); i++) {
276  dataOut[list[i]] = false;
277  }
278 
279  list.clear();
280 
281  for(int i = 1; i < (height - 1); i++) {
282  int tmp = i * width;
283  for(int j = 1; j < (width - 1); j++) {
284  int index = tmp + j;
285 
286  if(!dataOut[index]) {
287  continue;
288  }
289 
290  P[0] = dataOut[index];
291  P[1] = dataOut[index + 1];
292  P[2] = dataOut[index - width + 1];
293  P[3] = dataOut[index - width];
294  P[4] = dataOut[index - width - 1];
295  P[5] = dataOut[index - 1];
296  P[6] = dataOut[index + width - 1];
297  P[7] = dataOut[index + width];
298  P[8] = dataOut[index + width + 1];
299 
300  int X_h = 0;
301  int n1 = 0;
302  int n2 = 0;
303  for(int k = 1; k <= 4; k++) {
304  int k_2 = k << 1;
305  bool x_2km1 = P[k_2 - 1];
306  bool x_2k = P[k_2 ];
307  bool x_2kp1 = P[k_2 + 1];
308 
309  if( !x_2km1 && (x_2k || x_2kp1) ) {
310  X_h++;
311  }
312 
313  if(x_2km1 || x_2k) {
314  n1++;
315  }
316 
317  if(x_2k || x_2kp1) {
318  n2++;
319  }
320  }
321 
322  int min_12 = MIN(n1, n2);
323 
324  bool G1 = (X_h == 1);
325  bool G2 = (min_12 > 1) && (min_12 < 4);
326  bool G3 = P[5] && (P[6] || P[7] || !P[4]);
327 
328  if(G1 && G2 && G3) {
329  list.push_back(index);
330  }
331 
332  }
333  }
334 
335  for(unsigned int i = 0; i < list.size(); i++) {
336  dataOut[list[i]] = false;
337  }
338 
339  return dataOut;
340  }
341 };
342 
343 } // end namespace pic
344 
345 #endif /* PIC_UTIL_MASK_HPP */
static bool * clone(bool *bufferOut, bool *bufferIn, int n, int channels)
clone
Definition: filter_radial_basis_function.hpp:704
Definition: buffer.hpp:30
static bool * erode(bool *dataOut, bool *dataIn, int width, int height, int kernelSize=3)
erode erodes a mask.
Definition: mask.hpp:89
static bool empty(bool *dataIn, int width, int height)
MaskEmpty checks if a mask is empty.
Definition: mask.hpp:183
#define MIN(a, b)
Definition: math.hpp:69
Definition: mask.hpp:27
static bool * dilate(bool *dataOut, bool *dataIn, int width, int height, int kernelSize=3)
MaskDilate dilates a mask.
Definition: mask.hpp:137
Definition: bilateral_separation.hpp:25
#define CLAMP(x, a)
Definition: math.hpp:77
static bool * removeIsolatedPixels(bool *dataOut, bool *dataIn, int width, int height)
removeIsolatedPixels removes isolated pixels.
Definition: mask.hpp:38
static bool * thinning(bool *dataOut, bool *dataIn, int width, int height)
thinning thins a mask.
Definition: mask.hpp:209