SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LBPPyrDotFeatures.cpp
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2010 Vojtech Franc, Soeren Sonnenburg
00008  * Written (W) 2013 Evangelos Anagnostopoulos
00009  * Copyright (C) 2010 Vojtech Franc, xfrancv@cmp.felk.cvut.cz
00010  * Copyright (C) 2010 Berlin Institute of Technology
00011  */
00012 #include <shogun/features/LBPPyrDotFeatures.h>
00013 
00014 using namespace shogun;
00015 
00016 #define LIBLBP_INDEX(ROW,COL,NUM_ROWS) ((COL)*(NUM_ROWS)+(ROW))
00017 
00018 CLBPPyrDotFeatures::CLBPPyrDotFeatures() : CDotFeatures()
00019 {
00020     init(NULL, 0, 0);
00021     vec_nDim = 0;
00022 }
00023 
00024 CLBPPyrDotFeatures::CLBPPyrDotFeatures(CDenseFeatures<uint32_t>* image_set, int32_t image_w,
00025     int32_t image_h, uint16_t num_pyramids) : CDotFeatures()
00026 {
00027     ASSERT(image_set)
00028     init(image_set, image_w, image_h);
00029     vec_nDim = liblbp_pyr_get_dim(num_pyramids);
00030 }
00031 
00032 void CLBPPyrDotFeatures::init(CDenseFeatures<uint32_t>* image_set, int32_t image_w, int32_t image_h)
00033 {
00034     images = image_set;
00035     SG_REF(images);
00036     image_width = image_w;
00037     image_height = image_h;
00038 
00039     SG_ADD((CSGObject**) &images, "images", "Set of images", MS_NOT_AVAILABLE);
00040     SG_ADD(&image_width, "image_width", "The image width", MS_NOT_AVAILABLE);
00041     SG_ADD(&image_height, "image_height", "The image height", MS_NOT_AVAILABLE);
00042     SG_ADD(&vec_nDim, "vec_nDim", "The dimension of the pyr", MS_NOT_AVAILABLE);
00043 }
00044 
00045 CLBPPyrDotFeatures::~CLBPPyrDotFeatures()
00046 {
00047     SG_UNREF(images);
00048 }
00049 
00050 CLBPPyrDotFeatures::CLBPPyrDotFeatures(const CLBPPyrDotFeatures& orig)
00051 {
00052     init(orig.images, orig.image_width, orig.image_height);
00053     vec_nDim = orig.vec_nDim;
00054 }
00055 
00056 int32_t CLBPPyrDotFeatures::get_dim_feature_space() const
00057 {
00058     return vec_nDim;
00059 }
00060 
00061 int32_t CLBPPyrDotFeatures::get_nnz_features_for_vector(int32_t num)
00062 {
00063     return vec_nDim;
00064 }
00065 
00066 EFeatureType CLBPPyrDotFeatures::get_feature_type() const
00067 {
00068     return F_UNKNOWN;
00069 }
00070 
00071 EFeatureClass CLBPPyrDotFeatures::get_feature_class() const
00072 {
00073     return C_POLY;
00074 }
00075 
00076 int32_t CLBPPyrDotFeatures::get_num_vectors() const
00077 {
00078     return images->get_num_vectors();
00079 }
00080 
00081 void* CLBPPyrDotFeatures::get_feature_iterator(int32_t vector_index)
00082 {
00083     SG_NOTIMPLEMENTED
00084     return NULL;
00085 }
00086 
00087 bool CLBPPyrDotFeatures::get_next_feature(int32_t& index, float64_t& value, void* iterator)
00088 {
00089     SG_NOTIMPLEMENTED
00090     return false;
00091 }
00092 
00093 void CLBPPyrDotFeatures::free_feature_iterator(void* iterator)
00094 {
00095     SG_NOTIMPLEMENTED
00096 }
00097 
00098 float64_t CLBPPyrDotFeatures::dot(int32_t vec_idx1, CDotFeatures* df, int32_t vec_idx2)
00099 {
00100     ASSERT(strcmp(df->get_name(),get_name())==0)
00101     CLBPPyrDotFeatures* lbp_feat = (CLBPPyrDotFeatures* ) df;
00102     ASSERT(get_dim_feature_space() == lbp_feat->get_dim_feature_space());
00103 
00104     SGVector<char> vec1 = get_transformed_image(vec_idx1);
00105     SGVector<char> vec2 = lbp_feat->get_transformed_image(vec_idx2);
00106 
00107     return SGVector<char>::dot(vec1.vector, vec2.vector, vec_nDim);
00108 }
00109 
00110 SGVector<char> CLBPPyrDotFeatures::get_transformed_image(int32_t index)
00111 {
00112     SGVector<char> vec(vec_nDim);
00113     SGVector<char>::fill_vector(vec, vec_nDim, 0);
00114 
00115     int32_t ww;
00116     int32_t hh;
00117     uint32_t* img = get_image(index, ww, hh);
00118 
00119     int32_t offset = 0;
00120     while (true)
00121     {
00122         for (int32_t x=1; x<ww-1; x++)
00123         {
00124             for (int32_t y=1; y<hh-1; y++)
00125             {
00126                 uint8_t pattern = create_lbp_pattern(img, x, y);
00127                 vec[offset+pattern]++;
00128                 offset += 256;
00129             }
00130         }
00131         if (vec_nDim <= offset)
00132             break;
00133 
00134 
00135         if (ww % 2 == 1)
00136             ww--;
00137         if (hh % 2 == 1)
00138             hh--;
00139 
00140         ww = ww/2;
00141         for (int32_t x=0; x<ww; x++)
00142             for (int32_t j=0; j<hh; j++)
00143                 img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
00144                     img[LIBLBP_INDEX(j,2*x+1,image_height)];
00145 
00146         hh = hh/2;
00147         for (int32_t y=0; y<hh; y++)
00148             for (int32_t j=0; j<ww; j++)
00149                 img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
00150                     img[LIBLBP_INDEX(2*y+1,j,image_height)];
00151     }
00152 
00153     SG_FREE(img);
00154     return vec;
00155 }
00156 
00157 uint32_t* CLBPPyrDotFeatures::get_image(int32_t index, int32_t& width, int32_t& height)
00158 {
00159     int32_t len;
00160     bool do_free;
00161     uint32_t* image = images->get_feature_vector(index, len, do_free);
00162     uint32_t* img;
00163     img = SG_MALLOC(uint32_t, len);
00164     memcpy(img, image, len * sizeof(uint32_t));
00165     images->free_feature_vector(image, index, do_free);
00166     width = image_width;
00167     height = image_height;
00168     return img;
00169 }
00170 
00171 float64_t CLBPPyrDotFeatures::dense_dot(int32_t vec_idx1, float64_t* vec2, int32_t vec2_len)
00172 {
00173     if (vec2_len != vec_nDim)
00174         SG_ERROR("Dimensions don't match, vec2_dim=%d, vec_nDim=%d\n", vec2_len, vec_nDim)
00175 
00176     int32_t ww;
00177     int32_t hh;
00178     uint32_t* img = get_image(vec_idx1, ww, hh);
00179 
00180     float64_t dot_prod = 0;
00181     int32_t offset = 0;
00182     while (true)
00183     {
00184         for (int32_t x=1; x<ww-1; x++)
00185         {
00186             for (int32_t y=1; y<hh-1; y++)
00187             {
00188                 uint8_t pattern = create_lbp_pattern(img, x, y);
00189                 dot_prod += vec2[offset+pattern];
00190                 offset += 256;
00191             }
00192         }
00193         if (vec_nDim <= offset)
00194             break;
00195 
00196 
00197         if (ww % 2 == 1)
00198             ww--;
00199         if (hh % 2 == 1)
00200             hh--;
00201 
00202         ww = ww/2;
00203         for (int32_t x=0; x<ww; x++)
00204             for (int32_t j=0; j<hh; j++)
00205                 img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
00206                     img[LIBLBP_INDEX(j,2*x+1,image_height)];
00207 
00208         hh = hh/2;
00209         for (int32_t y=0; y<hh; y++)
00210             for (int32_t j=0; j<ww; j++)
00211                 img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
00212                     img[LIBLBP_INDEX(2*y+1,j,image_height)];
00213     }
00214 
00215     SG_FREE(img);
00216     return dot_prod;
00217 }
00218 
00219 void CLBPPyrDotFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
00220 {
00221     if (vec2_len != vec_nDim)
00222         SG_ERROR("Dimensions don't match, vec2_dim=%d, vec_nDim=%d\n", vec2_len, vec_nDim)
00223 
00224     int32_t ww;
00225     int32_t hh;
00226     uint32_t* img = get_image(vec_idx1, ww, hh);
00227 
00228     if (abs_val)
00229         alpha = CMath::abs(alpha);
00230 
00231     int32_t offset = 0;
00232 
00233     while (true)
00234     {
00235         for (int32_t x=1; x<ww-1; x++)
00236         {
00237             for (int32_t y=1; y<hh-1; y++)
00238             {
00239                 uint8_t pattern = create_lbp_pattern(img, x, y);
00240                 vec2[offset+pattern] += alpha;
00241                 offset += 256;
00242             }
00243         }
00244         if (vec_nDim <= offset)
00245             break;
00246 
00247 
00248         if (ww % 2 == 1)
00249             ww--;
00250         if (hh % 2 == 1)
00251             hh--;
00252 
00253         ww = ww/2;
00254         for (int32_t x=0; x<ww; x++)
00255             for (int32_t j=0; j<hh; j++)
00256                 img[LIBLBP_INDEX(j,x,image_height)] = img[LIBLBP_INDEX(j,2*x,image_height)] +
00257                     img[LIBLBP_INDEX(j,2*x+1,image_height)];
00258 
00259         hh = hh/2;
00260         for (int32_t y=0; y<hh; y++)
00261             for (int32_t j=0; j<ww; j++)
00262                 img[LIBLBP_INDEX(y,j,image_height)] = img[LIBLBP_INDEX(2*y,j,image_height)] +
00263                     img[LIBLBP_INDEX(2*y+1,j,image_height)];
00264     }
00265     SG_FREE(img);
00266 }
00267 
00268 uint8_t CLBPPyrDotFeatures::create_lbp_pattern(uint32_t* img, int32_t x, int32_t y)
00269 {
00270     uint8_t pattern = 0;
00271     uint32_t center = img[LIBLBP_INDEX(y,x,image_height)];
00272 
00273     if (img[LIBLBP_INDEX(y-1,x-1,image_height)] < center)
00274         pattern |= 0x01;
00275     if (img[LIBLBP_INDEX(y-1,x,image_height)] < center)
00276         pattern |= 0x02;
00277     if (img[LIBLBP_INDEX(y-1,x+1,image_height)] < center)
00278         pattern |= 0x04;
00279     if (img[LIBLBP_INDEX(y,x-1,image_height)] < center)
00280         pattern |= 0x08;
00281     if (img[LIBLBP_INDEX(y,x+1,image_height)] < center)
00282         pattern |= 0x10;
00283     if (img[LIBLBP_INDEX(y+1,x-1,image_height)] < center)
00284         pattern |= 0x20;
00285     if (img[LIBLBP_INDEX(y+1,x,image_height)] < center)
00286         pattern |= 0x40;
00287     if (img[LIBLBP_INDEX(y+1,x+1,image_height)] < center)
00288         pattern |= 0x80;
00289 
00290     return pattern;
00291 }
00292 
00293 CFeatures* CLBPPyrDotFeatures::duplicate() const
00294 {
00295     return new CLBPPyrDotFeatures(*this);
00296 }
00297 
00298 uint32_t CLBPPyrDotFeatures::liblbp_pyr_get_dim(uint16_t nPyramids)
00299 {
00300   uint32_t N = 0;
00301   uint32_t w = image_width;
00302   uint32_t h = image_height;
00303 
00304   for (uint32_t i=0; (i<nPyramids) && (CMath::min(w,h)>=3); i++)
00305   {
00306     N += (w-2)*(h-2);
00307 
00308     if (w % 2)
00309         w--;
00310     if (h % 2)
00311         h--;
00312 
00313     w = w/2;
00314     h = h/2;
00315   }
00316   return 256*N;
00317 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation