PICCANTE  0.4
The hottest HDR imaging library!
grow_cut.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_ALGORITHMS_GROW_CUT_HPP
19 #define PIC_ALGORITHMS_GROW_CUT_HPP
20 
21 #include "../base.hpp"
22 
23 #include "../image.hpp"
24 #include "../image_vec.hpp"
25 
26 #include "../util/std_util.hpp"
27 
28 #include "../filtering/filter_max.hpp"
29 #include "../filtering/filter_grow_cut.hpp"
30 #include "../filtering/filter_channel.hpp"
31 
32 namespace pic {
33 
34 class GrowCut
35 {
36 protected:
40 
41 public:
42 
47  {
48  state_next = NULL;
49  img_max = NULL;
50 
51  fltMax = new FilterMax(5);
52  }
53 
55  {
59  }
60 
69  static bool checkImage(Image *img, int width, int height, int channels)
70  {
71  return (img->channels != channels) ||
72  (img->width != width) ||
73  (img->height != height);
74  }
75 
82  static Image *fromStrokeImageToSeeds(Image *strokes, Image *out)
83  {
84  if(strokes == NULL) {
85  return out;
86  }
87 
88  if(strokes->channels < 3) {
89  return out;
90  }
91 
92  if(out == NULL) {
93  out = new Image(1, strokes->width, strokes->height, 1);
94  } else {
95  if(checkImage(out, strokes->width, strokes->height, 1)) {
96  out = new Image(1, strokes->width, strokes->height, 1);
97  }
98  }
99 
100  //red --> +1
101  //blue --> -1
102  float red[] = {1.0f, 0.0f, 0.0f};
103  float blue[] = {0.0f, 0.0f, 1.0f};
104 
105  for(int i = 0; i < strokes->nPixels(); i++) {
106  int ind = i * strokes->channels;
107 
108  float d_red = sqrtf(Arrayf::distanceSq(red, &strokes->data[ind], 3));
109  float d_blue = sqrtf(Arrayf::distanceSq(blue, &strokes->data[ind], 3));
110 
111  out->data[i] = 0.0f;
112 
113  out->data[i] = d_red < 0.5f ? 1.0f : out->data[i];
114  out->data[i] = d_blue < 0.5f ? -1.0f : out->data[i];
115  }
116 
117  return out;
118  }
119 
125  static Image* getMaskAsImage(Image *state, Image *out)
126  {
127  if(state == NULL) {
128  return out;
129  }
130 
131  if(out == NULL) {
132  out = new Image(1, state->width, state->height, 1);
133  }
134 
135  return FilterChannel::execute(state, out, 0);
136  }
137 
144  Image *Process(ImageVec imgIn, Image *imgOut)
145  {
146  if(!ImageVecCheck(imgIn, 2)) {
147  return imgOut;
148  }
149 
150  auto img = imgIn[0];
151  auto seeds = imgIn[1];
152 
153  if(imgOut == NULL) {
154  imgOut = new Image(img->width, img->height, 2);
155  } else {
156  if(checkImage(imgOut, img->width, img->height, 2)) {
157  imgOut = new Image(img->width, img->height, 2);
158  }
159  }
160 
161  auto state_cur = imgOut;
162 
163  if(state_next == NULL) {
164  state_next = state_cur->allocateSimilarOne();
165  } else {
166  if(checkImage(state_cur, img->width, img->height, 2)) {
167  state_next = state_cur->allocateSimilarOne();
168  }
169  }
170 
171  //compute max
172  img_max = fltMax->Process(Single(img), img_max);
173 
174  for(int i = 0; i < state_cur->nPixels(); i++) {
175  //init state_cur
176  int j = i * state_cur->channels;
177  int j_seeds = i * seeds->channels;
178  state_cur->data[j] = seeds->data[j_seeds];
179  state_cur->data[j + 1] = fabsf(seeds->data[j_seeds]) > 0.0f ? 1.0f : 0.0f;
180 
181  //fix max
182  j = i * img_max->channels;
184  }
185 
186  //iterative filtering...
187  int iterations = int(img->getDiagonalSize());
188 
189  if((iterations % 2) == 1) {
190  iterations++;
191  }
192 
193  ImageVec input = Triple(state_cur, img, img_max);
194  Image *output = state_next;
195 
196  for(int i = 0; i < iterations; i++) {
197  output = flt.Process(input, output);
198 
199  Image *tmp = input[0];
200  input[0] = output;
201  output = tmp;
202  }
203 
204  return imgOut;
205  }
206 
207  static Image *execute(Image *img, Image *seeds, Image *imgOut)
208  {
209  GrowCut gc;
210  return gc.Process(Double(img, seeds), imgOut);
211  }
212 };
213 
214 } // end namespace pic
215 
216 #endif /* PIC_ALGORITHMS_GROW_CUT_HPP */
217 
FilterMax * fltMax
Definition: grow_cut.hpp:38
PIC_INLINE bool ImageVecCheck(ImageVec &imgIn, int minInputImages)
ImageVecCheck.
Definition: image_vec.hpp:147
Image * state_next
Definition: grow_cut.hpp:39
GrowCut()
GrowCut.
Definition: grow_cut.hpp:46
int channels
Definition: filter_radial_basis_function.hpp:80
~GrowCut()
Definition: grow_cut.hpp:54
float * data
data is the main buffer where pixel values are stored.
Definition: image.hpp:91
int channels
Definition: image.hpp:80
T * delete_s(T *data)
delete_s
Definition: std_util.hpp:123
static Image * execute(Image *imgIn, Image *imgOut, int channel=0)
execute
Definition: filter_channel.hpp:131
std::vector< Image * > ImageVec
ImageVec an std::vector of pic::Image.
Definition: image_vec.hpp:29
virtual Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: filter.hpp:390
static T distanceSq(T *data0, T *data1, int n)
distanceSq
Definition: array.hpp:195
int nPixels() const
nPixels computes the number of pixels.
Definition: image.hpp:499
static Image * fromStrokeImageToSeeds(Image *strokes, Image *out)
fromStrokeImageToSeeds
Definition: grow_cut.hpp:82
PIC_INLINE ImageVec Double(Image *img1, Image *img2)
Double creates an std::vector which contains img1 and img2; this is for filters input.
Definition: image_vec.hpp:49
Image * img_max
Definition: grow_cut.hpp:39
Definition: grow_cut.hpp:34
static Image * getMaskAsImage(Image *state, Image *out)
getMaskAsImage
Definition: grow_cut.hpp:125
The FilterGrowCut class.
Definition: filter_grow_cut.hpp:29
FilterGrowCut flt
Definition: grow_cut.hpp:37
The FilterMax class.
Definition: filter_max.hpp:28
The Image class stores an image as buffer of float.
Definition: image.hpp:60
PIC_INLINE ImageVec Triple(Image *img1, Image *img2, Image *img3)
Triple creates an std::vector which contains img1, img2, and img3; this is for filters input...
Definition: image_vec.hpp:64
static Image * execute(Image *img, Image *seeds, Image *imgOut)
Definition: grow_cut.hpp:207
Image * allocateSimilarOne()
allocateSimilarOne creates an Image with similar size of the calling instance.
PIC_INLINE ImageVec Single(Image *img)
Single creates an std::vector which contains img; this is for filters input.
Definition: image_vec.hpp:36
Definition: bilateral_separation.hpp:25
Image * Process(ImageVec imgIn, Image *imgOut)
Process.
Definition: grow_cut.hpp:144
static T norm_sq(float *data, int n)
norm_sq
Definition: array.hpp:227
int width
Definition: image.hpp:80
int height
Definition: image.hpp:80
static bool checkImage(Image *img, int width, int height, int channels)
checkImage
Definition: grow_cut.hpp:69