main(int argc, char **argv) { char *filein, *fileout; NUMA *na; PIX *pixs, *pixd; PTA *pta; static char mainName[] = "baselinetest"; if (argc != 3) return ERROR_INT(" Syntax: baselinetest filein fileout", mainName, 1); filein = argv[1]; fileout = argv[2]; pixs = pixRead(filein); #if 1 /* Test function for deskewing using projective transform * on linear approximation for local skew angle */ pixd = pixDeskewLocal(pixs, 10, 0, 0, 0.0, 0.0, 0.0); pixWrite(fileout, pixd, IFF_TIFF_G4); /* test baseline finder */ na = pixFindBaselines(pixd, &pta, 1); /* ptaWriteStream(stderr, pta, 1); */ pixDestroy(&pixd); numaDestroy(&na); ptaDestroy(&pta); #endif #if 0 /* Test function for finding local skew angles */ na = pixGetLocalSkewAngles(pixs, 10, 0, 0, 0.0, 0.0, 0.0, NULL, NULL); numaDestroy(&na); #endif pixDestroy(&pixs); return 0; }
/*! * \brief pixGetLocalSkewTransform() * * \param[in] pixs * \param[in] nslices the number of horizontal overlapping slices; must * be larger than 1 and not exceed 20; use 0 for default * \param[in] redsweep sweep reduction factor: 1, 2, 4 or 8; * use 0 for default value * \param[in] redsearch search reduction factor: 1, 2, 4 or 8, and * not larger than redsweep; use 0 for default value * \param[in] sweeprange half the full range, assumed about 0; in degrees; * use 0.0 for default value * \param[in] sweepdelta angle increment of sweep; in degrees; * use 0.0 for default value * \param[in] minbsdelta min binary search increment angle; in degrees; * use 0.0 for default value * \param[out] pptas 4 points in the source * \param[out] pptad the corresponding 4 pts in the dest * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) This generates two pairs of points in the src, each pair * corresponding to a pair of points that would lie along * the same raster line in a transformed (dewarped) image. * (2) The sets of 4 src and 4 dest points returned by this function * can then be used, in a projective or bilinear transform, * to remove keystoning in the src. * </pre> */ l_int32 pixGetLocalSkewTransform(PIX *pixs, l_int32 nslices, l_int32 redsweep, l_int32 redsearch, l_float32 sweeprange, l_float32 sweepdelta, l_float32 minbsdelta, PTA **pptas, PTA **pptad) { l_int32 w, h, i; l_float32 deg2rad, angr, angd, dely; NUMA *naskew; PTA *ptas, *ptad; PROCNAME("pixGetLocalSkewTransform"); if (!pptas || !pptad) return ERROR_INT("&ptas and &ptad not defined", procName, 1); *pptas = *pptad = NULL; if (!pixs || pixGetDepth(pixs) != 1) return ERROR_INT("pixs not defined or not 1 bpp", procName, 1); if (nslices < 2 || nslices > 20) nslices = DEFAULT_SLICES; if (redsweep < 1 || redsweep > 8) redsweep = DEFAULT_SWEEP_REDUCTION; if (redsearch < 1 || redsearch > redsweep) redsearch = DEFAULT_BS_REDUCTION; if (sweeprange == 0.0) sweeprange = DEFAULT_SWEEP_RANGE; if (sweepdelta == 0.0) sweepdelta = DEFAULT_SWEEP_DELTA; if (minbsdelta == 0.0) minbsdelta = DEFAULT_MINBS_DELTA; naskew = pixGetLocalSkewAngles(pixs, nslices, redsweep, redsearch, sweeprange, sweepdelta, minbsdelta, NULL, NULL, 0); if (!naskew) return ERROR_INT("naskew not made", procName, 1); deg2rad = 3.14159265 / 180.; w = pixGetWidth(pixs); h = pixGetHeight(pixs); ptas = ptaCreate(4); ptad = ptaCreate(4); *pptas = ptas; *pptad = ptad; /* Find i for skew line that intersects LHS at i and RHS at h / 20 */ for (i = 0; i < h; i++) { numaGetFValue(naskew, i, &angd); angr = angd * deg2rad; dely = w * tan(angr); if (i - dely > 0.05 * h) break; } ptaAddPt(ptas, 0, i); ptaAddPt(ptas, w - 1, i - dely); ptaAddPt(ptad, 0, i); ptaAddPt(ptad, w - 1, i); /* Find i for skew line that intersects LHS at i and RHS at 19h / 20 */ for (i = h - 1; i > 0; i--) { numaGetFValue(naskew, i, &angd); angr = angd * deg2rad; dely = w * tan(angr); if (i - dely < 0.95 * h) break; } ptaAddPt(ptas, 0, i); ptaAddPt(ptas, w - 1, i - dely); ptaAddPt(ptad, 0, i); ptaAddPt(ptad, w - 1, i); numaDestroy(&naskew); return 0; }