third-party/leptonica/prog/skewtest.c
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/
/*
* skewtest.c
*
* Tests various skew finding methods, optionally deskewing
* the input (binary) image. The best version does a linear
* sweep followed by a binary (angle-splitting) search.
* The basic method is to find the vertical shear angle such
* that the differential variance of ON pixels between each
* line and it's neighbor, when summed over all lines, is
* maximized.
*/
#include "allheaders.h"
/* deskew */
#define DESKEW_REDUCTION 2 /* 1, 2 or 4 */
/* sweep only */
#define SWEEP_RANGE 10. /* degrees */
#define SWEEP_DELTA 0.2 /* degrees */
#define SWEEP_REDUCTION 2 /* 1, 2, 4 or 8 */
/* sweep and search */
#define SWEEP_RANGE2 10. /* degrees */
#define SWEEP_DELTA2 1. /* degrees */
#define SWEEP_REDUCTION2 2 /* 1, 2, 4 or 8 */
#define SEARCH_REDUCTION 2 /* 1, 2, 4 or 8 */
#define SEARCH_MIN_DELTA 0.01 /* degrees */
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];
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;
}