本文整理汇总了C++中pixClone函数的典型用法代码示例。如果您正苦于以下问题:C++ pixClone函数的具体用法?C++ pixClone怎么用?C++ pixClone使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了pixClone函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: main
int main(int argc,
char **argv) {
char buf[32];
char *filein, *fileout, *fontdir, *textstr;
l_int32 n, i, maxdepth, ntext, border, lossless, display, showtext;
l_float32 scalefact;
L_BMF *bmf;
PIX *pix1, *pix2, *pix3, *pix4, *pixd;
PIXA *pixa, *pixad;
static char mainName[] = "displaypixa";
if (argc != 3 && argc != 4 && argc != 7 && argc != 8) {
fprintf(stderr, "Syntax error in displaypixa:\n"
" displaypixa filein fileout [showtext]\n"
" displaypixa filein scalefact border"
" lossless disp fileout [showtext]\n");
return 1;
}
filein = argv[1];
if ((pixa = pixaRead(filein)) == NULL)
return ERROR_INT("pixa not made", mainName, 1);
pixaCountText(pixa, &ntext);
if (argc == 3 || argc == 4)
fileout = argv[2];
if (argc == 4)
showtext = atoi(argv[3]);
/* Simple specification; no output text */
if (argc == 3 ||
(argc == 4 && (ntext == 0 || showtext == 0))) { /* no text output */
pixaVerifyDepth(pixa, &maxdepth);
pixd = pixaDisplayTiledInRows(pixa, maxdepth, 1400, 1.0, 0, 10, 0);
pixDisplay(pixd, 100, 100);
if (pixGetDepth(pixd) == 1)
pixWrite(fileout, pixd, IFF_PNG);
else
pixWrite(fileout, pixd, IFF_JFIF_JPEG);
pixDestroy(&pixd);
pixaDestroy(&pixa);
return 0;
}
/* Simple specification with output text */
if (argc == 4) { /* showtext == 1 && ntext > 0 */
n = pixaGetCount(pixa);
bmf = bmfCreate(NULL, 6);
pixad = pixaCreate(n);
for (i = 0; i < n; i++) {
pix1 = pixaGetPix(pixa, i, L_CLONE);
pix2 = pixConvertTo32(pix1);
pix3 = pixAddBorderGeneral(pix2, 10, 10, 5, 5, 0xffffff00);
textstr = pixGetText(pix1);
if (textstr && strlen(textstr) > 0) {
snprintf(buf, sizeof(buf), "%s", textstr);
pix4 = pixAddSingleTextblock(pix3, bmf, buf, 0xff000000,
L_ADD_BELOW, NULL);
} else {
pix4 = pixClone(pix3);
}
pixaAddPix(pixad, pix4, L_INSERT);
pixDestroy(&pix1);
pixDestroy(&pix2);
pixDestroy(&pix3);
}
bmfDestroy(&bmf);
pixaVerifyDepth(pixad, &maxdepth);
pixd = pixaDisplayTiledInRows(pixad, maxdepth, 1400, 1.0, 0, 10, 0);
pixDisplay(pixd, 100, 100);
if (pixGetDepth(pixd) == 1)
pixWrite(fileout, pixd, IFF_PNG);
else
pixWrite(fileout, pixd, IFF_JFIF_JPEG);
pixDestroy(&pixd);
pixaDestroy(&pixa);
pixaDestroy(&pixad);
return 0;
}
/* Full specification */
scalefact = atof(argv[2]);
border = atoi(argv[3]);
lossless = atoi(argv[4]);
display = atoi(argv[5]);
fileout = argv[6];
showtext = (argc == 8) ? atoi(argv[7]) : 0;
if (showtext && ntext == 0)
L_INFO("No text found in any of the pix\n", mainName);
bmf = (showtext && ntext > 0) ? bmfCreate(NULL, 6) : NULL;
n = pixaGetCount(pixa);
pixad = pixaCreate(n);
for (i = 0; i < n; i++) {
pix1 = pixaGetPix(pixa, i, L_CLONE);
pix2 = pixConvertTo32(pix1);
pix3 = pixAddBorderGeneral(pix2, 10, 10, 5, 5, 0xffffff00);
textstr = pixGetText(pix1);
if (bmf && textstr && strlen(textstr) > 0) {
snprintf(buf, sizeof(buf), "%s", textstr);
pix4 = pixAddSingleTextblock(pix3, bmf, buf, 0xff000000,
//.........这里部分代码省略.........
示例2: main
int main(int argc,
char **argv)
{
char *filein, *fileout;
l_int32 ret;
l_float32 deg2rad;
l_float32 angle, conf, score;
PIX *pix, *pixs, *pixd;
static char mainName[] = "skewtest";
if (argc != 3)
return ERROR_INT(" Syntax: skewtest filein fileout", mainName, 1);
filein = argv[1];
fileout = argv[2];
setLeptDebugOK(1);
pixd = NULL;
deg2rad = 3.1415926535 / 180.;
if ((pixs = pixRead(filein)) == NULL)
return ERROR_INT("pixs not made", mainName, 1);
/* Find the skew angle various ways */
pix = pixConvertTo1(pixs, 130);
pixWrite("/tmp/binarized.tif", pix, IFF_TIFF_G4);
pixFindSkew(pix, &angle, &conf);
fprintf(stderr, "pixFindSkew():\n"
" conf = %5.3f, angle = %7.3f degrees\n", conf, angle);
pixFindSkewSweepAndSearchScorePivot(pix, &angle, &conf, &score,
SWEEP_REDUCTION2, SEARCH_REDUCTION,
0.0, SWEEP_RANGE2, SWEEP_DELTA2,
SEARCH_MIN_DELTA,
L_SHEAR_ABOUT_CORNER);
fprintf(stderr, "pixFind...Pivot(about corner):\n"
" conf = %5.3f, angle = %7.3f degrees, score = %f\n",
conf, angle, score);
pixFindSkewSweepAndSearchScorePivot(pix, &angle, &conf, &score,
SWEEP_REDUCTION2, SEARCH_REDUCTION,
0.0, SWEEP_RANGE2, SWEEP_DELTA2,
SEARCH_MIN_DELTA,
L_SHEAR_ABOUT_CENTER);
fprintf(stderr, "pixFind...Pivot(about center):\n"
" conf = %5.3f, angle = %7.3f degrees, score = %f\n",
conf, angle, score);
/* Use top-level */
pixd = pixDeskew(pixs, 0);
pixWriteImpliedFormat(fileout, pixd, 0, 0);
#if 0
/* Do it piecemeal; fails if outside the range */
if (pixGetDepth(pixs) == 1) {
pixd = pixDeskew(pix, DESKEW_REDUCTION);
pixWrite(fileout, pixd, IFF_PNG);
}
else {
ret = pixFindSkewSweepAndSearch(pix, &angle, &conf, SWEEP_REDUCTION2,
SEARCH_REDUCTION, SWEEP_RANGE2,
SWEEP_DELTA2, SEARCH_MIN_DELTA);
if (ret)
L_WARNING("skew angle not valid\n", mainName);
else {
fprintf(stderr, "conf = %5.3f, angle = %7.3f degrees\n",
conf, angle);
if (conf > 2.5)
pixd = pixRotate(pixs, angle * deg2rad, L_ROTATE_AREA_MAP,
L_BRING_IN_WHITE, 0, 0);
else
pixd = pixClone(pixs);
pixWrite(fileout, pixd, IFF_PNG);
pixDestroy(&pixd);
}
}
#endif
pixDestroy(&pixs);
pixDestroy(&pix);
pixDestroy(&pixd);
return 0;
}
示例3: pixRunlengthTransform
/*!
* pixRunlengthTransform()
*
* Input: pixs (1 bpp)
* color (0 for white runs, 1 for black runs)
* direction (L_HORIZONTAL_RUNS, L_VERTICAL_RUNS)
* depth (8 or 16 bpp)
* Return: pixd (8 or 16 bpp), or null on error
*
* Notes:
* (1) The dest Pix is 8 or 16 bpp, with the pixel values
* equal to the runlength in which it is a member.
* The length is clipped to the max pixel value if necessary.
* (2) The color determines if we're labelling white or black runs.
* (3) A pixel that is not a member of the chosen color gets
* value 0; it belongs to a run of length 0 of the
* chosen color.
* (4) To convert for maximum dynamic range, either linear or
* log, use pixMaxDynamicRange().
*/
PIX *
pixRunlengthTransform(PIX *pixs,
l_int32 color,
l_int32 direction,
l_int32 depth) {
l_int32 i, j, w, h, wpld, bufsize, maxsize, n;
l_int32 *start, *end, *buffer;
l_uint32 *datad, *lined;
PIX *pixt, *pixd;
PROCNAME("pixRunlengthTransform");
if (!pixs)
return (PIX *) ERROR_PTR("pixs not defined", procName, NULL);
if (pixGetDepth(pixs) != 1)
return (PIX *) ERROR_PTR("pixs not 1 bpp", procName, NULL);
if (depth != 8 && depth != 16)
return (PIX *) ERROR_PTR("depth must be 8 or 16 bpp", procName, NULL);
pixGetDimensions(pixs, &w, &h, NULL);
if (direction == L_HORIZONTAL_RUNS)
maxsize = 1 + w / 2;
else if (direction == L_VERTICAL_RUNS)
maxsize = 1 + h / 2;
else
return (PIX *) ERROR_PTR("invalid direction", procName, NULL);
bufsize = L_MAX(w, h);
if ((pixd = pixCreate(w, h, depth)) == NULL)
return (PIX *) ERROR_PTR("pixd not made", procName, NULL);
datad = pixGetData(pixd);
wpld = pixGetWpl(pixd);
if ((start = (l_int32 *) CALLOC(maxsize, sizeof(l_int32))) == NULL)
return (PIX *) ERROR_PTR("start not made", procName, NULL);
if ((end = (l_int32 *) CALLOC(maxsize, sizeof(l_int32))) == NULL)
return (PIX *) ERROR_PTR("end not made", procName, NULL);
if ((buffer = (l_int32 *) CALLOC(bufsize, sizeof(l_int32))) == NULL)
return (PIX *) ERROR_PTR("buffer not made", procName, NULL);
/* Use fg runs for evaluation */
if (color == 0)
pixt = pixInvert(NULL, pixs);
else
pixt = pixClone(pixs);
if (direction == L_HORIZONTAL_RUNS) {
for (i = 0; i < h; i++) {
pixFindHorizontalRuns(pixt, i, start, end, &n);
runlengthMembershipOnLine(buffer, w, depth, start, end, n);
lined = datad + i * wpld;
if (depth == 8) {
for (j = 0; j < w; j++)
SET_DATA_BYTE(lined, j, buffer[j]);
} else { /* depth == 16 */
for (j = 0; j < w; j++)
SET_DATA_TWO_BYTES(lined, j, buffer[j]);
}
}
} else { /* L_VERTICAL_RUNS */
for (j = 0; j < w; j++) {
pixFindVerticalRuns(pixt, j, start, end, &n);
runlengthMembershipOnLine(buffer, h, depth, start, end, n);
if (depth == 8) {
for (i = 0; i < h; i++) {
lined = datad + i * wpld;
SET_DATA_BYTE(lined, j, buffer[i]);
}
} else { /* depth == 16 */
for (i = 0; i < h; i++) {
lined = datad + i * wpld;
SET_DATA_TWO_BYTES(lined, j, buffer[i]);
}
}
}
}
pixDestroy(&pixt);
FREE(start);
FREE(end);
//.........这里部分代码省略.........
示例4: pixGenerateSelRandom
/*!
* pixGenerateSelRandom()
*
* Input: pix (1 bpp, typically small, to be used as a pattern)
* hitfract (fraction of allowable fg pixels that are hits)
* missfract (fraction of allowable bg pixels that are misses)
* distance (min distance from boundary pixel; use 0 for default)
* toppix (number of extra pixels of bg added above)
* botpix (number of extra pixels of bg added below)
* leftpix (number of extra pixels of bg added to left)
* rightpix (number of extra pixels of bg added to right)
* &pixe (<optional return> input pix expanded by extra pixels)
* Return: sel (hit-miss for input pattern), or null on error
*
* Notes:
* (1) Either of hitfract and missfract can be zero. If both are zero,
* the sel would be empty, and NULL is returned.
* (2) No elements are selected that are less than 'distance' pixels away
* from a boundary pixel of the same color. This makes the
* match much more robust to edge noise. Valid inputs of
* 'distance' are 0, 1, 2, 3 and 4. If distance is either 0 or
* greater than 4, we reset it to the default value.
* (3) The 4 numbers for adding rectangles of pixels outside the fg
* can be use if the pattern is expected to be surrounded by bg
* (white) pixels. On the other hand, if the pattern may be near
* other fg (black) components on some sides, use 0 for those sides.
* (4) The input pix, as extended by the extra pixels on selected sides,
* can optionally be returned. For debugging, call
* pixDisplayHitMissSel() to visualize the hit-miss sel superimposed
* on the generating bitmap.
*/
SEL *
pixGenerateSelRandom(PIX *pixs,
l_float32 hitfract,
l_float32 missfract,
l_int32 distance,
l_int32 toppix,
l_int32 botpix,
l_int32 leftpix,
l_int32 rightpix,
PIX **ppixe)
{
l_int32 ws, hs, w, h, x, y, i, j, thresh;
l_uint32 val;
PIX *pixt1, *pixt2, *pixfg, *pixbg;
SEL *seld, *sel;
PROCNAME("pixGenerateSelRandom");
if (ppixe) *ppixe = NULL;
if (!pixs)
return (SEL *)ERROR_PTR("pixs not defined", procName, NULL);
if (pixGetDepth(pixs) != 1)
return (SEL *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
if (hitfract <= 0.0 && missfract <= 0.0)
return (SEL *)ERROR_PTR("no hits or misses", procName, NULL);
if (hitfract > 1.0 || missfract > 1.0)
return (SEL *)ERROR_PTR("fraction can't be > 1.0", procName, NULL);
if (distance <= 0)
distance = DEFAULT_DISTANCE_TO_BOUNDARY;
if (distance > MAX_DISTANCE_TO_BOUNDARY) {
L_WARNING("distance too large; setting to max value", procName);
distance = MAX_DISTANCE_TO_BOUNDARY;
}
/* Locate the foreground */
pixClipToForeground(pixs, &pixt1, NULL);
if (!pixt1)
return (SEL *)ERROR_PTR("pixt1 not made", procName, NULL);
ws = pixGetWidth(pixt1);
hs = pixGetHeight(pixt1);
w = ws;
h = hs;
/* Crop out a region including the foreground, and add pixels
* on sides depending on the side flags */
if (toppix || botpix || leftpix || rightpix) {
x = y = 0;
if (toppix) {
h += toppix;
y = toppix;
}
if (botpix)
h += botpix;
if (leftpix) {
w += leftpix;
x = leftpix;
}
if (rightpix)
w += rightpix;
pixt2 = pixCreate(w, h, 1);
pixRasterop(pixt2, x, y, ws, hs, PIX_SRC, pixt1, 0, 0);
}
else
pixt2 = pixClone(pixt1);
if (ppixe)
*ppixe = pixClone(pixt2);
pixDestroy(&pixt1);
//.........这里部分代码省略.........
示例5: pixOtsuAdaptiveThreshold
//.........这里部分代码省略.........
* For this situation, the smoothing parameters are ignored.
* (5) The threshold values partition the image pixels into two classes:
* one whose values are less than the threshold and another
* whose values are greater than or equal to the threshold.
* This is the same use of 'threshold' as in pixThresholdToBinary().
* (6) The scorefract is the fraction of the maximum Otsu score, which
* is used to determine the range over which the histogram minimum
* is searched. See numaSplitDistribution() for details on the
* underlying method of choosing a threshold.
* (7) This uses enables a modified version of the Otsu criterion for
* splitting the distribution of pixels in each tile into a
* fg and bg part. The modification consists of searching for
* a minimum in the histogram over a range of pixel values where
* the Otsu score is within a defined fraction, @scorefract,
* of the max score. To get the original Otsu algorithm, set
* @scorefract == 0.
*/
l_int32
pixOtsuAdaptiveThreshold(PIX *pixs,
l_int32 sx,
l_int32 sy,
l_int32 smoothx,
l_int32 smoothy,
l_float32 scorefract,
PIX **ppixth,
PIX **ppixd)
{
l_int32 w, h, nx, ny, i, j, thresh;
l_uint32 val;
PIX *pixt, *pixb, *pixthresh, *pixth, *pixd;
PIXTILING *pt;
PROCNAME("pixOtsuAdaptiveThreshold");
if (!ppixth && !ppixd){
return ERROR_INT("neither &pixth nor &pixd defined", procName, 1);
LOGE("neither &pixth nor &pixd defined");
}
if (ppixth) *ppixth = NULL;
if (ppixd) *ppixd = NULL;
if (!pixs || pixGetDepth(pixs) != 8){
return ERROR_INT("pixs not defined or not 8 bpp", procName, 1);
LOGE("pixs not defined or not 8 bpp");
}
if (sx < 16 || sy < 16){
return ERROR_INT("sx and sy must be >= 16", procName, 1);
LOGE("sx and sy must be >= 16");
}
/* Compute the threshold array for the tiles */
pixGetDimensions(pixs, &w, &h, NULL);
nx = L_MAX(1, w / sx);
ny = L_MAX(1, h / sy);
smoothx = L_MIN(smoothx, (nx - 1) / 2);
smoothy = L_MIN(smoothy, (ny - 1) / 2);
pt = pixTilingCreate(pixs, nx, ny, 0, 0, 0, 0);
pixthresh = pixCreate(nx, ny, 8);
for (i = 0; i < ny; i++) {
for (j = 0; j < nx; j++) {
pixt = pixTilingGetTile(pt, i, j);
pixSplitDistributionFgBg(pixt, scorefract, 1, &thresh,
NULL, NULL, 0);
pixSetPixel(pixthresh, j, i, thresh); /* see note (4) */
pixDestroy(&pixt);
}
}
/* Optionally smooth the threshold array */
if (smoothx > 0 || smoothy > 0)
pixth = pixBlockconv(pixthresh, smoothx, smoothy);
else
pixth = pixClone(pixthresh);
pixDestroy(&pixthresh);
/* Optionally apply the threshold array to binarize pixs */
if (ppixd) {
pixd = pixCreate(w, h, 1);
for (i = 0; i < ny; i++) {
for (j = 0; j < nx; j++) {
pixt = pixTilingGetTile(pt, i, j);
pixGetPixel(pixth, j, i, &val);
pixb = pixThresholdToBinary(pixt, val);
pixTilingPaintTile(pixd, i, j, pixb, pt);
pixDestroy(&pixt);
pixDestroy(&pixb);
}
}
*ppixd = pixd;
}
if (ppixth)
*ppixth = pixth;
else
pixDestroy(&pixth);
pixTilingDestroy(&pt);
return 0;
}
示例6: pixSaveTiledOutline
/*!
* \brief pixSaveTiledOutline()
*
* \param[in] pixs 1, 2, 4, 8, 32 bpp
* \param[in] pixa the pix are accumulated here
* \param[in] scalefactor 0.0 to disable; otherwise this is a scale factor
* \param[in] newrow 0 if placed on the same row as previous; 1 otherwise
* \param[in] space horizontal and vertical spacing, in pixels
* \param[in] linewidth width of added outline for image; 0 for no outline
* \param[in] dp depth of pixa; 8 or 32 bpp; only used on first call
* \return 0 if OK, 1 on error.
*
* <pre>
* Notes:
* (1) Before calling this function for the first time, use
* pixaCreate() to make the %pixa that will accumulate the pix.
* This is passed in each time pixSaveTiled() is called.
* (2) %scalefactor scales the input image. After scaling and
* possible depth conversion, the image is saved in the input
* pixa, along with a box that specifies the location to
* place it when tiled later. Disable saving the pix by
* setting %scalefactor == 0.0.
* (3) %newrow and %space specify the location of the new pix
* with respect to the last one(s) that were entered.
* (4) %dp specifies the depth at which all pix are saved. It can
* be only 8 or 32 bpp. Any colormap is removed. This is only
* used at the first invocation.
* (5) This function uses two variables from call to call.
* If they were static, the function would not be .so or thread
* safe, and furthermore, there would be interference with two or
* more pixa accumulating images at a time. Consequently,
* we use the first pix in the pixa to store and obtain both
* the depth and the current position of the bottom (one pixel
* below the lowest image raster line when laid out using
* the boxa). The bottom variable is stored in the input format
* field, which is the only field available for storing an int.
* </pre>
*/
l_int32
pixSaveTiledOutline(PIX *pixs,
PIXA *pixa,
l_float32 scalefactor,
l_int32 newrow,
l_int32 space,
l_int32 linewidth,
l_int32 dp)
{
l_int32 n, top, left, bx, by, bw, w, h, depth, bottom;
BOX *box;
PIX *pix1, *pix2, *pix3, *pix4;
PROCNAME("pixSaveTiledOutline");
if (scalefactor == 0.0) return 0;
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (!pixa)
return ERROR_INT("pixa not defined", procName, 1);
n = pixaGetCount(pixa);
if (n == 0) {
bottom = 0;
if (dp != 8 && dp != 32) {
L_WARNING("dp not 8 or 32 bpp; using 32\n", procName);
depth = 32;
} else {
depth = dp;
}
} else { /* extract the depth and bottom params from the first pix */
pix1 = pixaGetPix(pixa, 0, L_CLONE);
depth = pixGetDepth(pix1);
bottom = pixGetInputFormat(pix1); /* not typical usage! */
pixDestroy(&pix1);
}
/* Remove colormap if it exists; otherwise a copy. This
* guarantees that pix4 is not a clone of pixs. */
pix1 = pixRemoveColormapGeneral(pixs, REMOVE_CMAP_BASED_ON_SRC, L_COPY);
/* Scale and convert to output depth */
if (scalefactor == 1.0) {
pix2 = pixClone(pix1);
} else if (scalefactor > 1.0) {
pix2 = pixScale(pix1, scalefactor, scalefactor);
} else if (scalefactor < 1.0) {
if (pixGetDepth(pix1) == 1)
pix2 = pixScaleToGray(pix1, scalefactor);
else
pix2 = pixScale(pix1, scalefactor, scalefactor);
}
pixDestroy(&pix1);
if (depth == 8)
pix3 = pixConvertTo8(pix2, 0);
else
pix3 = pixConvertTo32(pix2);
pixDestroy(&pix2);
/* Add black outline */
if (linewidth > 0)
//.........这里部分代码省略.........
示例7: dewarpShowResults
/*!
* dewarpShowResults()
*
* Input: dewa
* sarray (of indexed input images)
* boxa (crop boxes for input images; can be null)
* firstpage, lastpage
* fontdir (for text bitmap fonts)
* pdfout (filename)
* Return: 0 if OK, 1 on error
*
* Notes:
* (1) This generates a pdf of image pairs (before, after) for
* the designated set of input pages.
* (2) If the boxa exists, its elements are aligned with numbers
* in the filenames in @sa. It is used to crop the input images.
* It is assumed that the dewa was generated from the cropped
* images. No undercropping is applied before rendering.
*/
l_int32
dewarpShowResults(L_DEWARPA *dewa,
SARRAY *sa,
BOXA *boxa,
l_int32 firstpage,
l_int32 lastpage,
const char *fontdir,
const char *pdfout)
{
char bufstr[256];
char *outpath;
l_int32 i, modelpage;
L_BMF *bmf;
BOX *box;
L_DEWARP *dew;
PIX *pixs, *pixc, *pixd, *pixt1, *pixt2;
PIXA *pixa;
PROCNAME("dewarpShowResults");
if (!dewa)
return ERROR_INT("dewa not defined", procName, 1);
if (!sa)
return ERROR_INT("sa not defined", procName, 1);
if (!pdfout)
return ERROR_INT("pdfout not defined", procName, 1);
if (firstpage > lastpage)
return ERROR_INT("invalid first/last page numbers", procName, 1);
lept_rmdir("dewarp_pdfout");
lept_mkdir("dewarp_pdfout");
if ((bmf = bmfCreate(fontdir, 6)) == NULL)
L_ERROR("bmf not made; page info not displayed", procName);
fprintf(stderr, "Dewarping and generating s/by/s view\n");
for (i = firstpage; i <= lastpage; i++) {
if (i && (i % 10 == 0)) fprintf(stderr, ".. %d ", i);
pixs = pixReadIndexed(sa, i);
if (boxa) {
box = boxaGetBox(boxa, i, L_CLONE);
pixc = pixClipRectangle(pixs, box, NULL);
boxDestroy(&box);
}
else
pixc = pixClone(pixs);
dew = dewarpaGetDewarp(dewa, i);
pixd = NULL;
if (dew) {
dewarpaApplyDisparity(dewa, dew->pageno, pixc,
GRAYIN_VALUE, 0, 0, &pixd, NULL);
dewarpMinimize(dew);
}
pixa = pixaCreate(2);
pixaAddPix(pixa, pixc, L_INSERT);
if (pixd)
pixaAddPix(pixa, pixd, L_INSERT);
pixt1 = pixaDisplayTiledAndScaled(pixa, 32, 500, 2, 0, 35, 2);
if (dew) {
modelpage = (dew->hasref) ? dew->refpage : dew->pageno;
snprintf(bufstr, sizeof(bufstr), "Page %d; using %d\n",
i, modelpage);
}
else
snprintf(bufstr, sizeof(bufstr), "Page %d; no dewarp\n", i);
pixt2 = pixAddSingleTextblock(pixt1, bmf, bufstr, 0x0000ff00,
L_ADD_BELOW, 0);
snprintf(bufstr, sizeof(bufstr), "/tmp/dewarp_pdfout/%05d", i);
pixWrite(bufstr, pixt2, IFF_JFIF_JPEG);
pixaDestroy(&pixa);
pixDestroy(&pixs);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
}
fprintf(stderr, "\n");
fprintf(stderr, "Generating pdf of result\n");
convertFilesToPdf("/tmp/dewarp_pdfout", NULL, 100, 1.0, L_JPEG_ENCODE,
0, "Dewarp sequence", pdfout);
outpath = genPathname(pdfout, NULL);
fprintf(stderr, "Output written to: %s\n", outpath);
FREE(outpath);
//.........这里部分代码省略.........
示例8: pixaDisplayTiledAndScaled
/*!
* pixaDisplayTiledAndScaled()
*
* Input: pixa
* outdepth (output depth: 1, 8 or 32 bpp)
* tilewidth (each pix is scaled to this width)
* ncols (number of tiles in each row)
* background (0 for white, 1 for black; this is the color
* of the spacing between the images)
* spacing (between images, and on outside)
* border (width of additional black border on each image;
* use 0 for no border)
* Return: pix of tiled images, or null on error
*
* Notes:
* (1) This can be used to tile a number of renderings of
* an image that are at different scales and depths.
* (2) Each image, after scaling and optionally adding the
* black border, has width 'tilewidth'. Thus, the border does
* not affect the spacing between the image tiles. The
* maximum allowed border width is tilewidth / 5.
*/
PIX *
pixaDisplayTiledAndScaled(PIXA *pixa,
l_int32 outdepth,
l_int32 tilewidth,
l_int32 ncols,
l_int32 background,
l_int32 spacing,
l_int32 border)
{
l_int32 x, y, w, h, wd, hd, d;
l_int32 i, n, nrows, maxht, ninrow, irow, bordval;
l_int32 *rowht;
l_float32 scalefact;
PIX *pix, *pixn, *pixt, *pixb, *pixd;
PIXA *pixan;
PROCNAME("pixaDisplayTiledAndScaled");
if (!pixa)
return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
if (outdepth != 1 && outdepth != 8 && outdepth != 32)
return (PIX *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
if (border < 0 || border > tilewidth / 5)
border = 0;
if ((n = pixaGetCount(pixa)) == 0)
return (PIX *)ERROR_PTR("no components", procName, NULL);
/* Normalize scale and depth for each pix; optionally add border */
pixan = pixaCreate(n);
bordval = (outdepth == 1) ? 1 : 0;
for (i = 0; i < n; i++) {
if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
continue;
pixGetDimensions(pix, &w, &h, &d);
scalefact = (l_float32)(tilewidth - 2 * border) / (l_float32)w;
if (d == 1 && outdepth > 1 && scalefact < 1.0)
pixt = pixScaleToGray(pix, scalefact);
else
pixt = pixScale(pix, scalefact, scalefact);
if (outdepth == 1)
pixn = pixConvertTo1(pixt, 128);
else if (outdepth == 8)
pixn = pixConvertTo8(pixt, FALSE);
else /* outdepth == 32 */
pixn = pixConvertTo32(pixt);
pixDestroy(&pixt);
if (border)
pixb = pixAddBorder(pixn, border, bordval);
else
pixb = pixClone(pixn);
pixaAddPix(pixan, pixb, L_INSERT);
pixDestroy(&pix);
pixDestroy(&pixn);
}
if ((n = pixaGetCount(pixan)) == 0) { /* should not have changed! */
pixaDestroy(&pixan);
return (PIX *)ERROR_PTR("no components", procName, NULL);
}
/* Determine the size of each row and of pixd */
wd = tilewidth * ncols + spacing * (ncols + 1);
nrows = (n + ncols - 1) / ncols;
if ((rowht = (l_int32 *)CALLOC(nrows, sizeof(l_int32))) == NULL)
return (PIX *)ERROR_PTR("rowht array not made", procName, NULL);
maxht = 0;
ninrow = 0;
irow = 0;
for (i = 0; i < n; i++) {
pix = pixaGetPix(pixan, i, L_CLONE);
ninrow++;
pixGetDimensions(pix, &w, &h, NULL);
maxht = L_MAX(h, maxht);
if (ninrow == ncols) {
//.........这里部分代码省略.........
示例9: ioFormatTest
/*!
* ioFormatTest()
*
* Input: filename (input file)
* Return: 0 if OK; 1 on error or if the test fails
*
* Notes:
* (1) This writes and reads a set of output files losslessly
* in different formats to /tmp/format/, and tests that the
* result before and after is unchanged.
* (2) This should work properly on input images of any depth,
* with and without colormaps.
* (3) All supported formats are tested for bmp, png, tiff and
* non-ascii pnm. Ascii pnm also works (but who'd ever want
* to use it?) We allow 2 bpp bmp, although it's not
* supported elsewhere. And we don't support reading
* 16 bpp png, although this can be turned on in pngio.c.
* (4) This silently skips png or tiff testing if HAVE_LIBPNG
* or HAVE_LIBTIFF are 0, respectively.
*/
l_int32
ioFormatTest(const char *filename)
{
l_int32 d, equal, problems;
PIX *pixs, *pixc, *pix1, *pix2;
PIXCMAP *cmap;
PROCNAME("ioFormatTest");
if (!filename)
return ERROR_INT("filename not defined", procName, 1);
if ((pixs = pixRead(filename)) == NULL)
return ERROR_INT("pixs not made", procName, 1);
lept_mkdir("lept");
/* Note that the reader automatically removes colormaps
* from 1 bpp BMP images, but not from 8 bpp BMP images.
* Therefore, if our 8 bpp image initially doesn't have a
* colormap, we are going to need to remove it from any
* pix read from a BMP file. */
pixc = pixClone(pixs); /* laziness */
/* This does not test the alpha layer pixels, because most
* formats don't support it. Remove any alpha. */
if (pixGetSpp(pixc) == 4)
pixSetSpp(pixc, 3);
cmap = pixGetColormap(pixc); /* colormap; can be NULL */
d = pixGetDepth(pixc);
problems = FALSE;
/* ----------------------- BMP -------------------------- */
/* BMP works for 1, 2, 4, 8 and 32 bpp images.
* It always writes colormaps for 1 and 8 bpp, so we must
* remove it after readback if the input image doesn't have
* a colormap. Although we can write/read 2 bpp BMP, nobody
* else can read them! */
if (d == 1 || d == 8) {
L_INFO("write/read bmp\n", procName);
pixWrite(FILE_BMP, pixc, IFF_BMP);
pix1 = pixRead(FILE_BMP);
if (!cmap)
pix2 = pixRemoveColormap(pix1, REMOVE_CMAP_BASED_ON_SRC);
else
pix2 = pixClone(pix1);
pixEqual(pixc, pix2, &equal);
if (!equal) {
L_INFO(" **** bad bmp image: d = %d ****\n", procName, d);
problems = TRUE;
}
pixDestroy(&pix1);
pixDestroy(&pix2);
}
if (d == 2 || d == 4 || d == 32) {
L_INFO("write/read bmp\n", procName);
pixWrite(FILE_BMP, pixc, IFF_BMP);
pix1 = pixRead(FILE_BMP);
pixEqual(pixc, pix1, &equal);
if (!equal) {
L_INFO(" **** bad bmp image: d = %d ****\n", procName, d);
problems = TRUE;
}
pixDestroy(&pix1);
}
/* ----------------------- PNG -------------------------- */
#if HAVE_LIBPNG
/* PNG works for all depths, but here, because we strip
* 16 --> 8 bpp on reading, we don't test png for 16 bpp. */
if (d != 16) {
L_INFO("write/read png\n", procName);
pixWrite(FILE_PNG, pixc, IFF_PNG);
pix1 = pixRead(FILE_PNG);
pixEqual(pixc, pix1, &equal);
if (!equal) {
L_INFO(" **** bad png image: d = %d ****\n", procName, d);
//.........这里部分代码省略.........
示例10: jbWordsInTextlines
/*!
* \brief jbWordsInTextlines()
*
* \param[in] dirin directory of input pages
* \param[in] reduction 1 for full res; 2 for half-res
* \param[in] maxwidth of word mask components, to be kept
* \param[in] maxheight of word mask components, to be kept
* \param[in] thresh on correlation; 0.80 is reasonable
* \param[in] weight for handling thick text; 0.6 is reasonable
* \param[out] pnatl numa with textline index for each component
* \param[in] firstpage 0-based
* \param[in] npages use 0 for all pages in dirin
* \return classer for the set of pages
*
* <pre>
* Notes:
* (1) This is a high-level function. See prog/jbwords for example
* of usage.
* (2) Typically, use input of 75 - 150 ppi for finding words.
* </pre>
*/
JBCLASSER *
jbWordsInTextlines(const char *dirin,
l_int32 reduction,
l_int32 maxwidth,
l_int32 maxheight,
l_float32 thresh,
l_float32 weight,
NUMA **pnatl,
l_int32 firstpage,
l_int32 npages)
{
char *fname;
l_int32 nfiles, i, w, h;
BOXA *boxa;
JBCLASSER *classer;
NUMA *nai, *natl;
PIX *pix1, *pix2;
PIXA *pixa;
SARRAY *safiles;
PROCNAME("jbWordsInTextlines");
if (!pnatl)
return (JBCLASSER *)ERROR_PTR("&natl not defined", procName, NULL);
*pnatl = NULL;
if (!dirin)
return (JBCLASSER *)ERROR_PTR("dirin not defined", procName, NULL);
if (reduction != 1 && reduction != 2)
return (JBCLASSER *)ERROR_PTR("reduction not in {1,2}", procName, NULL);
safiles = getSortedPathnamesInDirectory(dirin, NULL, firstpage, npages);
nfiles = sarrayGetCount(safiles);
/* Classify components */
classer = jbCorrelationInit(JB_WORDS, maxwidth, maxheight, thresh, weight);
classer->safiles = sarrayCopy(safiles);
natl = numaCreate(0);
*pnatl = natl;
for (i = 0; i < nfiles; i++) {
fname = sarrayGetString(safiles, i, L_NOCOPY);
if ((pix1 = pixRead(fname)) == NULL) {
L_WARNING("image file %d not read\n", procName, i);
continue;
}
if (reduction == 1)
pix2 = pixClone(pix1);
else /* reduction == 2 */
pix2 = pixReduceRankBinaryCascade(pix1, 1, 0, 0, 0);
pixGetWordsInTextlines(pix2, JB_WORDS_MIN_WIDTH,
JB_WORDS_MIN_HEIGHT, maxwidth, maxheight,
&boxa, &pixa, &nai);
pixGetDimensions(pix2, &w, &h, NULL);
classer->w = w;
classer->h = h;
jbAddPageComponents(classer, pix2, boxa, pixa);
numaJoin(natl, nai, 0, -1);
pixDestroy(&pix1);
pixDestroy(&pix2);
numaDestroy(&nai);
boxaDestroy(&boxa);
pixaDestroy(&pixa);
}
sarrayDestroy(&safiles);
return classer;
}
示例11: pixaDisplayTiledInRows
/*!
* pixaDisplayTiledInRows()
*
* Input: pixa
* outdepth (output depth: 1, 8 or 32 bpp)
* maxwidth (of output image)
* scalefactor (applied to every pix; use 1.0 for no scaling)
* background (0 for white, 1 for black; this is the color
* of the spacing between the images)
* spacing (between images, and on outside)
* border (width of black border added to each image;
* use 0 for no border)
* Return: pixd (of tiled images), or null on error
*
* Notes:
* (1) This saves a pixa to a single image file of width not to
* exceed maxwidth, with background color either white or black,
* and with each row tiled such that the top of each pix is
* aligned and separated by 'spacing' from the next one.
* A black border can be added to each pix.
* (2) All pix are converted to outdepth; existing colormaps are removed.
* (3) This does a reasonably spacewise-efficient job of laying
* out the individual pix images into a tiled composite.
*/
PIX *
pixaDisplayTiledInRows(PIXA *pixa,
l_int32 outdepth,
l_int32 maxwidth,
l_float32 scalefactor,
l_int32 background,
l_int32 spacing,
l_int32 border)
{
l_int32 h; /* cumulative height over all the rows */
l_int32 w; /* cumulative height in the current row */
l_int32 bordval, wtry, wt, ht;
l_int32 irow; /* index of current pix in current row */
l_int32 wmaxrow; /* width of the largest row */
l_int32 maxh; /* max height in row */
l_int32 i, j, index, n, x, y, nrows, ninrow;
NUMA *nainrow; /* number of pix in the row */
NUMA *namaxh; /* height of max pix in the row */
PIX *pix, *pixn, *pixt, *pixd;
PIXA *pixan;
PROCNAME("pixaDisplayTiledInRows");
if (!pixa)
return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
if (outdepth != 1 && outdepth != 8 && outdepth != 32)
return (PIX *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
if (border < 0)
border = 0;
if (scalefactor <= 0.0) scalefactor = 1.0;
if ((n = pixaGetCount(pixa)) == 0)
return (PIX *)ERROR_PTR("no components", procName, NULL);
/* Normalize depths, scale, remove colormaps; optionally add border */
pixan = pixaCreate(n);
bordval = (outdepth == 1) ? 1 : 0;
for (i = 0; i < n; i++) {
if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
continue;
if (outdepth == 1)
pixn = pixConvertTo1(pix, 128);
else if (outdepth == 8)
pixn = pixConvertTo8(pix, FALSE);
else /* outdepth == 32 */
pixn = pixConvertTo32(pix);
pixDestroy(&pix);
if (scalefactor != 1.0)
pixt = pixScale(pixn, scalefactor, scalefactor);
else
pixt = pixClone(pixn);
if (border)
pixd = pixAddBorder(pixt, border, bordval);
else
pixd = pixClone(pixt);
pixDestroy(&pixn);
pixDestroy(&pixt);
pixaAddPix(pixan, pixd, L_INSERT);
}
if (pixaGetCount(pixan) != n) {
n = pixaGetCount(pixan);
L_WARNING_INT("only got %d components", procName, n);
if (n == 0) {
pixaDestroy(&pixan);
return (PIX *)ERROR_PTR("no components", procName, NULL);
}
}
/* Compute parameters for layout */
nainrow = numaCreate(0);
namaxh = numaCreate(0);
wmaxrow = 0;
w = h = spacing;
//.........这里部分代码省略.........
示例12: RotateTest
void
RotateTest(PIX *pixs,
l_int32 reduction,
L_REGPARAMS *rp)
{
l_int32 w, h, d, outformat;
PIX *pixt1, *pixt2, *pixt3, *pixd;
PIXA *pixa;
pixGetDimensions(pixs, &w, &h, &d);
outformat = (d == 8 || d == 32) ? IFF_JFIF_JPEG : IFF_PNG;
pixa = pixaCreate(0);
pixt1 = pixRotate(pixs, ANGLE1, L_ROTATE_SHEAR, L_BRING_IN_WHITE, w, h);
pixSaveTiled(pixt1, pixa, reduction, 1, 20, 32);
pixt2 = pixRotate(pixs, ANGLE1, L_ROTATE_SHEAR, L_BRING_IN_BLACK, w, h);
pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixt1 = pixRotate(pixs, ANGLE1, L_ROTATE_SHEAR, L_BRING_IN_WHITE, 0, 0);
pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
pixt2 = pixRotate(pixs, ANGLE1, L_ROTATE_SHEAR, L_BRING_IN_BLACK, 0, 0);
pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixt1 = pixRotate(pixs, ANGLE2, L_ROTATE_SHEAR, L_BRING_IN_WHITE, w, h);
pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
pixt2 = pixRotate(pixs, ANGLE2, L_ROTATE_SHEAR, L_BRING_IN_BLACK, w, h);
pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixt1 = pixRotate(pixs, ANGLE2, L_ROTATE_SHEAR, L_BRING_IN_WHITE, 0, 0);
pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
pixt2 = pixRotate(pixs, ANGLE2, L_ROTATE_SHEAR, L_BRING_IN_BLACK, 0, 0);
pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixd = pixaDisplay(pixa, 0, 0);
regTestWritePixAndCheck(rp, pixd, outformat);
pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
pixDestroy(&pixd);
pixaDestroy(&pixa);
pixa = pixaCreate(0);
pixt1 = pixRotate(pixs, ANGLE2, L_ROTATE_SAMPLING, L_BRING_IN_WHITE, w, h);
pixSaveTiled(pixt1, pixa, reduction, 1, 20, 32);
pixt2 = pixRotate(pixs, ANGLE2, L_ROTATE_SAMPLING, L_BRING_IN_BLACK, w, h);
pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
pixt1 = pixRotate(pixs, ANGLE2, L_ROTATE_SAMPLING, L_BRING_IN_WHITE, 0, 0);
pixSaveTiled(pixt1, pixa, reduction, 1, 20, 0);
pixt2 = pixRotate(pixs, ANGLE2, L_ROTATE_SAMPLING, L_BRING_IN_BLACK, 0, 0);
pixSaveTiled(pixt2, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt1);
pixDestroy(&pixt2);
if (pixGetDepth(pixs) == 1)
pixt1 = pixScaleToGray2(pixs);
else
pixt1 = pixClone(pixs);
pixt2 = pixRotate(pixt1, ANGLE2, L_ROTATE_AREA_MAP, L_BRING_IN_WHITE, w, h);
pixSaveTiled(pixt2, pixa, reduction, 1, 20, 0);
pixt3 = pixRotate(pixt1, ANGLE2, L_ROTATE_AREA_MAP, L_BRING_IN_BLACK, w, h);
pixSaveTiled(pixt3, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt2);
pixDestroy(&pixt3);
pixt2 = pixRotate(pixt1, ANGLE2, L_ROTATE_AREA_MAP, L_BRING_IN_WHITE, 0, 0);
pixSaveTiled(pixt2, pixa, reduction, 1, 20, 0);
pixt3 = pixRotate(pixt1, ANGLE2, L_ROTATE_AREA_MAP, L_BRING_IN_BLACK, 0, 0);
pixSaveTiled(pixt3, pixa, reduction, 0, 20, 0);
pixDestroy(&pixt2);
pixDestroy(&pixt3);
pixDestroy(&pixt1);
pixd = pixaDisplay(pixa, 0, 0);
regTestWritePixAndCheck(rp, pixd, outformat);
pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display);
pixDestroy(&pixd);
pixaDestroy(&pixa);
return;
}
示例13: pixWriteSegmentedPageToPS
/*
* pixWriteSegmentedPageToPS()
*
* Input: pixs (all depths; colormap ok)
* pixm (<optional> 1 bpp segmentation mask over image region)
* textscale (scale of text output relative to pixs)
* imagescale (scale of image output relative to pixs)
* threshold (threshold for binarization; typ. 190)
* pageno (page number in set; use 1 for new output file)
* fileout (output ps file)
* Return: 0 if OK, 1 on error
*
* Notes:
* (1) This generates the PS string for a mixed text/image page,
* and adds it to an existing file if @pageno > 1.
* The PS output is determined by fitting the result to
* a letter-size (8.5 x 11 inch) page.
* (2) The two images (pixs and pixm) are at the same resolution
* (typically 300 ppi). They are used to generate two compressed
* images, pixb and pixc, that are put directly into the output
* PS file.
* (3) pixb is the text component. In the PostScript world, we think of
* it as a mask through which we paint black. It is produced by
* scaling pixs by @textscale, and thresholding to 1 bpp.
* (4) pixc is the image component, which is that part of pixs under
* the mask pixm. It is scaled from pixs by @imagescale.
* (5) Typical values are textscale = 2.0 and imagescale = 0.5.
* (6) If pixm == NULL, the page has only text. If it is all black,
* the page is all image and has no text.
* (7) This can be used to write a multi-page PS file, by using
* sequential page numbers with the same output file. It can
* also be used to write separate PS files for each page,
* by using different output files with @pageno = 0 or 1.
*/
l_int32
pixWriteSegmentedPageToPS(PIX *pixs,
PIX *pixm,
l_float32 textscale,
l_float32 imagescale,
l_int32 threshold,
l_int32 pageno,
const char *fileout)
{
l_int32 alltext, notext, d, ret;
l_uint32 val;
l_float32 scaleratio;
PIX *pixmi, *pixmis, *pixt, *pixg, *pixsc, *pixb, *pixc;
PROCNAME("pixWriteSegmentedPageToPS");
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (!fileout)
return ERROR_INT("fileout not defined", procName, 1);
if (imagescale <= 0.0 || textscale <= 0.0)
return ERROR_INT("relative scales must be > 0.0", procName, 1);
/* Analyze the page. Determine the ratio by which the
* binary text mask is scaled relative to the image part.
* If there is no image region (alltext == TRUE), the
* text mask will be rendered directly to fit the page,
* and scaleratio = 1.0. */
alltext = TRUE;
notext = FALSE;
scaleratio = 1.0;
if (pixm) {
pixZero(pixm, &alltext); /* pixm empty: all text */
if (alltext)
pixm = NULL; /* treat it as not existing here */
else {
pixmi = pixInvert(NULL, pixm);
pixZero(pixmi, ¬ext); /* pixm full; no text */
pixDestroy(&pixmi);
scaleratio = textscale / imagescale;
}
}
if (pixGetDepth(pixs) == 1) { /* render tiff g4 */
pixb = pixClone(pixs);
pixc = NULL;
}
else {
pixt = pixConvertTo8Or32(pixs, 0, 0); /* this can be a clone of pixs */
/* Get the binary text mask. Note that pixg cannot be a
* clone of pixs, because it may be altered by pixSetMasked(). */
pixb = NULL;
if (notext == FALSE) {
d = pixGetDepth(pixt);
if (d == 8)
pixg = pixCopy(NULL, pixt);
else /* d == 32 */
pixg = pixConvertRGBToLuminance(pixt);
if (pixm) /* clear out the image parts */
pixSetMasked(pixg, pixm, 255);
if (textscale == 1.0)
pixsc = pixClone(pixg);
else if (textscale >= 0.7)
pixsc = pixScaleGrayLI(pixg, textscale, textscale);
else
//.........这里部分代码省略.........
示例14: main
main(int argc,
char **argv)
{
char *filein, *fileout;
l_int32 w, h, d, w2, h2, i, ncols;
l_float32 angle, conf;
BOX *box;
BOXA *boxa, *boxas, *boxad, *boxa2;
NUMA *numa;
PIX *pixs, *pixt, *pixb, *pixb2, *pixd;
PIX *pixtlm, *pixvws;
PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6;
PIXA *pixam, *pixac, *pixad, *pixat;
PIXAA *pixaa, *pixaa2;
PTA *pta;
SEL *selsplit;
static char mainName[] = "textlinemask";
if (argc != 3)
exit(ERROR_INT(" Syntax: textlinemask filein fileout", mainName, 1));
filein = argv[1];
fileout = argv[2];
pixDisplayWrite(NULL, -1); /* init debug output */
if ((pixs = pixRead(filein)) == NULL)
return ERROR_INT("pixs not made", mainName, 1);
pixGetDimensions(pixs, &w, &h, &d);
/* Binarize input */
if (d == 8)
pixt = pixThresholdToBinary(pixs, 128);
else if (d == 1)
pixt = pixClone(pixs);
else {
fprintf(stderr, "depth is %d\n", d);
exit(1);
}
/* Deskew */
pixb = pixFindSkewAndDeskew(pixt, 1, &angle, &conf);
pixDestroy(&pixt);
fprintf(stderr, "Skew angle: %7.2f degrees; %6.2f conf\n", angle, conf);
pixDisplayWrite(pixb, DEBUG_OUTPUT);
#if 1
/* Use full image morphology to find columns, at 2x reduction.
* This only works for very simple layouts where each column
* of text extends the full height of the input image.
* pixam has a pix component over each column. */
pixb2 = pixReduceRankBinary2(pixb, 2, NULL);
pixt1 = pixMorphCompSequence(pixb2, "c5.500", 0);
boxa = pixConnComp(pixt1, &pixam, 8);
ncols = boxaGetCount(boxa);
fprintf(stderr, "Num columns: %d\n", ncols);
pixDisplayWrite(pixt1, DEBUG_OUTPUT);
/* Use selective region-based morphology to get the textline mask. */
pixad = pixaMorphSequenceByRegion(pixb2, pixam, "c100.3", 0, 0);
pixGetDimensions(pixb2, &w2, &h2, NULL);
if (DEBUG_OUTPUT) {
pixt2 = pixaDisplay(pixad, w2, h2);
pixDisplayWrite(pixt2, DEBUG_OUTPUT);
pixDestroy(&pixt2);
}
/* Some of the lines may be touching, so use a HMT to split the
* lines in each column, and use a pixaa to save the results. */
selsplit = selCreateFromString(seltext, 17, 7, "selsplit");
pixaa = pixaaCreate(ncols);
for (i = 0; i < ncols; i++) {
pixt3 = pixaGetPix(pixad, i, L_CLONE);
box = pixaGetBox(pixad, i, L_COPY);
pixt4 = pixHMT(NULL, pixt3, selsplit);
pixXor(pixt4, pixt4, pixt3);
boxa2 = pixConnComp(pixt4, &pixac, 8);
pixaaAddPixa(pixaa, pixac, L_INSERT);
pixaaAddBox(pixaa, box, L_INSERT);
if (DEBUG_OUTPUT) {
pixt5 = pixaDisplayRandomCmap(pixac, 0, 0);
pixDisplayWrite(pixt5, DEBUG_OUTPUT);
fprintf(stderr, "Num textlines in col %d: %d\n", i,
boxaGetCount(boxa2));
pixDestroy(&pixt5);
}
pixDestroy(&pixt3);
pixDestroy(&pixt4);
boxaDestroy(&boxa2);
}
/* Visual output */
if (DEBUG_OUTPUT) {
pixDisplayMultiple("/tmp/junk_write_display*");
pixat = pixaReadFiles("/tmp", "junk_write_display");
pixt5 = selDisplayInPix(selsplit, 31, 2);
pixaAddPix(pixat, pixt5, L_INSERT);
pixt6 = pixaDisplayTiledAndScaled(pixat, 32, 400, 3, 0, 35, 3);
pixWrite(fileout, pixt6, IFF_PNG);
pixaDestroy(&pixat);
//.........这里部分代码省略.........
示例15: pixGetWordsInTextlines
/*!
* \brief pixGetWordsInTextlines()
*
* \param[in] pixs 1 bpp, typ. 300 ppi
* \param[in] reduction 1 for input res; 2 for 2x reduction of input res
* \param[in] minwidth, minheight of saved components; smaller are discarded
* \param[in] maxwidth, maxheight of saved components; larger are discarded
* \param[out] pboxad word boxes sorted in textline line order
* \param[out] ppixad word images sorted in textline line order
* \param[out] pnai index of textline for each word
* \return 0 if OK, 1 on error
*
* <pre>
* Notes:
* (1) The input should be at a resolution of about 300 ppi.
* The word masks and word images can be computed at either
* 150 ppi or 300 ppi. For the former, set reduction = 2.
* (2) The four size constraints on saved components are all
* scaled by %reduction.
* (3) The result are word images (and their b.b.), extracted in
* textline order, at either full res or 2x reduction,
* and with a numa giving the textline index for each word.
* (4) The pixa and boxa interfaces should make this type of
* application simple to put together. The steps are:
* ~ optionally reduce by 2x
* ~ generate first estimate of word masks
* ~ get b.b. of these, and remove the small and big ones
* ~ extract pixa of the word images, using the b.b.
* ~ sort actual word images in textline order (2d)
* ~ flatten them to a pixa (1d), saving the textline index
* for each pix
* (5) In an actual application, it may be desirable to pre-filter
* the input image to remove large components, to extract
* single columns of text, and to deskew them. For example,
* to remove both large components and small noisy components
* that can interfere with the statistics used to estimate
* parameters for segmenting by words, but still retain text lines,
* the following image preprocessing can be done:
* Pix *pixt = pixMorphSequence(pixs, "c40.1", 0);
* Pix *pixf = pixSelectBySize(pixt, 0, 60, 8,
* L_SELECT_HEIGHT, L_SELECT_IF_LT, NULL);
* pixAnd(pixf, pixf, pixs); // the filtered image
* The closing turns text lines into long blobs, but does not
* significantly increase their height. But if there are many
* small connected components in a dense texture, this is likely
* to generate tall components that will be eliminated in pixf.
* </pre>
*/
l_int32
pixGetWordsInTextlines(PIX *pixs,
l_int32 reduction,
l_int32 minwidth,
l_int32 minheight,
l_int32 maxwidth,
l_int32 maxheight,
BOXA **pboxad,
PIXA **ppixad,
NUMA **pnai)
{
l_int32 maxdil;
BOXA *boxa1, *boxad;
BOXAA *baa;
NUMA *nai;
NUMAA *naa;
PIXA *pixa1, *pixad;
PIX *pix1;
PIXAA *paa;
PROCNAME("pixGetWordsInTextlines");
if (!pboxad || !ppixad || !pnai)
return ERROR_INT("&boxad, &pixad, &nai not all defined", procName, 1);
*pboxad = NULL;
*ppixad = NULL;
*pnai = NULL;
if (!pixs)
return ERROR_INT("pixs not defined", procName, 1);
if (reduction != 1 && reduction != 2)
return ERROR_INT("reduction not in {1,2}", procName, 1);
if (reduction == 1) {
pix1 = pixClone(pixs);
maxdil = 18;
} else { /* reduction == 2 */
pix1 = pixReduceRankBinaryCascade(pixs, 1, 0, 0, 0);
maxdil = 9;
}
/* Get the bounding boxes of the words from the word mask. */
pixWordBoxesByDilation(pix1, maxdil, minwidth, minheight,
maxwidth, maxheight, &boxa1, NULL);
/* Generate a pixa of the word images */
pixa1 = pixaCreateFromBoxa(pix1, boxa1, NULL); /* mask over each word */
/* Sort the bounding boxes of these words by line. We use the
* index mapping to allow identical sorting of the pixa. */
baa = boxaSort2d(boxa1, &naa, -1, -1, 4);
paa = pixaSort2dByIndex(pixa1, naa, L_CLONE);
//.........这里部分代码省略.........