Gathers outline points and their directions from start_index into dirs by stepping along the outline and normalizing the coordinates until the required feature_length has been collected or end_index is reached. On input pos must point to the position corresponding to start_index and on return pos is updated to the current raw position, and pos_normed is set to the normed version of pos. Since dire
| 271 | // dir and dir+128 (128 is 180 degrees) and then use the resulting mean |
| 272 | // with the least variance. |
| 273 | static int GatherPoints(const C_OUTLINE* outline, double feature_length, |
| 274 | const DENORM& denorm, const DENORM* root_denorm, |
| 275 | int start_index, int end_index, |
| 276 | ICOORD* pos, FCOORD* pos_normed, |
| 277 | LLSQ* points, LLSQ* dirs) { |
| 278 | int step_length = outline->pathlength(); |
| 279 | ICOORD step = outline->step(start_index % step_length); |
| 280 | // Prev_normed is the start point of this collection and will be set on the |
| 281 | // first iteration, and on later iterations used to determine the length |
| 282 | // that has been collected. |
| 283 | FCOORD prev_normed; |
| 284 | points->clear(); |
| 285 | dirs->clear(); |
| 286 | int num_points = 0; |
| 287 | int index; |
| 288 | for (index = start_index; index <= end_index; ++index, *pos += step) { |
| 289 | step = outline->step(index % step_length); |
| 290 | int edge_weight = outline->edge_strength_at_index(index % step_length); |
| 291 | if (edge_weight == 0) { |
| 292 | // This point has conflicting gradient and step direction, so ignore it. |
| 293 | continue; |
| 294 | } |
| 295 | // Get the sub-pixel precise location and normalize. |
| 296 | FCOORD f_pos = outline->sub_pixel_pos_at_index(*pos, index % step_length); |
| 297 | denorm.NormTransform(root_denorm, f_pos, pos_normed); |
| 298 | if (num_points == 0) { |
| 299 | // The start of this segment. |
| 300 | prev_normed = *pos_normed; |
| 301 | } else { |
| 302 | FCOORD offset = *pos_normed - prev_normed; |
| 303 | float length = offset.length(); |
| 304 | if (length > feature_length) { |
| 305 | // We have gone far enough from the start. We will use this point in |
| 306 | // the next set so return what we have so far. |
| 307 | return index; |
| 308 | } |
| 309 | } |
| 310 | points->add(pos_normed->x(), pos_normed->y(), edge_weight); |
| 311 | int direction = outline->direction_at_index(index % step_length); |
| 312 | if (direction >= 0) { |
| 313 | direction = NormalizeDirection(direction, f_pos, denorm, root_denorm); |
| 314 | // Use both the direction and direction +128 so we are not trying to |
| 315 | // take the mean of something straddling the wrap-around point. |
| 316 | dirs->add(direction, Modulo(direction + 128, 256)); |
| 317 | } |
| 318 | ++num_points; |
| 319 | } |
| 320 | return index; |
| 321 | } |
| 322 | |
| 323 | // Extracts Tesseract features and appends them to the features vector. |
| 324 | // Startpt to lastpt, inclusive, MUST have the same src_outline member, |
no test coverage detected