SHOGUN  v3.0.0
 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  */
13 
14 using namespace shogun;
15 
16 #define LIBLBP_INDEX(ROW,COL,NUM_ROWS) ((COL)*(NUM_ROWS)+(ROW))
17 
19 {
20  init(NULL, 0, 0);
21  vec_nDim = 0;
22 }
23 
25  int32_t image_h, uint16_t num_pyramids) : CDotFeatures()
26 {
27  ASSERT(image_set)
28  init(image_set, image_w, image_h);
29  vec_nDim = liblbp_pyr_get_dim(num_pyramids);
30 }
31 
32 void CLBPPyrDotFeatures::init(CDenseFeatures<uint32_t>* image_set, int32_t image_w, int32_t image_h)
33 {
34  images = image_set;
35  SG_REF(images);
36  image_width = image_w;
37  image_height = image_h;
38 
39  SG_ADD((CSGObject**) &images, "images", "Set of images", MS_NOT_AVAILABLE);
40  SG_ADD(&image_width, "image_width", "The image width", MS_NOT_AVAILABLE);
41  SG_ADD(&image_height, "image_height", "The image height", MS_NOT_AVAILABLE);
42  SG_ADD(&vec_nDim, "vec_nDim", "The dimension of the pyr", MS_NOT_AVAILABLE);
43 }
44 
46 {
48 }
49 
51 {
52  init(orig.images, orig.image_width, orig.image_height);
53  vec_nDim = orig.vec_nDim;
54 }
55 
57 {
58  return vec_nDim;
59 }
60 
62 {
63  return vec_nDim;
64 }
65 
67 {
68  return F_UNKNOWN;
69 }
70 
72 {
73  return C_POLY;
74 }
75 
77 {
78  return images->get_num_vectors();
79 }
80 
81 void* CLBPPyrDotFeatures::get_feature_iterator(int32_t vector_index)
82 {
84  return NULL;
85 }
86 
87 bool CLBPPyrDotFeatures::get_next_feature(int32_t& index, float64_t& value, void* iterator)
88 {
90  return false;
91 }
92 
94 {
96 }
97 
98 float64_t CLBPPyrDotFeatures::dot(int32_t vec_idx1, CDotFeatures* df, int32_t vec_idx2)
99 {
100  ASSERT(strcmp(df->get_name(),get_name())==0)
101  CLBPPyrDotFeatures* lbp_feat = (CLBPPyrDotFeatures* ) df;
103 
104  SGVector<char> vec1 = get_transformed_image(vec_idx1);
105  SGVector<char> vec2 = lbp_feat->get_transformed_image(vec_idx2);
106 
107  return SGVector<char>::dot(vec1.vector, vec2.vector, vec_nDim);
108 }
109 
111 {
114 
115  int32_t ww;
116  int32_t hh;
117  uint32_t* img = get_image(index, ww, hh);
118 
119  int32_t offset = 0;
120  while (true)
121  {
122  for (int32_t x=1; x<ww-1; x++)
123  {
124  for (int32_t y=1; y<hh-1; y++)
125  {
126  uint8_t pattern = create_lbp_pattern(img, x, y);
127  vec[offset+pattern]++;
128  offset += 256;
129  }
130  }
131  if (vec_nDim <= offset)
132  break;
133 
134 
135  if (ww % 2 == 1)
136  ww--;
137  if (hh % 2 == 1)
138  hh--;
139 
140  ww = ww/2;
141  for (int32_t x=0; x<ww; x++)
142  for (int32_t j=0; j<hh; j++)
143  img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
144  img[LIBLBP_INDEX(j,2*x+1,image_height)];
145 
146  hh = hh/2;
147  for (int32_t y=0; y<hh; y++)
148  for (int32_t j=0; j<ww; j++)
149  img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
150  img[LIBLBP_INDEX(2*y+1,j,image_height)];
151  }
152 
153  SG_FREE(img);
154  return vec;
155 }
156 
157 uint32_t* CLBPPyrDotFeatures::get_image(int32_t index, int32_t& width, int32_t& height)
158 {
159  int32_t len;
160  bool do_free;
161  uint32_t* image = images->get_feature_vector(index, len, do_free);
162  uint32_t* img;
163  img = SG_MALLOC(uint32_t, len);
164  memcpy(img, image, len * sizeof(uint32_t));
165  images->free_feature_vector(image, index, do_free);
166  width = image_width;
167  height = image_height;
168  return img;
169 }
170 
171 float64_t CLBPPyrDotFeatures::dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
172 {
173  if (vec2_len != vec_nDim)
174  SG_ERROR("Dimensions don't match, vec2_dim=%d, vec_nDim=%d\n", vec2_len, vec_nDim)
175 
176  int32_t ww;
177  int32_t hh;
178  uint32_t* img = get_image(vec_idx1, ww, hh);
179 
180  float64_t dot_prod = 0;
181  int32_t offset = 0;
182  while (true)
183  {
184  for (int32_t x=1; x<ww-1; x++)
185  {
186  for (int32_t y=1; y<hh-1; y++)
187  {
188  uint8_t pattern = create_lbp_pattern(img, x, y);
189  dot_prod += vec2[offset+pattern];
190  offset += 256;
191  }
192  }
193  if (vec_nDim <= offset)
194  break;
195 
196 
197  if (ww % 2 == 1)
198  ww--;
199  if (hh % 2 == 1)
200  hh--;
201 
202  ww = ww/2;
203  for (int32_t x=0; x<ww; x++)
204  for (int32_t j=0; j<hh; j++)
205  img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
206  img[LIBLBP_INDEX(j,2*x+1,image_height)];
207 
208  hh = hh/2;
209  for (int32_t y=0; y<hh; y++)
210  for (int32_t j=0; j<ww; j++)
211  img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
212  img[LIBLBP_INDEX(2*y+1,j,image_height)];
213  }
214 
215  SG_FREE(img);
216  return dot_prod;
217 }
218 
219 void CLBPPyrDotFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
220 {
221  if (vec2_len != vec_nDim)
222  SG_ERROR("Dimensions don't match, vec2_dim=%d, vec_nDim=%d\n", vec2_len, vec_nDim)
223 
224  int32_t ww;
225  int32_t hh;
226  uint32_t* img = get_image(vec_idx1, ww, hh);
227 
228  if (abs_val)
229  alpha = CMath::abs(alpha);
230 
231  int32_t offset = 0;
232 
233  while (true)
234  {
235  for (int32_t x=1; x<ww-1; x++)
236  {
237  for (int32_t y=1; y<hh-1; y++)
238  {
239  uint8_t pattern = create_lbp_pattern(img, x, y);
240  vec2[offset+pattern] += alpha;
241  offset += 256;
242  }
243  }
244  if (vec_nDim <= offset)
245  break;
246 
247 
248  if (ww % 2 == 1)
249  ww--;
250  if (hh % 2 == 1)
251  hh--;
252 
253  ww = ww/2;
254  for (int32_t x=0; x<ww; x++)
255  for (int32_t j=0; j<hh; j++)
256  img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
257  img[LIBLBP_INDEX(j,2*x+1,image_height)];
258 
259  hh = hh/2;
260  for (int32_t y=0; y<hh; y++)
261  for (int32_t j=0; j<ww; j++)
262  img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
263  img[LIBLBP_INDEX(2*y+1,j,image_height)];
264  }
265  SG_FREE(img);
266 }
267 
268 uint8_t CLBPPyrDotFeatures::create_lbp_pattern(uint32_t* img, int32_t x, int32_t y)
269 {
270  uint8_t pattern = 0;
271  uint32_t center = img[LIBLBP_INDEX(y,x,image_height)];
272 
273  if (img[LIBLBP_INDEX(y-1,x-1,image_height)] < center)
274  pattern |= 0x01;
275  if (img[LIBLBP_INDEX(y-1,x,image_height)] < center)
276  pattern |= 0x02;
277  if (img[LIBLBP_INDEX(y-1,x+1,image_height)] < center)
278  pattern |= 0x04;
279  if (img[LIBLBP_INDEX(y,x-1,image_height)] < center)
280  pattern |= 0x08;
281  if (img[LIBLBP_INDEX(y,x+1,image_height)] < center)
282  pattern |= 0x10;
283  if (img[LIBLBP_INDEX(y+1,x-1,image_height)] < center)
284  pattern |= 0x20;
285  if (img[LIBLBP_INDEX(y+1,x,image_height)] < center)
286  pattern |= 0x40;
287  if (img[LIBLBP_INDEX(y+1,x+1,image_height)] < center)
288  pattern |= 0x80;
289 
290  return pattern;
291 }
292 
294 {
295  return new CLBPPyrDotFeatures(*this);
296 }
297 
298 uint32_t CLBPPyrDotFeatures::liblbp_pyr_get_dim(uint16_t nPyramids)
299 {
300  uint32_t N = 0;
301  uint32_t w = image_width;
302  uint32_t h = image_height;
303 
304  for (uint32_t i=0; (i<nPyramids) && (CMath::min(w,h)>=3); i++)
305  {
306  N += (w-2)*(h-2);
307 
308  if (w % 2)
309  w--;
310  if (h % 2)
311  h--;
312 
313  w = w/2;
314  h = h/2;
315  }
316  return 256*N;
317 }

SHOGUN Machine Learning Toolbox - Documentation