📄 oldbasel.cpp
字号:
int pointcount; /*no of coords */ int xstarts[SPLINESIZE + 1]; //segment boundaries int segments; //no of segments //no of blobs in row blobcount = row->blob_list ()->length (); partids = (char *) alloc_mem (blobcount * sizeof (char)); xcoords = (int *) alloc_mem (blobcount * sizeof (int)); ycoords = (int *) alloc_mem (blobcount * sizeof (int)); blobcoords = (BOX *) alloc_mem (blobcount * sizeof (BOX)); ydiffs = (float *) alloc_mem (blobcount * sizeof (float)); lineheight = get_blob_coords (row, (int) block->line_size, blobcoords, holed_line, blobcount); /*limit for line change */ jumplimit = lineheight * textord_oldbl_jumplimit; if (jumplimit < MINASCRISE) jumplimit = MINASCRISE; if (textord_oldbl_debug) { tprintf ("\nInput height=%g, Estimate x-height=%d pixels, jumplimit=%.2f\n", block->line_size, lineheight, jumplimit); } if (holed_line) make_holed_baseline (blobcoords, blobcount, spline, &row->baseline, row->line_m ()); else make_first_baseline (blobcoords, blobcount, xcoords, ycoords, spline, &row->baseline, jumplimit);#ifndef GRAPHICS_DISABLED if (textord_show_final_rows) row->baseline.plot (to_win, GOLDENROD);#endif if (blobcount > 1) { bestpart = partition_line (blobcoords, blobcount, &partcount, partids, partsizes, &row->baseline, jumplimit, ydiffs); pointcount = partition_coords (blobcoords, blobcount, partids, bestpart, xcoords, ycoords); segments = segment_spline (blobcoords, blobcount, xcoords, ycoords, degree, pointcount, xstarts); if (!holed_line) { do { row->baseline = QSPLINE (xstarts, segments, xcoords, ycoords, pointcount, degree); } while (textord_oldbl_split_splines && split_stepped_spline (&row->baseline, jumplimit / 2, xcoords, xstarts, segments)); } find_lesser_parts(row, blobcoords, blobcount, partids, partsizes, partcount, bestpart); } else { row->xheight = -1.0f; /*failed */ row->descdrop = 0.0f; row->ascrise = 0.0f; } row->baseline.extrapolate (row->line_m (), block->block->bounding_box ().left (), block->block->bounding_box ().right ()); if (textord_really_old_xheight) old_first_xheight (row, blobcoords, lineheight, blobcount, &row->baseline, jumplimit); else make_first_xheight (row, blobcoords, lineheight, (int) block->line_size, blobcount, &row->baseline, jumplimit); free_mem(partids); free_mem(xcoords); free_mem(ycoords); free_mem(blobcoords); free_mem(ydiffs);}/********************************************************************** * get_blob_coords * * Fill the blobcoords array with the coordinates of the blobs * in the row. The return value is the first guess atthe line height. **********************************************************************/int get_blob_coords( //get boxes TO_ROW *row, //row to use INT32 lineheight, //block level BOX *blobcoords, //ouput boxes BOOL8 &holed_line, //lost a lot of blobs int &outcount //no of real blobs ) { //blobs BLOBNBOX_IT blob_it = row->blob_list (); register int blobindex; /*no along text line */ int losscount; //lost blobs int maxlosscount; //greatest lost blobs /*height stat collection */ STATS heightstat (0, MAXHEIGHT); if (blob_it.empty ()) return 0; //none maxlosscount = 0; losscount = 0; blob_it.mark_cycle_pt (); blobindex = 0; do { blobcoords[blobindex] = box_next_pre_chopped (&blob_it); if (blobcoords[blobindex].height () > lineheight * 0.25) heightstat.add (blobcoords[blobindex].height (), 1); if (blobindex == 0 || blobcoords[blobindex].height () > lineheight * 0.25 || blob_it.cycled_list ()) { blobindex++; /*no of merged blobs */ losscount = 0; } else { if (blobcoords[blobindex].height () < blobcoords[blobindex].width () * oldbl_dot_error_size && blobcoords[blobindex].width () < blobcoords[blobindex].height () * oldbl_dot_error_size) { //counts as dot blobindex++; losscount = 0; } else { losscount++; //lost it if (losscount > maxlosscount) //remember max maxlosscount = losscount; } } } while (!blob_it.cycled_list ()); holed_line = maxlosscount > oldbl_holed_losscount; outcount = blobindex; /*total blobs */ if (heightstat.get_total () > 1) /*guess x-height */ return (int) heightstat.ile (0.25); else return blobcoords[0].height ();}/********************************************************************** * make_first_baseline * * Make the first estimate at a baseline, either by shifting * a supplied previous spline, or by doing a piecewise linear * approximation using all the blobs. **********************************************************************/voidmake_first_baseline ( //initial approximationBOX blobcoords[], /*blob bounding boxes */int blobcount, /*no of blobcoords */int xcoords[], /*coords for spline */int ycoords[], /*approximator */QSPLINE * spline, /*initial spline */QSPLINE * baseline, /*output spline */float jumplimit /*guess half descenders */) { int leftedge; /*left edge of line */ int rightedge; /*right edge of line */ int blobindex; /*current blob */ int segment; /*current segment */ float prevy, thisy, nexty; /*3 y coords */ float y1, y2, y3; /*3 smooth blobs */ float maxmax, minmin; /*absolute limits */ int x2 = 0; /*right edge of old y3 */ int ycount; /*no of ycoords in use */ float yturns[SPLINESIZE]; /*y coords of turn pts */ int xturns[SPLINESIZE]; /*xcoords of turn pts */ int xstarts[SPLINESIZE + 1]; int segments; //no of segments ICOORD shift; //shift of spline prevy = 0; /*left edge of row */ leftedge = blobcoords[0].left (); /*right edge of line */ rightedge = blobcoords[blobcount - 1].right (); if (spline == NULL /*no given spline */ || spline->segments < 3 /*or trivial */ /*or too non-overlap */ || spline->xcoords[1] > leftedge + MAXOVERLAP * (rightedge - leftedge) || spline->xcoords[spline->segments - 1] < rightedge - MAXOVERLAP * (rightedge - leftedge)) { if (textord_oldbl_paradef) return; //use default xstarts[0] = blobcoords[0].left () - 1; for (blobindex = 0; blobindex < blobcount; blobindex++) { xcoords[blobindex] = (blobcoords[blobindex].left () + blobcoords[blobindex].right ()) / 2; ycoords[blobindex] = blobcoords[blobindex].bottom (); } xstarts[1] = blobcoords[blobcount - 1].right () + 1; segments = 1; /*no of segments */ /*linear */ *baseline = QSPLINE (xstarts, segments, xcoords, ycoords, blobcount, 1); if (blobcount >= 3) { y1 = y2 = y3 = 0.0f; ycount = 0; segment = 0; /*no of segments */ maxmax = minmin = 0.0f; thisy = ycoords[0] - baseline->y (xcoords[0]); nexty = ycoords[1] - baseline->y (xcoords[1]); for (blobindex = 2; blobindex < blobcount; blobindex++) { prevy = thisy; /*shift ycoords */ thisy = nexty; nexty = ycoords[blobindex] - baseline->y (xcoords[blobindex]); /*middle of smooth y */ if (ABS (thisy - prevy) < jumplimit && ABS (thisy - nexty) < jumplimit) { y1 = y2; /*shift window */ y2 = y3; y3 = thisy; /*middle point */ ycount++; /*local max */ if (ycount >= 3 && (y1 < y2 && y2 >= y3 /*local min */ || y1 > y2 && y2 <= y3)) { if (segment < SPLINESIZE - 2) { /*turning pt */ xturns[segment] = x2; yturns[segment] = y2; segment++; /*no of spline segs */ } } if (ycount == 1) { maxmax = minmin = y3;/*initialise limits */ } else { if (y3 > maxmax) maxmax = y3; /*biggest max */ if (y3 < minmin) minmin = y3; /*smallest min */ } /*possible turning pt */ x2 = blobcoords[blobindex - 1].right (); } } jumplimit *= 1.2; /*must be wavy */ if (maxmax - minmin > jumplimit) { ycount = segment; /*no of segments */ for (blobindex = 0, segment = 1; blobindex < ycount; blobindex++) { if (yturns[blobindex] > minmin + jumplimit || yturns[blobindex] < maxmax - jumplimit) { /*significant peak */ if (segment == 1 || yturns[blobindex] > prevy + jumplimit || yturns[blobindex] < prevy - jumplimit) { /*different to previous */ xstarts[segment] = xturns[blobindex]; segment++; prevy = yturns[blobindex]; } /*bigger max */ else if (prevy > minmin + jumplimit && yturns[blobindex] > prevy /*smaller min */ || prevy < maxmax - jumplimit && yturns[blobindex] < prevy) { xstarts[segment - 1] = xturns[blobindex]; /*improved previous */ prevy = yturns[blobindex]; } } } xstarts[segment] = blobcoords[blobcount - 1].right () + 1; segments = segment; /*no of segments */ /*linear */ *baseline = QSPLINE (xstarts, segments, xcoords, ycoords, blobcount, 1); } } } else { *baseline = *spline; /*copy it */ shift = ICOORD (0, (INT16) (blobcoords[0].bottom () - spline->y (blobcoords[0].right ()))); baseline->move (shift); }}/********************************************************************** * make_holed_baseline * * Make the first estimate at a baseline, either by shifting * a supplied previous spline, or by doing a piecewise linear * approximation using all the blobs. **********************************************************************/voidmake_holed_baseline ( //initial approximationBOX blobcoords[], /*blob bounding boxes */int blobcount, /*no of blobcoords */QSPLINE * spline, /*initial spline */QSPLINE * baseline, /*output spline */float gradient //of line) { int leftedge; /*left edge of line */ int rightedge; /*right edge of line */ int blobindex; /*current blob */ float x; //centre of row ICOORD shift; //shift of spline LMS lms(blobcount); //straight baseline INT32 xstarts[2]; //straight line double coeffs[3]; float c; //line parameter /*left edge of row */ leftedge = blobcoords[0].left (); /*right edge of line */ rightedge = blobcoords[blobcount - 1].right (); for (blobindex = 0; blobindex < blobcount; blobindex++) { lms.add (FCOORD ((blobcoords[blobindex].left () + blobcoords[blobindex].right ()) / 2.0, blobcoords[blobindex].bottom ())); } lms.constrained_fit (gradient, c); xstarts[0] = leftedge; xstarts[1] = rightedge; coeffs[0] = 0; coeffs[1] = gradient; coeffs[2] = c; *baseline = QSPLINE (1, xstarts, coeffs); if (spline != NULL /*no given spline */ && spline->segments >= 3 /*or trivial */ /*or too non-overlap */ && spline->xcoords[1] <= leftedge + MAXOVERLAP * (rightedge - leftedge) && spline->xcoords[spline->segments - 1] >= rightedge
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -