Tesseract
3.02
|
#include <linefind.h>
Static Public Member Functions | |
static void | FindAndRemoveLines (int resolution, bool debug, Pix *pix, int *vertical_x, int *vertical_y, Pix **pix_music_mask, TabVector_LIST *v_lines, TabVector_LIST *h_lines) |
static void | ConvertBoxaToBlobs (int image_width, int image_height, Boxa **boxes, C_BLOB_LIST *blobs) |
The LineFinder class is a simple static function wrapper class that mainly exposes the FindVerticalLines function.
Definition at line 39 of file linefind.h.
void tesseract::LineFinder::ConvertBoxaToBlobs | ( | int | image_width, |
int | image_height, | ||
Boxa ** | boxes, | ||
C_BLOB_LIST * | blobs | ||
) | [static] |
Converts the Boxa array to a list of C_BLOB, getting rid of severely overlapping outlines and those that are children of a bigger one.
The output is a list of C_BLOBs that are owned by the list.
The C_OUTLINEs in the C_BLOBs contain no outline data - just empty bounding boxes. The Boxa is consumed and destroyed.
Definition at line 321 of file linefind.cpp.
{ C_OUTLINE_LIST outlines; C_OUTLINE_IT ol_it = &outlines; // Iterate the boxes to convert to outlines. int nboxes = boxaGetCount(*boxes); for (int i = 0; i < nboxes; ++i) { l_int32 x, y, width, height; boxaGetBoxGeometry(*boxes, i, &x, &y, &width, &height); // Make a C_OUTLINE from the leptonica box. This is a bit of a hack, // as there is no outline, just a bounding box, but with some very // small changes to coutln.cpp, it works nicely. ICOORD top_left(x, y); ICOORD bot_right(x + width, y + height); CRACKEDGE startpt; startpt.pos = top_left; C_OUTLINE* outline = new C_OUTLINE(&startpt, top_left, bot_right, 0); ol_it.add_after_then_move(outline); } // Use outlines_to_blobs to convert the outlines to blobs and find // overlapping and contained objects. The output list of blobs in the block // has all the bad ones filtered out and deleted. BLOCK block; ICOORD page_tl(0, 0); ICOORD page_br(image_width, image_height); outlines_to_blobs(&block, page_tl, page_br, &outlines); // Transfer the created blobs to the output list. C_BLOB_IT blob_it(blobs); blob_it.add_list_after(block.blob_list()); // The boxes aren't needed any more. boxaDestroy(boxes); }
void tesseract::LineFinder::FindAndRemoveLines | ( | int | resolution, |
bool | debug, | ||
Pix * | pix, | ||
int * | vertical_x, | ||
int * | vertical_y, | ||
Pix ** | pix_music_mask, | ||
TabVector_LIST * | v_lines, | ||
TabVector_LIST * | h_lines | ||
) | [static] |
Finds vertical and horizontal line objects in the given pix and removes them.
Uses the given resolution to determine size thresholds instead of any that may be present in the pix.
The output vertical_x and vertical_y contain a sum of the output vectors, thereby giving the mean vertical direction.
If pix_music_mask != NULL, and music is detected, a mask of the staves and anything that is connected (bars, notes etc.) will be returned in pix_music_mask, the mask subtracted from pix, and the lines will not appear in v_lines or h_lines.
The output vectors are owned by the list and Frozen (cannot refit) by having no boxes, as there is no need to refit or merge separator lines.
The detected lines are removed from the pix.
Definition at line 243 of file linefind.cpp.
{ if (pix == NULL || vertical_x == NULL || vertical_y == NULL) { tprintf("Error in parameters for LineFinder::FindAndRemoveLines\n"); return; } Pix* pix_vline = NULL; Pix* pix_non_vline = NULL; Pix* pix_hline = NULL; Pix* pix_non_hline = NULL; Pix* pix_intersections = NULL; Pixa* pixa_display = debug ? pixaCreate(0) : NULL; GetLineMasks(resolution, pix, &pix_vline, &pix_non_vline, &pix_hline, &pix_non_hline, &pix_intersections, pix_music_mask, pixa_display); // Find lines, convert to TabVector_LIST and remove those that are used. FindAndRemoveVLines(resolution, pix_intersections, vertical_x, vertical_y, &pix_vline, pix_non_vline, pix, v_lines); if (pix_hline != NULL) { // Recompute intersections and re-filter false positive h-lines. if (pix_vline != NULL) pixAnd(pix_intersections, pix_vline, pix_hline); else pixDestroy(&pix_intersections); if (!FilterFalsePositives(resolution, pix_non_hline, pix_intersections, pix_hline)) { pixDestroy(&pix_hline); } } FindAndRemoveHLines(resolution, pix_intersections, *vertical_x, *vertical_y, &pix_hline, pix_non_hline, pix, h_lines); if (pixa_display != NULL && pix_vline != NULL) pixaAddPix(pixa_display, pix_vline, L_CLONE); if (pixa_display != NULL && pix_hline != NULL) pixaAddPix(pixa_display, pix_hline, L_CLONE); if (pix_vline != NULL && pix_hline != NULL) { // Remove joins (intersections) where lines cross, and the residue. // Recalculate the intersections, since some lines have been deleted. pixAnd(pix_intersections, pix_vline, pix_hline); // Fatten up the intersections and seed-fill to get the intersection // residue. Pix* pix_join_residue = pixDilateBrick(NULL, pix_intersections, 5, 5); pixSeedfillBinary(pix_join_residue, pix_join_residue, pix, 8); // Now remove the intersection residue. pixSubtract(pix, pix, pix_join_residue); pixDestroy(&pix_join_residue); } // Remove any detected music. if (pix_music_mask != NULL && *pix_music_mask != NULL) { if (pixa_display != NULL) pixaAddPix(pixa_display, *pix_music_mask, L_CLONE); pixSubtract(pix, pix, *pix_music_mask); } if (pixa_display != NULL) pixaAddPix(pixa_display, pix, L_CLONE); pixDestroy(&pix_vline); pixDestroy(&pix_non_vline); pixDestroy(&pix_hline); pixDestroy(&pix_non_hline); pixDestroy(&pix_intersections); if (pixa_display != NULL) { #if LIBLEPT_MINOR_VERSION >= 69 || LIBLEPT_MAJOR_VERSION > 1 pixaConvertToPdf(pixa_display, resolution, 1.0f, 0, 0, "LineFinding", "vhlinefinding.pdf"); #endif pixaDestroy(&pixa_display); } }