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