28 #pragma warning(disable:4244) // Conversion warnings
36 #include "allheaders.h"
67 static Pix* RemoveEnclosingCircle(Pix* pixs) {
68 Pix* pixsi = pixInvert(
NULL, pixs);
69 Pix* pixc = pixCreateTemplate(pixs);
70 pixSetOrClearBorder(pixc, 1, 1, 1, 1, PIX_SET);
71 pixSeedfillBinary(pixc, pixc, pixsi, 4);
72 pixInvert(pixc, pixc);
74 Pix* pixt = pixAnd(
NULL, pixs, pixc);
76 pixCountConnComp(pixt, 8, &max_count);
82 pixErodeBrick(pixc, pixc, 3, 3);
83 pixt = pixAnd(
NULL, pixs, pixc);
85 pixCountConnComp(pixt, 8, &count);
86 if (i == 1 || count > max_count) {
89 }
else if (i > 1 && count < min_count) {
92 pixout = pixCopy(
NULL, pixt);
93 }
else if (count >= min_count) {
110 int width = pixGetWidth(pix_binary_);
111 int height = pixGetHeight(pix_binary_);
117 input_file !=
NULL && input_file->
length() > 0) {
118 STRING name = *input_file;
119 const char* lastdot = strrchr(name.
string(),
'.');
121 name[lastdot - name.
string()] =
'\0';
124 if (blocks->empty()) {
127 BLOCK_IT block_it(blocks);
130 block_it.add_to_end(block);
139 int auto_page_seg_ret_val = 0;
140 TO_BLOCK_LIST to_blocks;
142 auto_page_seg_ret_val =
144 blocks, &to_blocks, osd_tess, osr);
146 return auto_page_seg_ret_val;
153 Pix* pixcleaned = RemoveEnclosingCircle(pix_binary_);
154 if (pixcleaned !=
NULL) {
155 pixDestroy(&pix_binary_);
156 pix_binary_ = pixcleaned;
161 if (auto_page_seg_ret_val < 0) {
165 if (blocks->empty()) {
171 textord_.
TextordPage(pageseg_mode, width, height, pix_binary_,
173 return auto_page_seg_ret_val;
181 static void WriteDebugBackgroundImage(
bool printable, Pix* pix_binary) {
182 Pix* grey_pix = pixCreate(pixGetWidth(pix_binary),
183 pixGetHeight(pix_binary), 8);
188 pixSetMasked(grey_pix, pix_binary, 192);
190 pixSetAllArbitrary(grey_pix, 64);
191 pixSetMasked(grey_pix, pix_binary, 0);
195 pixDestroy(&grey_pix);
219 BLOCK_LIST* blocks, TO_BLOCK_LIST* to_blocks,
224 Pix* photomask_pix =
NULL;
225 Pix* musicmask_pix =
NULL;
227 BLOCK_LIST found_blocks;
228 TO_BLOCK_LIST temp_blocks;
231 single_column, osd, only_osd, blocks, osd_tess, osr,
232 &temp_blocks, &photomask_pix, &musicmask_pix);
233 if (finder !=
NULL) {
234 TO_BLOCK_IT to_block_it(&temp_blocks);
235 TO_BLOCK* to_block = to_block_it.data();
236 if (musicmask_pix !=
NULL) {
239 pixOr(photomask_pix, photomask_pix, musicmask_pix);
244 if (finder->
FindBlocks(single_column, scaled_color_, scaled_factor_,
245 to_block, photomask_pix,
246 &found_blocks, to_blocks) < 0) {
247 pixDestroy(&photomask_pix);
248 pixDestroy(&musicmask_pix);
254 pixDestroy(&photomask_pix);
255 pixDestroy(&musicmask_pix);
257 BLOCK_IT block_it(blocks);
259 block_it.add_list_after(&found_blocks);
282 bool single_column,
bool osd,
bool only_osd,
284 TO_BLOCK_LIST* to_blocks, Pix** photo_mask_pix, Pix** music_mask_pix) {
287 TabVector_LIST v_lines;
288 TabVector_LIST h_lines;
293 pixWrite(
"tessinput.png", pix_binary_, IFF_PNG);
298 &vertical_x, &vertical_y, music_mask_pix,
301 pixWrite(
"tessnolines.png", pix_binary_, IFF_PNG);
305 pixWrite(
"tessnoimages.png", pix_binary_, IFF_PNG);
312 TO_BLOCK_IT to_block_it(to_blocks);
316 TO_BLOCK* to_block = to_block_it.data();
317 TBOX blkbox = to_block->block->bounding_box();
320 if (to_block->line_size >= 2) {
321 finder =
new ColumnFinder(static_cast<int>(to_block->line_size),
324 &v_lines, &h_lines, vertical_x, vertical_y);
332 BLOBNBOX_CLIST osd_blobs;
337 int osd_orientation = 0;
339 if (osd && osd_tess !=
NULL && osr !=
NULL) {
348 for (
int i = 0; i < 4; ++i) {
349 if (i != osd_orientation &&
361 if (!cjk && !vertical_text && osd_orientation == 2) {
363 tprintf(
"OSD: Weak margin (%.2f), horiz textlines, not CJK: "
364 "Don't rotate.\n", osd_margin);
367 tprintf(
"OSD: Weak margin (%.2f) for %d blob text block, "
368 "but using orientation anyway: %d\n",
369 osd_blobs.length(), osd_margin, osd_orientation);
373 osd_blobs.shallow_clear();
int tessedit_pageseg_mode
bool tessedit_dump_pageseg_images
static void IncrementDebugPix()
#define PSM_OSD_ENABLED(pageseg_mode)
bool textord_tabfind_show_vlines
bool read_unlv_file(STRING name, inT32 xsize, inT32 ysize, BLOCK_LIST *blocks)
#define PSM_COL_FIND_ENABLED(pageseg_mode)
void SetupAndFilterNoise(Pix *photo_mask_pix, TO_BLOCK *input_block)
int FindBlocks(bool single_column, Pix *scaled_color, int scaled_factor, TO_BLOCK *block, Pix *photo_mask_pix, BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks)
#define PSM_BLOCK_FIND_ENABLED(pageseg_mode)
bool textord_debug_images
void SetEquationDetect(EquationDetectBase *detect)
void TextordPage(PageSegMode pageseg_mode, int width, int height, Pix *pix, BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks)
bool right_to_left() const
int textord_debug_tabfind
int AutoPageSeg(bool single_column, bool osd, bool only_osd, BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks, Tesseract *osd_tess, OSResults *osr)
void set_right_to_left(bool value)
void GetDeskewVectors(FCOORD *deskew, FCOORD *reskew)
const ICOORD & topright() const
void CorrectOrientation(TO_BLOCK *block, bool vertical_text_lines, int recognition_rotation)
Orientation and script detection only.
bool textord_debug_printable
void find_components(Pix *pix, BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks)
const char * string() const
const ICOORD & botleft() const
DLLSYM void tprintf(const char *format,...)
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)
Treat the image as a single word in a circle.
bool IsVerticallyAlignedText(TO_BLOCK *block, BLOBNBOX_CLIST *osd_blobs)
static const STRING & textord_debug_pix()
const int kMinCredibleResolution
Minimum believable resolution.
ColumnFinder * SetupPageSegAndDetectOrientation(bool single_column, bool osd, bool only_osd, BLOCK_LIST *blocks, Tesseract *osd_tess, OSResults *osr, TO_BLOCK_LIST *to_blocks, Pix **photo_mask_pix, Pix **music_mask_pix)
double min_orientation_margin
static Pix * FindImages(Pix *pix)
int os_detect_blobs(BLOBNBOX_CLIST *blob_list, OSResults *osr, tesseract::Tesseract *tess)
const int kMaxCircleErosions
int SegmentPage(const STRING *input_file, BLOCK_LIST *blocks, Tesseract *osd_tess, OSResults *osr)
Assume a single uniform block of text. (Default.)
int LabelSpecialText(TO_BLOCK *to_block)
const int kDefaultResolution
Default resolution used if input in not believable.