void find_components( BLOCK_LIST *blocks, TO_BLOCK_LIST *land_blocks, TO_BLOCK_LIST *port_blocks, TBOX *page_box) { BLOCK *block; //current block PDBLK_CLIST pd_blocks; //copy of list BLOCK_IT block_it = blocks; //iterator PDBLK_C_IT pd_it = &pd_blocks; //iterator IMAGE thresh_image; //thresholded int width = page_image.get_xsize(); int height = page_image.get_ysize(); if (width > MAX_INT16 || height > MAX_INT16) { tprintf("Input image too large! (%d, %d)\n", width, height); return; // Can't handle it. } ICOORD page_tr(width, height); block_it.set_to_list (blocks); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; set_global_loc_code(LOC_EDGE_PROG); if (!page_image.white_high ()) invert_image(&page_image); #ifndef EMBEDDED previous_cpu = clock (); #endif for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) { block = block_it.data(); if (block->poly_block() == NULL || block->poly_block()->IsText()) { #ifndef GRAPHICS_DISABLED extract_edges(NULL, &page_image, &page_image, page_tr, block); #else extract_edges(&page_image, &page_image, page_tr, block); #endif *page_box += block->bounding_box (); } } if (global_monitor != NULL) { global_monitor->ocr_alive = TRUE; global_monitor->progress = 10; } assign_blobs_to_blocks2(blocks, land_blocks, port_blocks); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; filter_blobs (page_box->topright (), land_blocks, textord_test_landscape); #ifndef EMBEDDED previous_cpu = clock (); #endif filter_blobs (page_box->topright (), port_blocks, !textord_test_landscape); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; }
/// Return a TBLOB * from the whole page_image. /// To be freed later with free_blob(). TBLOB *make_tesseract_blob(float baseline, float xheight, float descender, float ascender) { BLOCK *block = new BLOCK ("a character", TRUE, 0, 0, 0, 0, page_image.get_xsize(), page_image.get_ysize()); // Create C_BLOBs from the page extract_edges( #ifndef GRAPHICS_DISABLED NULL, #endif &page_image, &page_image, ICOORD(page_image.get_xsize(), page_image.get_ysize()), block); // Create one PBLOB from all C_BLOBs C_BLOB_LIST *list = block->blob_list(); C_BLOB_IT c_blob_it(list); PBLOB *pblob = new PBLOB; // will be (hopefully) deleted by the pblob_list for (c_blob_it.mark_cycle_pt(); !c_blob_it.cycled_list(); c_blob_it.forward()) { C_BLOB *c_blob = c_blob_it.data(); PBLOB c_as_p(c_blob, baseline + xheight); merge_blobs(pblob, &c_as_p); } PBLOB_LIST *pblob_list = new PBLOB_LIST; // will be deleted by the word PBLOB_IT pblob_it(pblob_list); pblob_it.add_after_then_move(pblob); // Normalize PBLOB WERD word(pblob_list, 0, " "); ROW *row = make_tess_ocrrow(baseline, xheight, descender, ascender); word.baseline_normalise(row); delete row; // Create a TBLOB from PBLOB return make_tess_blob(pblob, /* flatten: */ TRUE); }
// Perform steps to prepare underlying binary image/other data structures for // OCR. The current segmentation is required by this method. // Note that this method resets pix_binary_ to the original binarized image, // which may be different from the image actually used for OCR depending on the // value of devanagari_ocr_split_strategy. void Tesseract::PrepareForTessOCR(BLOCK_LIST* block_list, Tesseract* osd_tess, OSResults* osr) { // Find the max splitter strategy over all langs. ShiroRekhaSplitter::SplitStrategy max_ocr_strategy = static_cast<ShiroRekhaSplitter::SplitStrategy>( static_cast<inT32>(ocr_devanagari_split_strategy)); for (int i = 0; i < sub_langs_.size(); ++i) { ShiroRekhaSplitter::SplitStrategy ocr_strategy = static_cast<ShiroRekhaSplitter::SplitStrategy>( static_cast<inT32>(sub_langs_[i]->ocr_devanagari_split_strategy)); if (ocr_strategy > max_ocr_strategy) max_ocr_strategy = ocr_strategy; } // Utilize the segmentation information available. splitter_.set_segmentation_block_list(block_list); splitter_.set_ocr_split_strategy(max_ocr_strategy); // Run the splitter for OCR bool split_for_ocr = splitter_.Split(false); // Restore pix_binary to the binarized original pix for future reference. ASSERT_HOST(splitter_.orig_pix()); pixDestroy(&pix_binary_); pix_binary_ = pixClone(splitter_.orig_pix()); // If the pageseg and ocr strategies are different, refresh the block list // (from the last SegmentImage call) with blobs from the real image to be used // for OCR. if (splitter_.HasDifferentSplitStrategies()) { BLOCK block("", TRUE, 0, 0, 0, 0, pixGetWidth(pix_binary_), pixGetHeight(pix_binary_)); Pix* pix_for_ocr = split_for_ocr ? splitter_.splitted_image() : splitter_.orig_pix(); extract_edges(pix_for_ocr, &block); splitter_.RefreshSegmentationWithNewBlobs(block.blob_list()); } // The splitter isn't needed any more after this, so save memory by clearing. splitter_.Clear(); }
void Textord::find_components(Pix* pix, BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks) { int width = pixGetWidth(pix); int height = pixGetHeight(pix); if (width > INT16_MAX || height > INT16_MAX) { tprintf("Input image too large! (%d, %d)\n", width, height); return; // Can't handle it. } set_global_loc_code(LOC_EDGE_PROG); BLOCK_IT block_it(blocks); // iterator for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) { BLOCK* block = block_it.data(); if (block->pdblk.poly_block() == nullptr || block->pdblk.poly_block()->IsText()) { extract_edges(pix, block); } } assign_blobs_to_blocks2(pix, blocks, to_blocks); ICOORD page_tr(width, height); filter_blobs(page_tr, to_blocks, !textord_test_landscape); }
void edges_and_textord( //read .pb file const char *filename, //.pb file BLOCK_LIST *blocks) { BLOCK *block; //current block char *lastdot; //of name STRING name = filename; //truncated name ICOORD page_tr; BOX page_box; //bounding_box PDBLK_CLIST pd_blocks; //copy of list BLOCK_IT block_it = blocks; //iterator PDBLK_C_IT pd_it = &pd_blocks; //iterator //different orientations TO_BLOCK_LIST land_blocks, port_blocks; IMAGE thresh_image; //thresholded lastdot = strrchr (name.string (), '.'); if (lastdot != NULL) *lastdot = '\0'; if (page_image.get_bpp () == 0) { name += tessedit_image_ext; if (page_image.read_header (name.string ())) CANTOPENFILE.error ("edges_and_textord", EXIT, name.string ()); if (page_image.read (0)) READFAILED.error ("edges_and_textord", EXIT, name.string ()); name = filename; lastdot = strrchr (name.string (), '.'); if (lastdot != NULL) *lastdot = '\0'; } page_tr = ICOORD (page_image.get_xsize (), page_image.get_ysize ()); read_pd_file (name, page_image.get_xsize (), page_image.get_ysize (), blocks); block_it.set_to_list (blocks); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; if (page_image.get_bpp () > 1) { set_global_loc_code(LOC_ADAPTIVE); for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); pd_it.add_after_then_move (block); } // adaptive_threshold(&page_image,&pd_blocks,&thresh_image); set_global_loc_code(LOC_EDGE_PROG); #ifndef EMBEDDED previous_cpu = clock (); #endif for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); if (!polygon_tess_approximation) invert_image(&page_image); #ifndef GRAPHICS_DISABLED extract_edges(NO_WINDOW, &page_image, &thresh_image, page_tr, block); #else extract_edges(&page_image, &thresh_image, page_tr, block); #endif page_box += block->bounding_box (); } page_image = thresh_image; //everyone else gets it } else { set_global_loc_code(LOC_EDGE_PROG); if (!page_image.white_high ()) invert_image(&page_image); #ifndef EMBEDDED previous_cpu = clock (); #endif for (block_it.mark_cycle_pt (); !block_it.cycled_list (); block_it.forward ()) { block = block_it.data (); #ifndef GRAPHICS_DISABLED extract_edges(NO_WINDOW, &page_image, &page_image, page_tr, block); #else extract_edges(&page_image, &page_image, page_tr, block); #endif page_box += block->bounding_box (); } } if (global_monitor != NULL) { global_monitor->ocr_alive = TRUE; global_monitor->progress = 10; } assign_blobs_to_blocks2(blocks, &land_blocks, &port_blocks); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; filter_blobs (page_box.topright (), &land_blocks, textord_test_landscape); #ifndef EMBEDDED previous_cpu = clock (); #endif filter_blobs (page_box.topright (), &port_blocks, !textord_test_landscape); if (global_monitor != NULL) global_monitor->ocr_alive = TRUE; textord_page (page_box.topright (), blocks, &land_blocks, &port_blocks); }