SHOGUN  3.2.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LBPPyrDotFeatures.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010 Vojtech Franc, Soeren Sonnenburg
8  * Written (W) 2013 Evangelos Anagnostopoulos
9  * Copyright (C) 2010 Vojtech Franc, xfrancv@cmp.felk.cvut.cz
10  * Copyright (C) 2010 Berlin Institute of Technology
11  */
14 
15 using namespace shogun;
16 
17 #define LIBLBP_INDEX(ROW,COL,NUM_ROWS) ((COL)*(NUM_ROWS)+(ROW))
18 
20 {
21  init(NULL, 0, 0);
22  vec_nDim = 0;
23 }
24 
26  int32_t image_h, uint16_t num_pyramids) : CDotFeatures()
27 {
28  ASSERT(image_set)
29  init(image_set, image_w, image_h);
30  vec_nDim = liblbp_pyr_get_dim(num_pyramids);
31 }
32 
33 void CLBPPyrDotFeatures::init(CDenseFeatures<uint32_t>* image_set, int32_t image_w, int32_t image_h)
34 {
35  images = image_set;
36  SG_REF(images);
37  image_width = image_w;
38  image_height = image_h;
39 
40  SG_ADD((CSGObject**) &images, "images", "Set of images", MS_NOT_AVAILABLE);
41  SG_ADD(&image_width, "image_width", "The image width", MS_NOT_AVAILABLE);
42  SG_ADD(&image_height, "image_height", "The image height", MS_NOT_AVAILABLE);
43  SG_ADD(&vec_nDim, "vec_nDim", "The dimension of the pyr", MS_NOT_AVAILABLE);
44 }
45 
47 {
49 }
50 
52 {
53  init(orig.images, orig.image_width, orig.image_height);
54  vec_nDim = orig.vec_nDim;
55 }
56 
58 {
59  return vec_nDim;
60 }
61 
63 {
64  return vec_nDim;
65 }
66 
68 {
69  return F_UNKNOWN;
70 }
71 
73 {
74  return C_POLY;
75 }
76 
78 {
79  return images->get_num_vectors();
80 }
81 
82 void* CLBPPyrDotFeatures::get_feature_iterator(int32_t vector_index)
83 {
85  return NULL;
86 }
87 
88 bool CLBPPyrDotFeatures::get_next_feature(int32_t& index, float64_t& value, void* iterator)
89 {
91  return false;
92 }
93 
95 {
97 }
98 
99 float64_t CLBPPyrDotFeatures::dot(int32_t vec_idx1, CDotFeatures* df, int32_t vec_idx2)
100 {
101  ASSERT(strcmp(df->get_name(),get_name())==0)
102  CLBPPyrDotFeatures* lbp_feat = (CLBPPyrDotFeatures* ) df;
104 
105  SGVector<char> vec1 = get_transformed_image(vec_idx1);
106  SGVector<char> vec2 = lbp_feat->get_transformed_image(vec_idx2);
107 
108  return CMath::dot(vec1.vector, vec2.vector, vec_nDim);
109 }
110 
112 {
115 
116  int32_t ww;
117  int32_t hh;
118  uint32_t* img = get_image(index, ww, hh);
119 
120  int32_t offset = 0;
121  while (true)
122  {
123  for (int32_t x=1; x<ww-1; x++)
124  {
125  for (int32_t y=1; y<hh-1; y++)
126  {
127  uint8_t pattern = create_lbp_pattern(img, x, y);
128  vec[offset+pattern]++;
129  offset += 256;
130  }
131  }
132  if (vec_nDim <= offset)
133  break;
134 
135 
136  if (ww % 2 == 1)
137  ww--;
138  if (hh % 2 == 1)
139  hh--;
140 
141  ww = ww/2;
142  for (int32_t x=0; x<ww; x++)
143  for (int32_t j=0; j<hh; j++)
144  img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
145  img[LIBLBP_INDEX(j,2*x+1,image_height)];
146 
147  hh = hh/2;
148  for (int32_t y=0; y<hh; y++)
149  for (int32_t j=0; j<ww; j++)
150  img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
151  img[LIBLBP_INDEX(2*y+1,j,image_height)];
152  }
153 
154  SG_FREE(img);
155  return vec;
156 }
157 
158 uint32_t* CLBPPyrDotFeatures::get_image(int32_t index, int32_t& width, int32_t& height)
159 {
160  int32_t len;
161  bool do_free;
162  uint32_t* image = images->get_feature_vector(index, len, do_free);
163  uint32_t* img;
164  img = SG_MALLOC(uint32_t, len);
165  memcpy(img, image, len * sizeof(uint32_t));
166  images->free_feature_vector(image, index, do_free);
167  width = image_width;
168  height = image_height;
169  return img;
170 }
171 
172 float64_t CLBPPyrDotFeatures::dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
173 {
174  if (vec2_len != vec_nDim)
175  SG_ERROR("Dimensions don't match, vec2_dim=%d, vec_nDim=%d\n", vec2_len, vec_nDim)
176 
177  int32_t ww;
178  int32_t hh;
179  uint32_t* img = get_image(vec_idx1, ww, hh);
180 
181  float64_t dot_prod = 0;
182  int32_t offset = 0;
183  while (true)
184  {
185  for (int32_t x=1; x<ww-1; x++)
186  {
187  for (int32_t y=1; y<hh-1; y++)
188  {
189  uint8_t pattern = create_lbp_pattern(img, x, y);
190  dot_prod += vec2[offset+pattern];
191  offset += 256;
192  }
193  }
194  if (vec_nDim <= offset)
195  break;
196 
197 
198  if (ww % 2 == 1)
199  ww--;
200  if (hh % 2 == 1)
201  hh--;
202 
203  ww = ww/2;
204  for (int32_t x=0; x<ww; x++)
205  for (int32_t j=0; j<hh; j++)
206  img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
207  img[LIBLBP_INDEX(j,2*x+1,image_height)];
208 
209  hh = hh/2;
210  for (int32_t y=0; y<hh; y++)
211  for (int32_t j=0; j<ww; j++)
212  img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
213  img[LIBLBP_INDEX(2*y+1,j,image_height)];
214  }
215 
216  SG_FREE(img);
217  return dot_prod;
218 }
219 
220 void CLBPPyrDotFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
221 {
222  if (vec2_len != vec_nDim)
223  SG_ERROR("Dimensions don't match, vec2_dim=%d, vec_nDim=%d\n", vec2_len, vec_nDim)
224 
225  int32_t ww;
226  int32_t hh;
227  uint32_t* img = get_image(vec_idx1, ww, hh);
228 
229  if (abs_val)
230  alpha = CMath::abs(alpha);
231 
232  int32_t offset = 0;
233 
234  while (true)
235  {
236  for (int32_t x=1; x<ww-1; x++)
237  {
238  for (int32_t y=1; y<hh-1; y++)
239  {
240  uint8_t pattern = create_lbp_pattern(img, x, y);
241  vec2[offset+pattern] += alpha;
242  offset += 256;
243  }
244  }
245  if (vec_nDim <= offset)
246  break;
247 
248 
249  if (ww % 2 == 1)
250  ww--;
251  if (hh % 2 == 1)
252  hh--;
253 
254  ww = ww/2;
255  for (int32_t x=0; x<ww; x++)
256  for (int32_t j=0; j<hh; j++)
257  img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
258  img[LIBLBP_INDEX(j,2*x+1,image_height)];
259 
260  hh = hh/2;
261  for (int32_t y=0; y<hh; y++)
262  for (int32_t j=0; j<ww; j++)
263  img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
264  img[LIBLBP_INDEX(2*y+1,j,image_height)];
265  }
266  SG_FREE(img);
267 }
268 
269 uint8_t CLBPPyrDotFeatures::create_lbp_pattern(uint32_t* img, int32_t x, int32_t y)
270 {
271  uint8_t pattern = 0;
272  uint32_t center = img[LIBLBP_INDEX(y,x,image_height)];
273 
274  if (img[LIBLBP_INDEX(y-1,x-1,image_height)] < center)
275  pattern |= 0x01;
276  if (img[LIBLBP_INDEX(y-1,x,image_height)] < center)
277  pattern |= 0x02;
278  if (img[LIBLBP_INDEX(y-1,x+1,image_height)] < center)
279  pattern |= 0x04;
280  if (img[LIBLBP_INDEX(y,x-1,image_height)] < center)
281  pattern |= 0x08;
282  if (img[LIBLBP_INDEX(y,x+1,image_height)] < center)
283  pattern |= 0x10;
284  if (img[LIBLBP_INDEX(y+1,x-1,image_height)] < center)
285  pattern |= 0x20;
286  if (img[LIBLBP_INDEX(y+1,x,image_height)] < center)
287  pattern |= 0x40;
288  if (img[LIBLBP_INDEX(y+1,x+1,image_height)] < center)
289  pattern |= 0x80;
290 
291  return pattern;
292 }
293 
295 {
296  return new CLBPPyrDotFeatures(*this);
297 }
298 
299 uint32_t CLBPPyrDotFeatures::liblbp_pyr_get_dim(uint16_t nPyramids)
300 {
301  uint32_t N = 0;
302  uint32_t w = image_width;
303  uint32_t h = image_height;
304 
305  for (uint32_t i=0; (i<nPyramids) && (CMath::min(w,h)>=3); i++)
306  {
307  N += (w-2)*(h-2);
308 
309  if (w % 2)
310  w--;
311  if (h % 2)
312  h--;
313 
314  w = w/2;
315  h = h/2;
316  }
317  return 256*N;
318 }

SHOGUN Machine Learning Toolbox - Documentation