segmentation
All Data Structures Namespaces Files Functions Variables Modules Pages
lbp.cpp
1 
4 
5 /*
6  * Copyright (C) 2015 Department of iCub Facility - Istituto Italiano di Tecnologia
7  * Author: Vadim Tikhanoff
8  * email: vadim.tikhanoff@iit.it
9  * Permission is granted to copy, distribute, and/or modify this program
10  * under the terms of the GNU General Public License, version 2 or any
11  * later version published by the Free Software Foundation.
12  *
13  * A copy of the license can be found at
14  * http://www.robotcub.org/icub/license/gpl.txt
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
19  * Public License for more details
20  */
21 
22 #include <cmath>
23 #include "lbp.h"
24 
25 /************************************************************************/
26 template <typename _Tp>
27 void lbp::OLBP_(const cv::Mat& src, cv::Mat& dst) {
28 
29  dst = cv::Mat::zeros(src.rows-2, src.cols-2, CV_8UC1);
30  for(int i=1;i<src.rows-1;i++) {
31  for(int j=1;j<src.cols-1;j++) {
32  _Tp center = src.at<_Tp>(i,j);
33  unsigned char code = 0;
34  code |= (src.at<_Tp>(i-1,j-1) > center) << 7;
35  code |= (src.at<_Tp>(i-1,j) > center) << 6;
36  code |= (src.at<_Tp>(i-1,j+1) > center) << 5;
37  code |= (src.at<_Tp>(i,j+1) > center) << 4;
38  code |= (src.at<_Tp>(i+1,j+1) > center) << 3;
39  code |= (src.at<_Tp>(i+1,j) > center) << 2;
40  code |= (src.at<_Tp>(i+1,j-1) > center) << 1;
41  code |= (src.at<_Tp>(i,j-1) > center) << 0;
42  dst.at<unsigned char>(i-1,j-1) = code;
43  }
44  }
45 }
46 
47 /************************************************************************/
48 template <typename _Tp>
49 void lbp::ELBP_(const cv::Mat& src, cv::Mat& dst, int radius, int neighbors) {
50  neighbors = std::max(std::min(neighbors,31),1); // set bounds...
51  dst = cv::Mat::zeros(src.rows-2*radius, src.cols-2*radius, CV_32SC1);
52 
53  for(int n=0; n<neighbors; n++) {
54  // sample points
55  float x = static_cast<float>(radius) * cos(2.0*M_PI*n/static_cast<float>(neighbors));
56  float y = static_cast<float>(radius) * -sin(2.0*M_PI*n/static_cast<float>(neighbors));
57  // relative indices
58  int fx = static_cast<int>(floor(x));
59  int fy = static_cast<int>(floor(y));
60  int cx = static_cast<int>(ceil(x));
61  int cy = static_cast<int>(ceil(y));
62  // fractional part
63  float ty = y - fy;
64  float tx = x - fx;
65  // set interpolation weights
66  float w1 = (1 - tx) * (1 - ty);
67  float w2 = tx * (1 - ty);
68  float w3 = (1 - tx) * ty;
69  float w4 = tx * ty;
70  // iterate through your data
71  for(int i=radius; i < src.rows-radius;i++) {
72  for(int j=radius;j < src.cols-radius;j++) {
73  float t = w1*src.at<_Tp>(i+fy,j+fx) + w2*src.at<_Tp>(i+fy,j+cx) + w3*src.at<_Tp>(i+cy,j+fx) + w4*src.at<_Tp>(i+cy,j+cx);
74  // we are dealing with floating point precision, so add some little tolerance
75  dst.at<unsigned int>(i-radius,j-radius) += ((t > src.at<_Tp>(i,j)) && (std::abs(t-src.at<_Tp>(i,j)) > (int)std::numeric_limits<float>::epsilon())) << n;
76  }
77  }
78  }
79 }
80 
81 /************************************************************************/
82 template <typename _Tp>
83 void lbp::VARLBP_(const cv::Mat& src, cv::Mat& dst, int radius, int neighbors) {
84 
85  std::max(std::min(neighbors,31),1); // set bounds
86  dst = cv::Mat::zeros(src.rows-2*radius, src.cols-2*radius, CV_32FC1);
87  // allocate some memory for temporary on-line variance calculations
88  cv::Mat _mean = cv::Mat::zeros(src.rows, src.cols, CV_32FC1);
89  cv::Mat _delta = cv::Mat::zeros(src.rows, src.cols, CV_32FC1);
90  cv::Mat _m2 = cv::Mat::zeros(src.rows, src.cols, CV_32FC1);
91  for(int n=0; n<neighbors; n++) {
92  // sample points
93  float x = static_cast<float>(radius) * cos(2.0*M_PI*n/static_cast<float>(neighbors));
94  float y = static_cast<float>(radius) * -sin(2.0*M_PI*n/static_cast<float>(neighbors));
95  // relative indices
96  int fx = static_cast<int>(floor(x));
97  int fy = static_cast<int>(floor(y));
98  int cx = static_cast<int>(ceil(x));
99  int cy = static_cast<int>(ceil(y));
100  // fractional part
101  float ty = y - fy;
102  float tx = x - fx;
103  // set interpolation weights
104  float w1 = (1 - tx) * (1 - ty);
105  float w2 = tx * (1 - ty);
106  float w3 = (1 - tx) * ty;
107  float w4 = tx * ty;
108  // iterate through your data
109  for(int i=radius; i < src.rows-radius;i++) {
110  for(int j=radius;j < src.cols-radius;j++) {
111  float t = w1*src.at<_Tp>(i+fy,j+fx) + w2*src.at<_Tp>(i+fy,j+cx) + w3*src.at<_Tp>(i+cy,j+fx) + w4*src.at<_Tp>(i+cy,j+cx);
112  _delta.at<float>(i,j) = t - _mean.at<float>(i,j);
113  _mean.at<float>(i,j) = (_mean.at<float>(i,j) + (_delta.at<float>(i,j) / (1.0*(n+1)))); // i am a bit paranoid
114  _m2.at<float>(i,j) = _m2.at<float>(i,j) + _delta.at<float>(i,j) * (t - _mean.at<float>(i,j));
115  }
116  }
117  }
118  // calculate result
119  for(int i = radius; i < src.rows-radius; i++) {
120  for(int j = radius; j < src.cols-radius; j++) {
121  dst.at<float>(i-radius, j-radius) = _m2.at<float>(i,j) / (1.0*(neighbors-1));
122  }
123  }
124 }
125 
126 /************************************************************************/
127 // now the wrapper functions
128 void lbp::OLBP(const cv::Mat& src, cv::Mat& dst){
129  switch(src.type()) {
130  case CV_8SC1: OLBP_<char>(src, dst); break;
131  case CV_8UC1: OLBP_<unsigned char>(src, dst); break;
132  case CV_16SC1: OLBP_<short>(src, dst); break;
133  case CV_16UC1: OLBP_<unsigned short>(src, dst); break;
134  case CV_32SC1: OLBP_<int>(src, dst); break;
135  case CV_32FC1: OLBP_<float>(src, dst); break;
136  case CV_64FC1: OLBP_<double>(src, dst); break;
137  }
138 }
139 
140 /************************************************************************/
141 void lbp::ELBP(const cv::Mat& src, cv::Mat& dst, int radius, int neighbors){
142  switch(src.type()) {
143  case CV_8SC1: ELBP_<char>(src, dst, radius, neighbors); break;
144  case CV_8UC1: ELBP_<unsigned char>(src, dst, radius, neighbors); break;
145  case CV_16SC1: ELBP_<short>(src, dst, radius, neighbors); break;
146  case CV_16UC1: ELBP_<unsigned short>(src, dst, radius, neighbors); break;
147  case CV_32SC1: ELBP_<int>(src, dst, radius, neighbors); break;
148  case CV_32FC1: ELBP_<float>(src, dst, radius, neighbors); break;
149  case CV_64FC1: ELBP_<double>(src, dst, radius, neighbors); break;
150  }
151 }
152 
153 /************************************************************************/
154 void lbp::VARLBP(const cv::Mat& src, cv::Mat& dst, int radius, int neighbors){
155  switch(src.type()) {
156  case CV_8SC1: VARLBP_<char>(src, dst, radius, neighbors); break;
157  case CV_8UC1: VARLBP_<unsigned char>(src, dst, radius, neighbors); break;
158  case CV_16SC1: VARLBP_<short>(src, dst, radius, neighbors); break;
159  case CV_16UC1: VARLBP_<unsigned short>(src, dst, radius, neighbors); break;
160  case CV_32SC1: VARLBP_<int>(src, dst, radius, neighbors); break;
161  case CV_32FC1: VARLBP_<float>(src, dst, radius, neighbors); break;
162  case CV_64FC1: VARLBP_<double>(src, dst, radius, neighbors); break;
163  }
164 }
165 
166 /************************************************************************/
167 // now the Mat return functions
168 cv::Mat lbp::OLBP(const cv::Mat& src){
169  cv::Mat dst;
170  OLBP(src, dst);
171  return dst;
172 }
173 
174 /************************************************************************/
175 cv::Mat lbp::ELBP(const cv::Mat& src, int radius, int neighbors){
176  cv::Mat dst;
177  ELBP(src, dst, radius, neighbors);
178  return dst;
179 }
180 
181 /************************************************************************/
182 cv::Mat lbp::VARLBP(const cv::Mat& src, int radius, int neighbors) {
183  cv::Mat dst;
184  VARLBP(src, dst, radius, neighbors);
185  return dst;
186 }
187 
188 
189 
190 
void VARLBP_(const cv::Mat &src, cv::Mat &dst, int radius=1, int neighbors=8)
Definition: lbp.cpp:83
void OLBP_(const cv::Mat &src, cv::Mat &dst)
Original code by philipp <bytefish[at]gmx[dot]de>
Definition: lbp.cpp:27