79 #include "allheaders.h" 145 l_float32 scorefract,
149 l_int32 w, h, nx, ny, i, j, thresh;
151 PIX *pixt, *pixb, *pixthresh, *pixth, *pixd;
154 PROCNAME(
"pixOtsuAdaptiveThreshold");
156 if (!ppixth && !ppixd)
157 return ERROR_INT(
"neither &pixth nor &pixd defined", procName, 1);
158 if (ppixth) *ppixth = NULL;
159 if (ppixd) *ppixd = NULL;
160 if (!
pixs || pixGetDepth(
pixs) != 8)
161 return ERROR_INT(
"pixs not defined or not 8 bpp", procName, 1);
162 if (sx < 16 || sy < 16)
163 return ERROR_INT(
"sx and sy must be >= 16", procName, 1);
167 nx = L_MAX(1, w / sx);
168 ny = L_MAX(1, h / sy);
169 smoothx = L_MIN(smoothx, (nx - 1) / 2);
170 smoothy = L_MIN(smoothy, (ny - 1) / 2);
173 for (i = 0; i < ny; i++) {
174 for (j = 0; j < nx; j++) {
184 if (smoothx > 0 || smoothy > 0)
193 pixCopyResolution(pixd,
pixs);
194 for (i = 0; i < ny; i++) {
195 for (j = 0; j < nx; j++) {
265 l_float32 scorefract,
270 PIX *pixn, *pixt, *pixd;
272 PROCNAME(
"pixOtsuThreshOnBackgroundNorm");
274 if (pthresh) *pthresh = 0;
275 if (!
pixs || pixGetDepth(
pixs) != 8)
276 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", procName, NULL);
277 if (pixGetColormap(
pixs))
278 return (
PIX *)ERROR_PTR(
"pixs is colormapped", procName, NULL);
279 if (sx < 4 || sy < 4)
280 return (
PIX *)ERROR_PTR(
"sx and sy must be >= 4", procName, NULL);
281 if (mincount > sx * sy) {
282 L_WARNING(
"mincount too large for tile size\n", procName);
283 mincount = (sx * sy) / 3;
287 mincount, bgval, smoothx, smoothy);
289 return (
PIX *)ERROR_PTR(
"pixn not made", procName, NULL);
297 if (pixt && pthresh) {
304 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
362 l_float32 scorefract,
365 l_int32 w, h, highthresh;
367 PIX *pixn, *pixm, *pixd, *pix1, *pix2, *pix3, *pix4;
369 PROCNAME(
"pixMaskedThreshOnBackgroundNorm");
371 if (pthresh) *pthresh = 0;
372 if (!
pixs || pixGetDepth(
pixs) != 8)
373 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", procName, NULL);
374 if (pixGetColormap(
pixs))
375 return (
PIX *)ERROR_PTR(
"pixs is colormapped", procName, NULL);
376 if (sx < 4 || sy < 4)
377 return (
PIX *)ERROR_PTR(
"sx and sy must be >= 4", procName, NULL);
378 if (mincount > sx * sy) {
379 L_WARNING(
"mincount too large for tile size\n", procName);
380 mincount = (sx * sy) / 3;
385 mincount, 255, smoothx, smoothy);
387 return (
PIX *)ERROR_PTR(
"pixn not made", procName, NULL);
407 if (pthresh) *pthresh = val;
419 highthresh = L_MIN(256, val + 30);
428 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
475 l_int32 i, j, w, h, xrat, yrat;
476 PIX *pixth, *pixd, *tileth, *tiled, *pixt;
477 PIX **ptileth, **ptiled;
480 PROCNAME(
"pixSauvolaBinarizeTiled");
482 if (!ppixth && !ppixd)
483 return ERROR_INT(
"no outputs", procName, 1);
484 if (ppixth) *ppixth = NULL;
485 if (ppixd) *ppixd = NULL;
486 if (!
pixs || pixGetDepth(
pixs) != 8)
487 return ERROR_INT(
"pixs undefined or not 8 bpp", procName, 1);
488 if (pixGetColormap(
pixs))
489 return ERROR_INT(
"pixs is cmapped", procName, 1);
492 return ERROR_INT(
"whsize must be >= 2", procName, 1);
493 if (w < 2 * whsize + 3 || h < 2 * whsize + 3)
494 return ERROR_INT(
"whsize too large for image", procName, 1);
496 return ERROR_INT(
"factor must be >= 0", procName, 1);
498 if (nx <= 1 && ny <= 1)
507 if (xrat < whsize + 2) {
508 nx = w / (whsize + 2);
509 L_WARNING(
"tile width too small; nx reduced to %d\n", procName, nx);
511 if (yrat < whsize + 2) {
512 ny = h / (whsize + 2);
513 L_WARNING(
"tile height too small; ny reduced to %d\n", procName, ny);
515 if (nx <= 1 && ny <= 1)
531 for (i = 0; i < ny; i++) {
532 for (j = 0; j < nx; j++) {
534 ptileth = (ppixth) ? &tileth : NULL;
535 ptiled = (ppixd) ? &tiled : NULL;
604 PIX *pixg, *
pixsc, *pixm, *pixms, *pixth, *pixd;
606 PROCNAME(
"pixSauvolaBinarize");
608 if (ppixm) *ppixm = NULL;
609 if (ppixsd) *ppixsd = NULL;
610 if (ppixth) *ppixth = NULL;
611 if (ppixd) *ppixd = NULL;
612 if (!ppixm && !ppixsd && !ppixth && !ppixd)
613 return ERROR_INT(
"no outputs", procName, 1);
614 if (!
pixs || pixGetDepth(
pixs) != 8)
615 return ERROR_INT(
"pixs undefined or not 8 bpp", procName, 1);
616 if (pixGetColormap(
pixs))
617 return ERROR_INT(
"pixs is cmapped", procName, 1);
620 return ERROR_INT(
"whsize must be >= 2", procName, 1);
621 if (w < 2 * whsize + 3 || h < 2 * whsize + 3)
622 return ERROR_INT(
"whsize too large for image", procName, 1);
624 return ERROR_INT(
"factor must be >= 0", procName, 1);
628 whsize + 1, whsize + 1);
635 return ERROR_INT(
"pixg and pixsc not made", procName, 1);
638 if (ppixm || ppixth || ppixd)
640 if (ppixsd || ppixth || ppixd)
646 pixCopyResolution(pixd,
pixs);
709 l_int32 i, j, w, h, tabsize, wplm, wplms, wplsd, wpld, usetab;
710 l_int32 mv, ms, var, thresh;
711 l_uint32 *datam, *datams, *datasd, *datad;
712 l_uint32 *linem, *linems, *linesd, *lined;
717 PROCNAME(
"pixSauvolaGetThreshold");
719 if (ppixsd) *ppixsd = NULL;
720 if (!pixm || pixGetDepth(pixm) != 8)
721 return (
PIX *)ERROR_PTR(
"pixm undefined or not 8 bpp", procName, NULL);
722 if (pixGetColormap(pixm))
723 return (
PIX *)ERROR_PTR(
"pixm is colormapped", procName, NULL);
724 if (!pixms || pixGetDepth(pixms) != 32)
725 return (
PIX *)ERROR_PTR(
"pixms undefined or not 32 bpp",
728 return (
PIX *)ERROR_PTR(
"factor must be >= 0", procName, NULL);
733 usetab = (w * h > 100000) ? 1 : 0;
736 tab = (l_float32 *)LEPT_CALLOC(tabsize,
sizeof(l_float32));
737 for (i = 0; i < tabsize; i++)
738 tab[i] = sqrtf((l_float32)i);
750 wplm = pixGetWpl(pixm);
751 wplms = pixGetWpl(pixms);
752 if (ppixsd) wplsd = pixGetWpl(pixsd);
753 wpld = pixGetWpl(pixd);
754 for (i = 0; i < h; i++) {
755 linem = datam + i * wplm;
756 linems = datams + i * wplms;
757 if (ppixsd) linesd = datasd + i * wplsd;
758 lined = datad + i * wpld;
759 for (j = 0; j < w; j++) {
766 sd = sqrtf((l_float32)var);
768 thresh = (l_int32)(mv * (1.0 - factor * (1.0 - sd / 128.)));
773 if (usetab) LEPT_FREE(tab);
791 l_int32 i, j, w, h, wpls, wplt, wpld, vals, valt;
792 l_uint32 *datas, *datat, *datad, *lines, *linet, *lined;
795 PROCNAME(
"pixApplyLocalThreshold");
797 if (!
pixs || pixGetDepth(
pixs) != 8)
798 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", procName, NULL);
799 if (pixGetColormap(
pixs))
800 return (
PIX *)ERROR_PTR(
"pixs is colormapped", procName, NULL);
801 if (!pixth || pixGetDepth(pixth) != 8)
802 return (
PIX *)ERROR_PTR(
"pixth undefined or not 8 bpp", procName, NULL);
809 wpls = pixGetWpl(
pixs);
810 wplt = pixGetWpl(pixth);
811 wpld = pixGetWpl(pixd);
812 for (i = 0; i < h; i++) {
813 lines = datas + i * wpls;
814 linet = datat + i * wplt;
815 lined = datad + i * wpld;
816 for (j = 0; j < w; j++) {
892 l_float32 threshdiff,
893 l_int32 *pglobthresh,
897 l_int32 i, thresh, n, n4, n8, mincounts, found, globthresh;
898 l_float32 count4, count8, firstcount4, prevcount4, diff48, diff4;
901 PIX *pix1, *pix2, *pix3;
903 PROCNAME(
"pixThresholdByConnComp");
905 if (pglobthresh) *pglobthresh = 0;
906 if (ppixd) *ppixd = NULL;
907 if (!
pixs || pixGetDepth(
pixs) == 1)
908 return ERROR_INT(
"pixs undefined or 1 bpp", procName, 1);
909 if (pixm && pixGetDepth(pixm) != 1)
910 return ERROR_INT(
"pixm must be 1 bpp", procName, 1);
913 if (start <= 0) start = 80;
914 if (end <= 0) end = 200;
915 if (incr <= 0) incr = 10;
916 if (thresh48 <= 0.0) thresh48 = 0.01;
917 if (threshdiff <= 0.0) threshdiff = 0.01;
919 return ERROR_INT(
"invalid start,end", procName, 1);
922 if (pixGetColormap(
pixs))
926 if (pixGetDepth(pix1) == 32)
942 if (n4 < mincounts) {
943 L_INFO(
"Insufficient component count: %d\n", procName, n4);
953 for (thresh = start, i = 0; thresh <= end; thresh += incr, i++) {
963 "number of cc vs. threshold",
964 "threshold",
"number of cc");
965 gplotAddPlot(gplot, NULL, na4, GPLOT_LINES,
"plot 4cc");
966 gplotAddPlot(gplot, NULL, na8, GPLOT_LINES,
"plot 8cc");
973 for (i = 0; i < n; i++) {
976 prevcount4 = firstcount4;
980 diff48 = (count4 - count8) / firstcount4;
981 diff4 = L_ABS(prevcount4 - count4) / firstcount4;
983 fprintf(stderr,
"diff48 = %7.3f, diff4 = %7.3f\n",
986 if (diff48 < thresh48 && diff4 < threshdiff) {
997 globthresh = start + i * incr;
998 if (pglobthresh) *pglobthresh = globthresh;
1001 pixCopyResolution(*ppixd,
pixs);
1003 if (debugflag) fprintf(stderr,
"global threshold = %d\n", globthresh);
1008 if (debugflag) fprintf(stderr,
"no global threshold found\n");
void gplotDestroy(GPLOT **pgplot)
gplotDestroy()
PIX * pixConvertTo1(PIX *pixs, l_int32 threshold)
pixConvertTo1()
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
l_ok pixSauvolaBinarize(PIX *pixs, l_int32 whsize, l_float32 factor, l_int32 addborder, PIX **ppixm, PIX **ppixsd, PIX **ppixth, PIX **ppixd)
pixSauvolaBinarize()
l_ok gplotAddPlot(GPLOT *gplot, NUMA *nax, NUMA *nay, l_int32 plotstyle, const char *plottitle)
gplotAddPlot()
PIX * pixOtsuThreshOnBackgroundNorm(PIX *pixs, PIX *pixim, l_int32 sx, l_int32 sy, l_int32 thresh, l_int32 mincount, l_int32 bgval, l_int32 smoothx, l_int32 smoothy, l_float32 scorefract, l_int32 *pthresh)
pixOtsuThreshOnBackgroundNorm()
l_ok pixSetMasked(PIX *pixd, PIX *pixm, l_uint32 val)
pixSetMasked()
PIX * pixWindowedMean(PIX *pixs, l_int32 wc, l_int32 hc, l_int32 hasborder, l_int32 normflag)
pixWindowedMean()
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
l_ok gplotMakeOutput(GPLOT *gplot)
gplotMakeOutput()
GPLOT * gplotCreate(const char *rootname, l_int32 outformat, const char *title, const char *xlabel, const char *ylabel)
gplotCreate()
PIX * pixMaskedThreshOnBackgroundNorm(PIX *pixs, PIX *pixim, l_int32 sx, l_int32 sy, l_int32 thresh, l_int32 mincount, l_int32 smoothx, l_int32 smoothy, l_float32 scorefract, l_int32 *pthresh)
pixMaskedThreshOnBackgroundNorm()
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixSauvolaGetThreshold(PIX *pixm, PIX *pixms, l_float32 factor, PIX **ppixsd)
pixSauvolaGetThreshold()
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
NUMA * numaCreate(l_int32 n)
numaCreate()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
l_ok pixTilingPaintTile(PIX *pixd, l_int32 i, l_int32 j, PIX *pixs, PIXTILING *pt)
pixTilingPaintTile()
PIX * pixThresholdToBinary(PIX *pixs, l_int32 thresh)
pixThresholdToBinary()
PIXTILING * pixTilingCreate(PIX *pixs, l_int32 nx, l_int32 ny, l_int32 w, l_int32 h, l_int32 xoverlap, l_int32 yoverlap)
pixTilingCreate()
void pixTilingDestroy(PIXTILING **ppt)
pixTilingDestroy()
l_ok pixCombineMasked(PIX *pixd, PIX *pixs, PIX *pixm)
pixCombineMasked()
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
l_ok pixSplitDistributionFgBg(PIX *pixs, l_float32 scorefract, l_int32 factor, l_int32 *pthresh, l_int32 *pfgval, l_int32 *pbgval, PIX **ppixdb)
pixSplitDistributionFgBg()
l_int32 numaGetCount(NUMA *na)
numaGetCount()
PIX * pixBackgroundNormFlex(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 smoothx, l_int32 smoothy, l_int32 delta)
pixBackgroundNormFlex()
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
PIX * pixWindowedMeanSquare(PIX *pixs, l_int32 wc, l_int32 hc, l_int32 hasborder)
pixWindowedMeanSquare()
#define SET_DATA_BYTE(pdata, n, val)
PIX * pixConvertRGBToGrayMinMax(PIX *pixs, l_int32 type)
pixConvertRGBToGrayMinMax()
#define GET_DATA_BYTE(pdata, n)
l_ok numaSetParameters(NUMA *na, l_float32 startx, l_float32 delx)
numaSetParameters()
PIX * pixTilingGetTile(PIXTILING *pt, l_int32 i, l_int32 j)
pixTilingGetTile()
PIX * pixCreateNoInit(l_int32 width, l_int32 height, l_int32 depth)
pixCreateNoInit()
PIX * pixClone(PIX *pixs)
pixClone()
void pixDestroy(PIX **ppix)
pixDestroy()
void numaDestroy(NUMA **pna)
numaDestroy()
l_ok pixThresholdByConnComp(PIX *pixs, PIX *pixm, l_int32 start, l_int32 end, l_int32 incr, l_float32 thresh48, l_float32 threshdiff, l_int32 *pglobthresh, PIX **ppixd, l_int32 debugflag)
pixThresholdByConnComp()
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
l_ok pixOtsuAdaptiveThreshold(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 smoothx, l_int32 smoothy, l_float32 scorefract, PIX **ppixth, PIX **ppixd)
pixOtsuAdaptiveThreshold()
l_ok pixSauvolaBinarizeTiled(PIX *pixs, l_int32 whsize, l_float32 factor, l_int32 nx, l_int32 ny, PIX **ppixth, PIX **ppixd)
pixSauvolaBinarizeTiled()
PIX * pixBackgroundNorm(PIX *pixs, PIX *pixim, PIX *pixg, l_int32 sx, l_int32 sy, l_int32 thresh, l_int32 mincount, l_int32 bgval, l_int32 smoothx, l_int32 smoothy)
pixBackgroundNorm()
PIX * pixBlockconv(PIX *pix, l_int32 wc, l_int32 hc)
pixBlockconv()
PIX * pixApplyLocalThreshold(PIX *pixs, PIX *pixth, l_int32 redfactor)
pixApplyLocalThreshold()
l_ok pixTilingNoStripOnPaint(PIXTILING *pt)
pixTilingNoStripOnPaint()
l_ok pixCountConnComp(PIX *pixs, l_int32 connectivity, l_int32 *pcount)
pixCountConnComp()
#define SET_DATA_BIT(pdata, n)