BLOB_CHOICE* M_Utils::runBlobOCR(BLOBNBOX* blob, Tesseract* ocrengine) { // * Normalize blob height to x-height (current OSD): // SetupNormalization(NULL, NULL, &rotation, NULL, NULL, 0, // box.rotational_x_middle(rotation), // box.rotational_y_middle(rotation), // kBlnXHeight / box.rotational_height(rotation), // kBlnXHeight / box.rotational_height(rotation), // 0, kBlnBaselineOffset); BLOB_CHOICE_LIST ratings_lang; C_BLOB* cblob = blob->cblob(); TBLOB* tblob = TBLOB::PolygonalCopy(cblob); const TBOX& box = tblob->bounding_box(); // Normalize the blob. Set the origin to the place we want to be the // bottom-middle, and scaling is to mpx, box_, NULL); float scaling = static_cast<float>(kBlnXHeight) / box.height(); DENORM denorm; float x_orig = (box.left() + box.right()) / 2.0f, y_orig = box.bottom(); denorm.SetupNormalization(NULL, NULL, NULL, NULL, NULL, 0, x_orig, y_orig, scaling, scaling, 0.0f, static_cast<float>(kBlnBaselineOffset)); TBLOB* normed_blob = new TBLOB(*tblob); normed_blob->Normalize(denorm); ocrengine->AdaptiveClassifier(normed_blob, denorm, &ratings_lang, NULL); delete normed_blob; delete tblob; // Get the best choice from ratings_lang and rating_equ. As the choice in the // list has already been sorted by the certainty, we simply use the first // choice. BLOB_CHOICE *lang_choice = NULL; if (ratings_lang.length() > 0) { BLOB_CHOICE_IT choice_it(&ratings_lang); lang_choice = choice_it.data(); } return lang_choice; }
// Normalizes the blob for classification only if needed. // (Normally this means a non-zero classify rotation.) // If no Normalization is needed, then NULL is returned, and the denorm is // unchanged. Otherwise a new TBLOB is returned and the denorm points to // a new DENORM. In this case, both the TBLOB and DENORM must be deleted. TBLOB* TBLOB::ClassifyNormalizeIfNeeded(const DENORM** denorm) const { TBLOB* rotated_blob = NULL; // If necessary, copy the blob and rotate it. The rotation is always // +/- 90 degrees, as 180 was already taken care of. if ((*denorm)->block() != NULL && (*denorm)->block()->classify_rotation().y() != 0.0) { TBOX box = bounding_box(); int x_middle = (box.left() + box.right()) / 2; int y_middle = (box.top() + box.bottom()) / 2; rotated_blob = new TBLOB(*this); const FCOORD& rotation = (*denorm)->block()->classify_rotation(); DENORM* norm = new DENORM; // Move the rotated blob back to the same y-position so that we // can still distinguish similar glyphs with differeny y-position. float target_y = kBlnBaselineOffset + (rotation.y() > 0 ? x_middle - box.left() : box.right() - x_middle); norm->SetupNormalization(NULL, NULL, &rotation, *denorm, NULL, 0, x_middle, y_middle, 1.0f, 1.0f, 0.0f, target_y); // x_middle, y_middle, 1.0f, 1.0f, 0.0f, y_middle); rotated_blob->Normalize(*norm); *denorm = norm; } return rotated_blob; }