174 #include "allheaders.h" 177 static const char *textsel1 =
"x oo " 183 static const char *textsel2 =
" oo x" 189 static const char *textsel3 =
"xxxxxx" 195 static const char *textsel4 =
"xxxxxx" 202 static const l_int32 DEFAULT_MIN_UP_DOWN_COUNT = 70;
203 static const l_float32 DEFAULT_MIN_UP_DOWN_CONF = 8.0;
204 static const l_float32 DEFAULT_MIN_UP_DOWN_RATIO = 2.5;
207 static const l_int32 DEFAULT_MIN_MIRROR_FLIP_COUNT = 100;
208 static const l_float32 DEFAULT_MIN_MIRROR_FLIP_CONF = 5.0;
211 static void pixDebugFlipDetect(
const char *filename,
PIX *pixs,
212 PIX *pixhm, l_int32 enable);
246 l_float32 *pleftconf,
251 l_float32 upconf, leftconf;
254 PROCNAME(
"pixOrientCorrect");
256 if (!pixs || pixGetDepth(pixs) != 1)
257 return (
PIX *)ERROR_PTR(
"pixs undefined or not 1 bpp", procName, NULL);
266 if (pupconf) *pupconf = upconf;
267 if (pleftconf) *pleftconf = leftconf;
276 L_INFO(
"text orientation not determined; no rotation\n", procName);
277 if (protation) *protation = 0;
281 L_INFO(
"text is oriented up; no rotation\n", procName);
282 if (protation) *protation = 0;
286 L_INFO(
"landscape; text oriented left; 90 cw rotation\n", procName);
287 if (protation) *protation = 90;
291 L_INFO(
"text oriented down; 180 cw rotation\n", procName);
292 if (protation) *protation = 180;
296 L_INFO(
"landscape; text oriented right; 270 cw rotation\n", procName);
297 if (protation) *protation = 270;
301 L_ERROR(
"invalid orient flag!\n", procName);
372 l_float32 *pleftconf,
378 PROCNAME(
"pixOrientDetect");
380 if (!pixs || pixGetDepth(pixs) != 1)
381 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
382 if (!pupconf && !pleftconf)
383 return ERROR_INT(
"nothing to do", procName, 1);
385 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
438 l_float32 absupconf, absleftconf;
440 PROCNAME(
"makeOrientDecision");
443 return ERROR_INT(
"&orient not defined", procName, 1);
445 if (upconf == 0.0 || leftconf == 0.0) {
446 L_INFO(
"not enough confidence to get orientation\n", procName);
452 if (minupconf == 0.0)
453 minupconf = DEFAULT_MIN_UP_DOWN_CONF;
455 minratio = DEFAULT_MIN_UP_DOWN_RATIO;
456 absupconf = L_ABS(upconf);
457 absleftconf = L_ABS(leftconf);
461 if (upconf > minupconf && absupconf > minratio * absleftconf)
463 else if (leftconf > minupconf && absleftconf > minratio * absupconf)
465 else if (upconf < -minupconf && absupconf > minratio * absleftconf)
467 else if (leftconf < -minupconf && absleftconf > minratio * absupconf)
471 fprintf(stderr,
"upconf = %7.3f, leftconf = %7.3f\n", upconf, leftconf);
473 fprintf(stderr,
"Confidence is low; no determination is made\n");
475 fprintf(stderr,
"Text is rightside-up\n");
477 fprintf(stderr,
"Text is rotated 90 deg ccw\n");
479 fprintf(stderr,
"Text is upside-down\n");
481 fprintf(stderr,
"Text is rotated 90 deg cw\n");
564 l_int32 countup, countdown, nmax;
565 l_float32 nup, ndown;
566 PIX *pix0, *pix1, *pix2, *pix3, *pixm;
567 SEL *sel1, *sel2, *sel3, *sel4;
569 PROCNAME(
"pixUpDownDetectGeneral");
572 return ERROR_INT(
"&conf not defined", procName, 1);
574 if (!pixs || pixGetDepth(pixs) != 1)
575 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
577 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
598 l_int32 i, nbox, x, y, w, h;
606 for (i = 0; i < nbox; i++) {
610 pixRasterop(pixm, x + npixels, y - 6, w - 2 * npixels, h + 13,
620 pix1 =
pixHMT(NULL, pix0, sel1);
621 pix2 =
pixHMT(NULL, pix0, sel2);
622 pixOr(pix1, pix1, pix2);
627 pixDebugFlipDetect(
"/tmp/lept/orient/up.png", pixs, pix1, debug);
633 pix1 =
pixHMT(NULL, pix0, sel3);
634 pix2 =
pixHMT(NULL, pix0, sel4);
635 pixOr(pix1, pix1, pix2);
640 pixDebugFlipDetect(
"/tmp/lept/orient/down.png", pixs, pix1, debug);
647 nup = (l_float32)(countup);
648 ndown = (l_float32)(countdown);
649 nmax = L_MAX(countup, countdown);
651 *pconf = 2. * ((nup - ndown) / sqrt(nup + ndown));
654 if (pixm) pixWrite(
"/tmp/lept/orient/pixm1.png", pixm, IFF_PNG);
655 fprintf(stderr,
"nup = %7.3f, ndown = %7.3f, conf = %7.3f\n",
657 if (*pconf > DEFAULT_MIN_UP_DOWN_CONF)
658 fprintf(stderr,
"Text is rightside-up\n");
659 if (*pconf < -DEFAULT_MIN_UP_DOWN_CONF)
660 fprintf(stderr,
"Text is upside-down\n");
701 l_float32 *pleftconf,
707 PROCNAME(
"pixOrientDetectDwa");
709 if (!pixs || pixGetDepth(pixs) != 1)
710 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
711 if (!pupconf && !pleftconf)
712 return ERROR_INT(
"nothing to do", procName, 1);
714 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
783 char flipsel1[] =
"flipsel1";
784 char flipsel2[] =
"flipsel2";
785 char flipsel3[] =
"flipsel3";
786 char flipsel4[] =
"flipsel4";
787 l_int32 countup, countdown, nmax;
788 l_float32 nup, ndown;
789 PIX *pixt, *pix0, *pix1, *pix2, *pix3, *pixm;
791 PROCNAME(
"pixUpDownDetectGeneralDwa");
794 return ERROR_INT(
"&conf not defined", procName, 1);
796 if (!pixs || pixGetDepth(pixs) != 1)
797 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
799 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
820 l_int32 i, nbox, x, y, w, h;
828 for (i = 0; i < nbox; i++) {
832 pixRasterop(pixm, x + npixels, y - 6, w - 2 * npixels, h + 13,
842 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel1);
843 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel2);
844 pixOr(pix1, pix1, pix2);
854 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel3);
855 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel4);
856 pixOr(pix1, pix1, pix2);
867 nup = (l_float32)(countup);
868 ndown = (l_float32)(countdown);
869 nmax = L_MAX(countup, countdown);
871 *pconf = 2. * ((nup - ndown) / sqrt(nup + ndown));
874 if (pixm) pixWrite(
"/tmp/lept/orient/pixm2.png", pixm, IFF_PNG);
875 fprintf(stderr,
"nup = %7.3f, ndown = %7.3f, conf = %7.3f\n",
877 if (*pconf > DEFAULT_MIN_UP_DOWN_CONF)
878 fprintf(stderr,
"Text is rightside-up\n");
879 if (*pconf < -DEFAULT_MIN_UP_DOWN_CONF)
880 fprintf(stderr,
"Text is upside-down\n");
939 l_int32 count1, count2, nmax;
940 l_float32 nleft, nright;
941 PIX *pix0, *pix1, *pix2, *pix3;
944 PROCNAME(
"pixMirrorDetect");
947 return ERROR_INT(
"&conf not defined", procName, 1);
949 if (!pixs || pixGetDepth(pixs) != 1)
950 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
952 mincount = DEFAULT_MIN_MIRROR_FLIP_COUNT;
963 pixOr(pix0, pix0, pixs);
967 pix1 =
pixHMT(NULL, pix0, sel1);
970 pixDebugFlipDetect(
"/tmp/lept/orient/right.png", pixs, pix1, debug);
975 pix2 =
pixHMT(NULL, pix0, sel2);
978 pixDebugFlipDetect(
"/tmp/lept/orient/left.png", pixs, pix2, debug);
982 nright = (l_float32)count1;
983 nleft = (l_float32)count2;
984 nmax = L_MAX(count1, count2);
990 *pconf = 2. * ((nright - nleft) / sqrt(nright + nleft));
993 fprintf(stderr,
"nright = %f, nleft = %f\n", nright, nleft);
994 if (*pconf > DEFAULT_MIN_MIRROR_FLIP_CONF)
995 fprintf(stderr,
"Text is not mirror reversed\n");
996 if (*pconf < -DEFAULT_MIN_MIRROR_FLIP_CONF)
997 fprintf(stderr,
"Text is mirror reversed\n");
1030 char flipsel1[] =
"flipsel1";
1031 char flipsel2[] =
"flipsel2";
1032 l_int32 count1, count2, nmax;
1033 l_float32 nleft, nright;
1034 PIX *pix0, *pix1, *pix2, *pix3;
1036 PROCNAME(
"pixMirrorDetectDwa");
1039 return ERROR_INT(
"&conf not defined", procName, 1);
1041 if (!pixs || pixGetDepth(pixs) != 1)
1042 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
1044 mincount = DEFAULT_MIN_MIRROR_FLIP_COUNT;
1048 pixXor(pix3, pix3, pixs);
1050 pixXor(pix0, pix0, pixs);
1051 pixAnd(pix0, pix0, pix3);
1052 pixOr(pix3, pix0, pixs);
1059 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel1);
1066 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel2);
1073 nright = (l_float32)count1;
1074 nleft = (l_float32)count2;
1075 nmax = L_MAX(count1, count2);
1077 if (nmax > mincount)
1078 *pconf = 2. * ((nright - nleft) / sqrt(nright + nleft));
1081 fprintf(stderr,
"nright = %f, nleft = %f\n", nright, nleft);
1082 if (*pconf > DEFAULT_MIN_MIRROR_FLIP_CONF)
1083 fprintf(stderr,
"Text is not mirror reversed\n");
1084 if (*pconf < -DEFAULT_MIN_MIRROR_FLIP_CONF)
1085 fprintf(stderr,
"Text is mirror reversed\n");
1105 pixDebugFlipDetect(
const char *filename,
1112 if (!enable)
return;
1119 pixWrite(filename, pixt, IFF_PNG);
l_int32 pixOrientDetect(PIX *pixs, l_float32 *pupconf, l_float32 *pleftconf, l_int32 mincount, l_int32 debug)
pixOrientDetect()
static const l_int32 ADDED_BORDER
l_int32 makeOrientDecision(l_float32 upconf, l_float32 leftconf, l_float32 minupconf, l_float32 minratio, l_int32 *porient, l_int32 debug)
makeOrientDecision()
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
l_int32 pixMirrorDetectDwa(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixMirrorDetectDwa()
l_int32 pixMirrorDetect(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixMirrorDetect()
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
l_int32 pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
void selDestroy(SEL **psel)
selDestroy()
PIX * pixAnd(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAnd()
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
l_int32 boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
l_int32 pixUpDownDetect(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixUpDownDetect()
void pixDestroy(PIX **ppix)
pixDestroy()
PIX * pixRotateOrth(PIX *pixs, l_int32 quads)
pixRotateOrth()
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
PIX * pixOr(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixOr()
l_int32 pixUpDownDetectGeneralDwa(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 npixels, l_int32 debug)
pixUpDownDetectGeneralDwa()
l_int32 pixUpDownDetectGeneral(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 npixels, l_int32 debug)
pixUpDownDetectGeneral()
PIX * pixHMT(PIX *pixd, PIX *pixs, SEL *sel)
pixHMT()
PIX * pixConvert1To4Cmap(PIX *pixs)
pixConvert1To4Cmap()
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
void boxDestroy(BOX **pbox)
boxDestroy()
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
PIX * pixRotate90(PIX *pixs, l_int32 direction)
pixRotate90()
PIX * pixMorphSequenceDwa(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequenceDwa()
l_int32 pixUpDownDetectDwa(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixUpDownDetectDwa()
l_int32 pixOrientDetectDwa(PIX *pixs, l_float32 *pupconf, l_float32 *pleftconf, l_int32 mincount, l_int32 debug)
pixOrientDetectDwa()
l_int32 pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
PIX * pixReduceRankBinaryCascade(PIX *pixs, l_int32 level1, l_int32 level2, l_int32 level3, l_int32 level4)
pixReduceRankBinaryCascade()
PIX * pixOrientCorrect(PIX *pixs, l_float32 minupconf, l_float32 minratio, l_float32 *pupconf, l_float32 *pleftconf, l_int32 *protation, l_int32 debug)
pixOrientCorrect()
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
SEL * selCreateFromString(const char *text, l_int32 h, l_int32 w, const char *name)
selCreateFromString()
PIX * pixMorphCompSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphCompSequence()
l_int32 pixSetMaskedCmap(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetMaskedCmap()