Extracts sets of 3-D features of length kStandardFeatureLength (=12.8), as (x,y) position and angle as measured counterclockwise from the vector <-1, 0>, from blob using two normalizations defined by bl_denorm and cn_denorm. See SetpuBLCNDenorms for definitions. If outline_cn_counts is not NULL, on return it contains the cumulative number of cn features generated for each outline in the blob (in o
| 443 | // Thus after the first outline, there were (*outline_cn_counts)[0] features, |
| 444 | // after the second outline, there were (*outline_cn_counts)[1] features etc. |
| 445 | void Classify::ExtractFeatures(const TBLOB& blob, |
| 446 | bool nonlinear_norm, |
| 447 | GenericVector<INT_FEATURE_STRUCT>* bl_features, |
| 448 | GenericVector<INT_FEATURE_STRUCT>* cn_features, |
| 449 | INT_FX_RESULT_STRUCT* results, |
| 450 | GenericVector<int>* outline_cn_counts) { |
| 451 | DENORM bl_denorm, cn_denorm; |
| 452 | tesseract::Classify::SetupBLCNDenorms(blob, nonlinear_norm, |
| 453 | &bl_denorm, &cn_denorm, results); |
| 454 | if (outline_cn_counts != NULL) |
| 455 | outline_cn_counts->truncate(0); |
| 456 | // Iterate the outlines. |
| 457 | for (TESSLINE* ol = blob.outlines; ol != NULL; ol = ol->next) { |
| 458 | // Iterate the polygon. |
| 459 | EDGEPT* loop_pt = ol->FindBestStartPt(); |
| 460 | EDGEPT* pt = loop_pt; |
| 461 | if (pt == NULL) continue; |
| 462 | do { |
| 463 | if (pt->IsHidden()) continue; |
| 464 | // Find a run of equal src_outline. |
| 465 | EDGEPT* last_pt = pt; |
| 466 | do { |
| 467 | last_pt = last_pt->next; |
| 468 | } while (last_pt != loop_pt && !last_pt->IsHidden() && |
| 469 | last_pt->src_outline == pt->src_outline); |
| 470 | last_pt = last_pt->prev; |
| 471 | // Until the adaptive classifier can be weaned off polygon segments, |
| 472 | // we have to force extraction from the polygon for the bl_features. |
| 473 | ExtractFeaturesFromRun(pt, last_pt, bl_denorm, kStandardFeatureLength, |
| 474 | true, bl_features); |
| 475 | ExtractFeaturesFromRun(pt, last_pt, cn_denorm, kStandardFeatureLength, |
| 476 | false, cn_features); |
| 477 | pt = last_pt; |
| 478 | } while ((pt = pt->next) != loop_pt); |
| 479 | if (outline_cn_counts != NULL) |
| 480 | outline_cn_counts->push_back(cn_features->size()); |
| 481 | } |
| 482 | results->NumBL = bl_features->size(); |
| 483 | results->NumCN = cn_features->size(); |
| 484 | results->YBottom = blob.bounding_box().bottom(); |
| 485 | results->YTop = blob.bounding_box().top(); |
| 486 | results->Width = blob.bounding_box().width(); |
| 487 | } |
| 488 | |
| 489 | } // namespace tesseract |
| 490 |
no test coverage detected