gradient.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "gradient.h"
00024 #include <core/exceptions/software.h>
00025
00026 using std::list;
00027 using std::iterator;
00028
00029 using fawkes::point_t;
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 GradientClassifier::GradientClassifier(std::list<ScanlineGrid* >* scanlines,
00047 Qualifier* q,
00048 unsigned int threshold, unsigned int max_size,
00049 bool use_rising_flank, bool use_falling_flank)
00050 : Classifier("GradientClassifier")
00051 {
00052 if (!scanlines)
00053 throw fawkes::NullPointerException("GradientClassifier: scanlines may not be null!");
00054 if (!q)
00055 throw fawkes::NullPointerException("GradientClassifier: the Qualifier may not be null!");
00056
00057 _scanlines = scanlines;
00058 _q = q;
00059
00060 _max_size = 999999;
00061 set_threshold(threshold, max_size);
00062 set_edges(use_rising_flank, use_falling_flank);
00063 }
00064
00065
00066
00067 GradientClassifier::~GradientClassifier()
00068 {
00069 if (_q)
00070 delete _q;
00071 }
00072
00073
00074
00075
00076
00077 void
00078 GradientClassifier::set_threshold(unsigned int threshold, unsigned int max_size)
00079 {
00080 _threshold = threshold;
00081
00082 if (max_size)
00083 _max_size = max_size;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 void
00093 GradientClassifier::set_edges(bool use_rising_edge, bool use_falling_edge)
00094 {
00095 _use_rising_edge = use_rising_edge;
00096 _use_falling_edge = use_falling_edge;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106 void
00107 GradientClassifier::set_src_buffer(unsigned char *yuv422_planar,
00108 unsigned int width, unsigned int height)
00109 {
00110 Classifier::set_src_buffer(yuv422_planar, width, height);
00111
00112 _q->set_buffer(yuv422_planar, width, height);
00113 }
00114
00115
00116
00117 std::list< ROI > *
00118 GradientClassifier::classify()
00119 {
00120 if (_q->get_buffer() == NULL)
00121 {
00122
00123 return new std::list< ROI >;
00124 }
00125
00126 list< ROI > *rv = new list< ROI >;
00127 int cur_val, cur_diff, direction = 0;
00128 point_t cur_pos, edge_start;
00129 cur_pos.x = cur_pos.y = edge_start.x = edge_start.y = 0;
00130
00131 unsigned int jumpSize = 0;
00132
00133 ROI current;
00134
00135 for (list<ScanlineGrid*>::iterator it = _scanlines->begin(); it != _scanlines->end(); it++)
00136 {
00137 ScanlineGrid* slm = (*it);
00138 slm->reset();
00139
00140 _last_pos = *(*slm);
00141 _last_val = _q->get(_last_pos);
00142
00143 while(!slm->finished())
00144 {
00145 cur_pos = *(++(*slm));
00146 cur_val = _q->get(cur_pos);
00147 cur_diff = cur_val - _last_val;
00148
00149 if ((cur_pos.x < _last_pos.x || cur_pos.y < _last_pos.y)
00150 || (current.pixel_step && ((cur_pos.x - current.start.x) > _max_size
00151 || (cur_pos.y - current.start.y) > _max_size)))
00152 {
00153 current.set_pixel_step(0);
00154
00155 edge_start.x = edge_start.y = direction = jumpSize = 0;
00156 }
00157
00158 int curDir = (cur_diff < 0 ? -1 : (cur_diff > 0 ? 1 : 0));
00159 switch (curDir)
00160 {
00161 case -1:
00162 switch (direction)
00163 {
00164 case -1:
00165 jumpSize -= cur_diff;
00166 break;
00167 case 0:
00168 jumpSize = -cur_diff;
00169 edge_start = cur_pos;
00170 break;
00171 case 1:
00172 if (jumpSize < _threshold)
00173 {
00174 jumpSize = -cur_diff;
00175 edge_start = cur_pos;
00176 }
00177 else
00178 {
00179 if (current.pixel_step)
00180 {
00181 current.set_width(_last_pos.x - current.start.x);
00182 current.set_height(_last_pos.y - current.start.y);
00183
00184 rv->push_back(ROI(current));
00185
00186 current.set_pixel_step(0);
00187 }
00188 else if (_use_falling_edge)
00189 {
00190 current.set_pixel_step(1);
00191 current.set_start(edge_start);
00192 }
00193
00194 edge_start = cur_pos;
00195 jumpSize = -cur_diff;
00196 }
00197 break;
00198 }
00199 direction = -1;
00200 break;
00201
00202
00203 case 0:
00204 switch (direction)
00205 {
00206 case -1:
00207 case 1:
00208 if (jumpSize >= _threshold)
00209 {
00210 if (current.pixel_step)
00211 {
00212 current.set_width(_last_pos.x - current.start.x);
00213 current.set_height(_last_pos.y - current.start.y);
00214
00215 rv->push_back(ROI(current));
00216
00217 current.set_pixel_step(0);
00218 }
00219 else
00220 {
00221 if ((_use_falling_edge && direction == 1) || (_use_rising_edge && direction == -1))
00222 {
00223 current.set_pixel_step(1);
00224 current.set_start(edge_start);
00225 }
00226 }
00227 }
00228 break;
00229
00230 case 0:
00231 break;
00232 }
00233 direction = jumpSize = 0;
00234 edge_start.x = edge_start.y = 0;
00235 break;
00236
00237
00238 case 1:
00239 switch (direction)
00240 {
00241 case 1:
00242 jumpSize += cur_diff;
00243 break;
00244 case 0:
00245 jumpSize = cur_diff;
00246 edge_start = cur_pos;
00247 break;
00248 case -1:
00249 if (jumpSize < _threshold)
00250 {
00251 jumpSize = cur_diff;
00252 edge_start = cur_pos;
00253 }
00254 else
00255 {
00256 if (current.pixel_step)
00257 {
00258 current.set_width(_last_pos.x - current.start.x);
00259 current.set_height(_last_pos.y - current.start.y);
00260
00261 rv->push_back(ROI(current));
00262
00263 current.set_pixel_step(0);
00264 }
00265 else if (_use_rising_edge)
00266 {
00267 current.set_pixel_step(1);
00268 current.set_start(edge_start);
00269 }
00270
00271 edge_start = cur_pos;
00272 jumpSize = cur_diff;
00273 }
00274 break;
00275 }
00276 direction = 1;
00277 break;
00278 }
00279
00280
00281 _last_val = cur_val;
00282 _last_pos = cur_pos;
00283 }
00284 }
00285
00286 return rv;
00287 }
00288