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);
264 if (pupconf) *pupconf = upconf;
265 if (pleftconf) *pleftconf = leftconf;
274 L_INFO(
"text orientation not determined; no rotation\n", procName);
275 if (protation) *protation = 0;
279 L_INFO(
"text is oriented up; no rotation\n", procName);
280 if (protation) *protation = 0;
284 L_INFO(
"landscape; text oriented left; 90 cw rotation\n", procName);
285 if (protation) *protation = 90;
289 L_INFO(
"text oriented down; 180 cw rotation\n", procName);
290 if (protation) *protation = 180;
294 L_INFO(
"landscape; text oriented right; 270 cw rotation\n", procName);
295 if (protation) *protation = 270;
299 L_ERROR(
"invalid orient flag!\n", procName);
370 l_float32 *pleftconf,
376 PROCNAME(
"pixOrientDetect");
378 if (!pixs || pixGetDepth(pixs) != 1)
379 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
380 if (!pupconf && !pleftconf)
381 return ERROR_INT(
"nothing to do", procName, 1);
383 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
434 l_float32 absupconf, absleftconf;
436 PROCNAME(
"makeOrientDecision");
439 return ERROR_INT(
"&orient not defined", procName, 1);
441 if (upconf == 0.0 || leftconf == 0.0) {
442 L_INFO(
"not enough confidence to get orientation\n", procName);
446 if (minupconf == 0.0)
447 minupconf = DEFAULT_MIN_UP_DOWN_CONF;
449 minratio = DEFAULT_MIN_UP_DOWN_RATIO;
450 absupconf = L_ABS(upconf);
451 absleftconf = L_ABS(leftconf);
455 if (upconf > minupconf && absupconf > minratio * absleftconf)
457 else if (leftconf > minupconf && absleftconf > minratio * absupconf)
459 else if (upconf < -minupconf && absupconf > minratio * absleftconf)
461 else if (leftconf < -minupconf && absleftconf > minratio * absupconf)
465 fprintf(stderr,
"upconf = %7.3f, leftconf = %7.3f\n", upconf, leftconf);
467 fprintf(stderr,
"Confidence is low; no determination is made\n");
469 fprintf(stderr,
"Text is rightside-up\n");
471 fprintf(stderr,
"Text is rotated 90 deg ccw\n");
473 fprintf(stderr,
"Text is upside-down\n");
475 fprintf(stderr,
"Text is rotated 90 deg cw\n");
558 l_int32 countup, countdown, nmax;
559 l_float32 nup, ndown;
560 PIX *pix0, *pix1, *pix2, *pix3, *pixm;
561 SEL *sel1, *sel2, *sel3, *sel4;
563 PROCNAME(
"pixUpDownDetectGeneral");
566 return ERROR_INT(
"&conf not defined", procName, 1);
568 if (!pixs || pixGetDepth(pixs) != 1)
569 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
571 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
594 l_int32 i, nbox, x, y, w, h;
602 for (i = 0; i < nbox; i++) {
606 pixRasterop(pixm, x + npixels, y - 6, w - 2 * npixels, h + 13,
616 pix1 =
pixHMT(NULL, pix0, sel1);
617 pix2 =
pixHMT(NULL, pix0, sel2);
618 pixOr(pix1, pix1, pix2);
623 pixDebugFlipDetect(
"/tmp/lept/orient/up.png", pixs, pix1, debug);
629 pix1 =
pixHMT(NULL, pix0, sel3);
630 pix2 =
pixHMT(NULL, pix0, sel4);
631 pixOr(pix1, pix1, pix2);
636 pixDebugFlipDetect(
"/tmp/lept/orient/down.png", pixs, pix1, debug);
643 nup = (l_float32)(countup);
644 ndown = (l_float32)(countdown);
645 nmax = L_MAX(countup, countdown);
647 *pconf = 2. * ((nup - ndown) / sqrt(nup + ndown));
650 if (pixm) pixWriteDebug(
"/tmp/lept/orient/pixm1.png", pixm, IFF_PNG);
651 fprintf(stderr,
"nup = %7.3f, ndown = %7.3f, conf = %7.3f\n",
653 if (*pconf > DEFAULT_MIN_UP_DOWN_CONF)
654 fprintf(stderr,
"Text is rightside-up\n");
655 if (*pconf < -DEFAULT_MIN_UP_DOWN_CONF)
656 fprintf(stderr,
"Text is upside-down\n");
697 l_float32 *pleftconf,
703 PROCNAME(
"pixOrientDetectDwa");
705 if (!pixs || pixGetDepth(pixs) != 1)
706 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
707 if (!pupconf && !pleftconf)
708 return ERROR_INT(
"nothing to do", procName, 1);
710 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
779 char flipsel1[] =
"flipsel1";
780 char flipsel2[] =
"flipsel2";
781 char flipsel3[] =
"flipsel3";
782 char flipsel4[] =
"flipsel4";
783 l_int32 countup, countdown, nmax;
784 l_float32 nup, ndown;
785 PIX *pixt, *pix0, *pix1, *pix2, *pix3, *pixm;
787 PROCNAME(
"pixUpDownDetectGeneralDwa");
790 return ERROR_INT(
"&conf not defined", procName, 1);
792 if (!pixs || pixGetDepth(pixs) != 1)
793 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
795 mincount = DEFAULT_MIN_UP_DOWN_COUNT;
814 l_int32 i, nbox, x, y, w, h;
822 for (i = 0; i < nbox; i++) {
826 pixRasterop(pixm, x + npixels, y - 6, w - 2 * npixels, h + 13,
836 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel1);
837 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel2);
838 pixOr(pix1, pix1, pix2);
848 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel3);
849 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel4);
850 pixOr(pix1, pix1, pix2);
861 nup = (l_float32)(countup);
862 ndown = (l_float32)(countdown);
863 nmax = L_MAX(countup, countdown);
865 *pconf = 2. * ((nup - ndown) / sqrt(nup + ndown));
870 pixWriteDebug(
"/tmp/lept/orient/pixm2.png", pixm, IFF_PNG);
872 fprintf(stderr,
"nup = %7.3f, ndown = %7.3f, conf = %7.3f\n",
874 if (*pconf > DEFAULT_MIN_UP_DOWN_CONF)
875 fprintf(stderr,
"Text is rightside-up\n");
876 if (*pconf < -DEFAULT_MIN_UP_DOWN_CONF)
877 fprintf(stderr,
"Text is upside-down\n");
936 l_int32 count1, count2, nmax;
937 l_float32 nleft, nright;
938 PIX *pix0, *pix1, *pix2, *pix3;
941 PROCNAME(
"pixMirrorDetect");
944 return ERROR_INT(
"&conf not defined", procName, 1);
946 if (!pixs || pixGetDepth(pixs) != 1)
947 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
949 mincount = DEFAULT_MIN_MIRROR_FLIP_COUNT;
964 pixOr(pix0, pix0, pixs);
968 pix1 =
pixHMT(NULL, pix0, sel1);
971 pixDebugFlipDetect(
"/tmp/lept/orient/right.png", pixs, pix1, debug);
976 pix2 =
pixHMT(NULL, pix0, sel2);
979 pixDebugFlipDetect(
"/tmp/lept/orient/left.png", pixs, pix2, debug);
983 nright = (l_float32)count1;
984 nleft = (l_float32)count2;
985 nmax = L_MAX(count1, count2);
991 *pconf = 2. * ((nright - nleft) / sqrt(nright + nleft));
994 fprintf(stderr,
"nright = %f, nleft = %f\n", nright, nleft);
995 if (*pconf > DEFAULT_MIN_MIRROR_FLIP_CONF)
996 fprintf(stderr,
"Text is not mirror reversed\n");
997 if (*pconf < -DEFAULT_MIN_MIRROR_FLIP_CONF)
998 fprintf(stderr,
"Text is mirror reversed\n");
1031 char flipsel1[] =
"flipsel1";
1032 char flipsel2[] =
"flipsel2";
1033 l_int32 count1, count2, nmax;
1034 l_float32 nleft, nright;
1035 PIX *pix0, *pix1, *pix2, *pix3;
1037 PROCNAME(
"pixMirrorDetectDwa");
1040 return ERROR_INT(
"&conf not defined", procName, 1);
1042 if (!pixs || pixGetDepth(pixs) != 1)
1043 return ERROR_INT(
"pixs not defined or not 1 bpp", procName, 1);
1045 mincount = DEFAULT_MIN_MIRROR_FLIP_COUNT;
1049 pixXor(pix3, pix3, pixs);
1051 pixXor(pix0, pix0, pixs);
1052 pixAnd(pix0, pix0, pix3);
1053 pixOr(pix3, pix0, pixs);
1060 pix1 = pixFlipFHMTGen(NULL, pix0, flipsel1);
1067 pix2 = pixFlipFHMTGen(NULL, pix0, flipsel2);
1074 nright = (l_float32)count1;
1075 nleft = (l_float32)count2;
1076 nmax = L_MAX(count1, count2);
1078 if (nmax > mincount)
1079 *pconf = 2. * ((nright - nleft) / sqrt(nright + nleft));
1082 fprintf(stderr,
"nright = %f, nleft = %f\n", nright, nleft);
1083 if (*pconf > DEFAULT_MIN_MIRROR_FLIP_CONF)
1084 fprintf(stderr,
"Text is not mirror reversed\n");
1085 if (*pconf < -DEFAULT_MIN_MIRROR_FLIP_CONF)
1086 fprintf(stderr,
"Text is mirror reversed\n");
1106 pixDebugFlipDetect(
const char *filename,
1113 if (!enable)
return;
1120 pixWriteDebug(filename, pixt, IFF_PNG);
l_ok makeOrientDecision(l_float32 upconf, l_float32 leftconf, l_float32 minupconf, l_float32 minratio, l_int32 *porient, l_int32 debug)
makeOrientDecision()
l_ok pixUpDownDetectGeneralDwa(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 npixels, l_int32 debug)
pixUpDownDetectGeneralDwa()
static const l_int32 ADDED_BORDER
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
l_ok pixUpDownDetectGeneral(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 npixels, l_int32 debug)
pixUpDownDetectGeneral()
l_ok 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()
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
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_ok pixUpDownDetectDwa(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixUpDownDetectDwa()
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
l_ok pixSetMaskedCmap(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetMaskedCmap()
l_ok pixOrientDetectDwa(PIX *pixs, l_float32 *pupconf, l_float32 *pleftconf, l_int32 mincount, l_int32 debug)
pixOrientDetectDwa()
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_ok pixMirrorDetectDwa(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixMirrorDetectDwa()
PIX * pixHMT(PIX *pixd, PIX *pixs, SEL *sel)
pixHMT()
l_ok pixOrientDetect(PIX *pixs, l_float32 *pupconf, l_float32 *pleftconf, l_int32 mincount, l_int32 debug)
pixOrientDetect()
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_ok pixMirrorDetect(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixMirrorDetect()
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
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_ok pixUpDownDetect(PIX *pixs, l_float32 *pconf, l_int32 mincount, l_int32 debug)
pixUpDownDetect()