X-Boost  2.3.8
NonMaximaSuppression.h
Go to the documentation of this file.
1 /* XBoost: Ada-Boost and Friends on Haar/ICF/HOG Features, Library and ToolBox
2  *
3  * Copyright (c) 2008-2014 Paolo Medici <medici@ce.unipr.it>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef _NON_MAXIMA_SUPPRESSION_H
22 #define _NON_MAXIMA_SUPPRESSION_H
23 
28 #include <vector>
29 
30 #ifdef _MULTITHREAD
31 # include "Thread/thread.h"
32 # include "Thread/thread_group.h"
33 # include "Thread/bind.h"
34 #endif
35 
41 template<class D, class FeatureListType, class Param>
42 void NonMaximaSuppression(const D *src, FeatureListType &maxima, unsigned int n, long stride, unsigned int width, unsigned int height, D threshold, Param param, int nThreads = sprint::thread::hardware_concurrency() );
43 
44 /******************** implementation ***************************************/
45 
46 namespace detail {
47 
49 template<class D, class FeatureListType, class Param>
50 struct LocalMaxima {
52  const D *m_src;
54  int n;
56  long stride;
58  int width;
60  int height;
62  Param id;
65 public:
66 
70  void *Process(FeatureListType &maxima, int j0, int j1) const
71  {
72  const D * src = m_src + j0 * stride; // initial row
73  typedef typename FeatureListType::value_type FeatureType;
74  // i need at least n+1 elements in the pool
75  for(int j=j0; j<j1; j+=n+1)
76  {
77  int j_max = std::min(j+n, height-1); // size of slice
78 
79  for(int i=0; i<width; i+=n+1)
80  {
81  // src punta sempre alla riga (j)
82  const D *ptr;
83  int pi, pj;
84  D pval;
85 
86  int i_max = std::min(i+n, width-1); // remaing part of cell
87 
88  ptr = src; // ptr deve puntare sempre alla riga di inizio, con i invece relativo al tipo di elaborazione
89  pval = ptr[i]; // initialized with (i,j)
90  pi = i;
91  pj = j;
92  // per ogni cella n x n cerco il massimo assoluto
93  for(int j2=j; j2<=j_max; ++j2)
94  {
95  for(int i2=i; i2<=i_max; ++i2)
96  {
97  D cval = ptr[i2];
98  // il punto deve essere maggiore o uguale al precedente per essere valido
99  // POSITIVI
100  if( cval>pval) {
101  pi = i2;
102  pj = j2;
103  pval = cval;
104  }
105  }
106  ptr += stride;
107  }
108 
109  if(pval<threshold)
110  goto pfailed;
111 
112  {
113  // clip the search area inside (0,0)-(width-1,height-1)
114  int j2_0 = pj - (int) n;
115  if(j2_0 < 0) j2_0 = 0;
116  int j2_1 = pj + (int) n;
117  if(j2_1 >= height) j2_1 = height-1;
118 
119  int i2_0 = pi - (int) n;
120  if(i2_0 < 0) i2_0 = 0;
121  int i2_1 = pi + (int) n;
122  if(i2_1 >= width) i2_1 = width-1;
123 
124  // siccome src punta sempre a j devo togliere j, se voglio lavorare con pj
125  ptr = src + (j2_0 - j ) * stride;
126 
127  // TODO: split in 4 cluster to avoid internal if
128  for (int32_t j2=j2_0; j2<=j2_1; j2++) {
129  for (int32_t i2=i2_0; i2<=i2_1; i2++) {
130  if (i2<i || i2>i+(int)n || j2<j || j2>j+(int)n) {
131  D cval = ptr[i2];
132  if (cval>pval)
133  goto pfailed; // abort
134  }
135  }
136  ptr += stride;
137  }
138  }
139 
140  // POSITIVI
141  if(pval>=threshold)
142  {
143  FeatureType p;
144  p.Set(pi, pj, pval, id);
145  maxima.push_back( p );
146  }
147 
148 pfailed:
149  ;
150 
151  }
152 
153  src+= (stride * (n+1));
154  }
155 
156  return 0;
157  }
158 
159 };
160 
161 } //detail
162 
163 
164 // multithread implementation:
165 
166 template<class D, class FeatureListType, class Param>
167 void NonMaximaSuppression(const D *src, FeatureListType &maxima, unsigned int n, long stride, unsigned int width, unsigned int height, D threshold, Param param, int nThreads )
168 {
170 
171  nms.m_src = src;
172  nms.n = n;
173  nms.height = height;
174  nms.width = width;
175  nms.threshold = threshold;
176  nms.id = param;
177  nms.stride = stride;
178 
179  // number of active "blocks" n+1 size
180  int32_t active = (int)height / ((int)n+1);
181 
182  // at least 3 chunk per thread TODO
183  if((active > 0) && (nThreads>1) && (active>=3*nThreads) )
184  {
185  sprint::thread_group thread_pool_;
186  FeatureListType *outputs = new FeatureListType[nThreads];
187 
188  for(int k=0; k<nThreads; ++k)
189  {
190  uint32_t k0 = (active * k) / nThreads; // prima riga da assegnare a questo core
191  uint32_t k1 = (active * (k+1) ) / nThreads; // ultima riga (non compresa) da assegnare a questo core
192 
193  thread_pool_.create_thread( sprint::thread_bind( &detail::LocalMaxima<D, FeatureListType, Param>::Process, &nms, &outputs[k], (int) k0 * (n+1), (int) k1 * (n+1)));
194  }
195 
196  thread_pool_.join_all();
197 
198  for(int k =0; k<nThreads; ++k)
199  {
200  maxima.insert(maxima.end(), outputs[k].begin(),outputs[k].end());
201  }
202 
203  delete [] outputs;
204  }
205  else
206  {
207  nms.Process(maxima, 0, (int) height);
208  }
209 }
210 
211 #endif
int n
nms step
Definition: NonMaximaSuppression.h:54
const D * m_src
The buffer.
Definition: NonMaximaSuppression.h:52
int width
horizontal number of pixel to be processed
Definition: NonMaximaSuppression.h:58
Definition: thread_group.h:82
The internal NM class.
Definition: NonMaximaSuppression.h:50
abstracting thread
void join_all()
wait all threads terminate
Definition: thread_group.h:114
proposal 1 for thread group
long stride
stride
Definition: NonMaximaSuppression.h:56
D threshold
threshold
Definition: NonMaximaSuppression.h:64
method to create function pointer for thread call
bool create_thread(const sprint::thread_function &p)
create an additional thread
Definition: thread_group.h:102
void * Process(FeatureListType &maxima, int j0, int j1) const
Definition: NonMaximaSuppression.h:70
Param id
optional data used by Set Method
Definition: NonMaximaSuppression.h:62
int height
clamping value
Definition: NonMaximaSuppression.h:60
void NonMaximaSuppression(const D *src, FeatureListType &maxima, unsigned int n, long stride, unsigned int width, unsigned int height, D threshold, Param param, int nThreads=sprint::thread::hardware_concurrency())
Definition: NonMaximaSuppression.h:167