ht_lines.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <cmath>
00027 #include <sys/time.h>
00028 #include <models/shape/ht_lines.h>
00029 #include <utils/math/angle.h>
00030
00031 using namespace std;
00032 using namespace fawkes;
00033
00034 #define TEST_IF_IS_A_PIXEL(x) ((x)>230)
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 HtLinesModel::HtLinesModel(unsigned int nr_candidates, float angle_from, float angle_range, int r_scale, float min_votes_ratio, int min_votes)
00049 {
00050 RHT_NR_CANDIDATES = nr_candidates;
00051
00052 RHT_R_SCALE = r_scale;
00053
00054 RHT_MIN_VOTES = min_votes;
00055 RHT_MIN_VOTES_RATIO = min_votes_ratio;
00056
00057 RHT_ANGLE_FROM = angle_from - (floor(angle_from / (2 * M_PI )) * (2 * M_PI));
00058 RHT_ANGLE_RANGE = angle_range - (floor(angle_range / (2 * M_PI )) * (2 * M_PI));
00059 RHT_ANGLE_INCREMENT = RHT_ANGLE_RANGE / RHT_NR_CANDIDATES;
00060 }
00061
00062
00063
00064 HtLinesModel::~HtLinesModel(void)
00065 {
00066 m_Lines.clear();
00067 }
00068
00069 int
00070 HtLinesModel::parseImage( unsigned char *buf,
00071 ROI *roi )
00072 {
00073 unsigned char *buffer = roi->get_roi_buffer_start(buf);
00074
00075
00076 accumulator.reset();
00077
00078
00079 m_Lines.clear();
00080
00081
00082
00083 unsigned char *line_start = buffer;
00084 unsigned int x, y;
00085 vector<point_t> pixels;
00086
00087 for (y = 0; y < roi->height; ++y) {
00088 for (x = 0; x < roi->width; ++x) {
00089 if (TEST_IF_IS_A_PIXEL(*buffer)) {
00090 point_t pt={x, y};
00091 pixels.push_back(pt);
00092 }
00093
00094 ++buffer;
00095 }
00096 line_start += roi->line_step;
00097 buffer = line_start;
00098 }
00099
00100
00101 point_t p;
00102 float r, phi;
00103 vector< point_t >::iterator pos;
00104 if (pixels.size() == 0) {
00105
00106 return 0;
00107 }
00108
00109
00110 while (pixels.size() > 0) {
00111 p = pixels.back();
00112 pixels.pop_back();
00113
00114 for (unsigned int i = 0; i < RHT_NR_CANDIDATES; ++i) {
00115 phi = RHT_ANGLE_FROM + i * RHT_ANGLE_INCREMENT;
00116 r = p.x * cos( phi ) + p.y * sin( phi );
00117
00118 int angle = (int)round(fawkes::rad2deg( phi ));
00119
00120 accumulator.accumulate( (int)round(r / RHT_R_SCALE),
00121 angle,
00122 0 );
00123 }
00124 }
00125
00126
00127
00128 int max, r_max, phi_max, any_max;
00129 max = accumulator.getMax(r_max, phi_max, any_max);
00130
00131 roi_width = roi->width;
00132 roi_height = roi->height;
00133
00134 LineShape l(roi->width, roi->height);
00135 l.r = r_max * RHT_R_SCALE;
00136 l.phi = phi_max;
00137 l.count = max;
00138 m_Lines.push_back( l );
00139
00140 return 1;
00141 }
00142
00143
00144 int
00145 HtLinesModel::getShapeCount(void) const
00146 {
00147 return m_Lines.size();
00148 }
00149
00150 LineShape *
00151 HtLinesModel::getShape(int id) const
00152 {
00153 if (id < 0 || (unsigned int)id >= m_Lines.size()) {
00154 return NULL;
00155 } else {
00156 return const_cast<LineShape*>(&m_Lines[id]);
00157 }
00158 }
00159
00160
00161 LineShape *
00162 HtLinesModel::getMostLikelyShape(void) const
00163 {
00164 if (m_Lines.size() == 0) {
00165 return NULL;
00166 } else if (m_Lines.size() == 1) {
00167 return const_cast<LineShape*>(&m_Lines[0]);
00168 } else {
00169 int cur=0;
00170 for (unsigned int i=1; i < m_Lines.size(); ++i) {
00171 if (m_Lines[i].count > m_Lines[cur].count) {
00172 cur = i;
00173 }
00174 }
00175 return const_cast<LineShape*>(&m_Lines[cur]);
00176 }
00177 }
00178
00179
00180
00181
00182
00183 vector< LineShape > *
00184 HtLinesModel::getShapes()
00185 {
00186 int votes = (int)(accumulator.getNumVotes() * (float)RHT_MIN_VOTES_RATIO);
00187
00188 if ( RHT_MIN_VOTES > votes ) {
00189 votes = RHT_MIN_VOTES;
00190 }
00191
00192 vector< LineShape > * rv = new vector< LineShape >();
00193
00194 vector< vector< int > > *rht_nodes = accumulator.getNodes( votes );
00195 vector< vector< int > >::iterator node_it;
00196
00197 LineShape l(roi_width, roi_height);
00198
00199 for (node_it = rht_nodes->begin(); node_it != rht_nodes->end(); ++node_it) {
00200 l.r = node_it->at(0) * RHT_R_SCALE;
00201 l.phi = node_it->at(1);
00202
00203 l.count = node_it->at(3);
00204 l.calcPoints();
00205 rv->push_back( l );
00206 }
00207
00208 return rv;
00209 }