88 #include <config_auto.h>
92 #include "allheaders.h"
162 l_float32 scorefract,
166 l_int32 w, h, nx, ny, i, j, thresh;
168 PIX *pixt, *pixb, *pixthresh, *pixth, *pixd;
171 PROCNAME(
"pixOtsuAdaptiveThreshold");
173 if (!ppixth && !ppixd)
174 return ERROR_INT(
"neither &pixth nor &pixd defined", procName, 1);
175 if (ppixth) *ppixth = NULL;
176 if (ppixd) *ppixd = NULL;
177 if (!pixs || pixGetDepth(pixs) != 8)
178 return ERROR_INT(
"pixs not defined or not 8 bpp", procName, 1);
179 if (sx < 16 || sy < 16)
180 return ERROR_INT(
"sx and sy must be >= 16", procName, 1);
184 nx = L_MAX(1, w / sx);
185 ny = L_MAX(1, h / sy);
186 smoothx = L_MIN(smoothx, (nx - 1) / 2);
187 smoothy = L_MIN(smoothy, (ny - 1) / 2);
190 for (i = 0; i < ny; i++) {
191 for (j = 0; j < nx; j++) {
201 if (smoothx > 0 || smoothy > 0)
210 pixCopyResolution(pixd, pixs);
211 for (i = 0; i < ny; i++) {
212 for (j = 0; j < nx; j++) {
282 l_float32 scorefract,
287 PIX *pixn, *pixt, *pixd;
289 PROCNAME(
"pixOtsuThreshOnBackgroundNorm");
291 if (pthresh) *pthresh = 0;
292 if (!pixs || pixGetDepth(pixs) != 8)
293 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", procName, NULL);
294 if (pixGetColormap(pixs))
295 return (
PIX *)ERROR_PTR(
"pixs is colormapped", procName, NULL);
296 if (sx < 4 || sy < 4)
297 return (
PIX *)ERROR_PTR(
"sx and sy must be >= 4", procName, NULL);
298 if (mincount > sx * sy) {
299 L_WARNING(
"mincount too large for tile size\n", procName);
300 mincount = (sx * sy) / 3;
304 mincount, bgval, smoothx, smoothy);
306 return (
PIX *)ERROR_PTR(
"pixn not made", procName, NULL);
314 if (pixt && pthresh) {
321 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
379 l_float32 scorefract,
382 l_int32 w, h, highthresh;
384 PIX *pixn, *pixm, *pixd, *pix1, *pix2, *pix3, *pix4;
386 PROCNAME(
"pixMaskedThreshOnBackgroundNorm");
388 if (pthresh) *pthresh = 0;
389 if (!pixs || pixGetDepth(pixs) != 8)
390 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", procName, NULL);
391 if (pixGetColormap(pixs))
392 return (
PIX *)ERROR_PTR(
"pixs is colormapped", procName, NULL);
393 if (sx < 4 || sy < 4)
394 return (
PIX *)ERROR_PTR(
"sx and sy must be >= 4", procName, NULL);
395 if (mincount > sx * sy) {
396 L_WARNING(
"mincount too large for tile size\n", procName);
397 mincount = (sx * sy) / 3;
402 mincount, 255, smoothx, smoothy);
404 return (
PIX *)ERROR_PTR(
"pixn not made", procName, NULL);
424 if (pthresh) *pthresh = val;
436 highthresh = L_MIN(256, val + 30);
445 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
492 l_int32 i, j, w, h, xrat, yrat;
493 PIX *pixth, *pixd, *tileth, *tiled, *pixt;
494 PIX **ptileth, **ptiled;
497 PROCNAME(
"pixSauvolaBinarizeTiled");
499 if (!ppixth && !ppixd)
500 return ERROR_INT(
"no outputs", procName, 1);
501 if (ppixth) *ppixth = NULL;
502 if (ppixd) *ppixd = NULL;
503 if (!pixs || pixGetDepth(pixs) != 8)
504 return ERROR_INT(
"pixs undefined or not 8 bpp", procName, 1);
505 if (pixGetColormap(pixs))
506 return ERROR_INT(
"pixs is cmapped", procName, 1);
509 return ERROR_INT(
"whsize must be >= 2", procName, 1);
510 if (w < 2 * whsize + 3 || h < 2 * whsize + 3)
511 return ERROR_INT(
"whsize too large for image", procName, 1);
513 return ERROR_INT(
"factor must be >= 0", procName, 1);
515 if (nx <= 1 && ny <= 1)
524 if (xrat < whsize + 2) {
525 nx = w / (whsize + 2);
526 L_WARNING(
"tile width too small; nx reduced to %d\n", procName, nx);
528 if (yrat < whsize + 2) {
529 ny = h / (whsize + 2);
530 L_WARNING(
"tile height too small; ny reduced to %d\n", procName, ny);
532 if (nx <= 1 && ny <= 1)
548 for (i = 0; i < ny; i++) {
549 for (j = 0; j < nx; j++) {
551 ptileth = (ppixth) ? &tileth : NULL;
552 ptiled = (ppixd) ? &tiled : NULL;
621 PIX *pixg, *pixsc, *pixm, *pixms, *pixth, *pixd;
623 PROCNAME(
"pixSauvolaBinarize");
625 if (ppixm) *ppixm = NULL;
626 if (ppixsd) *ppixsd = NULL;
627 if (ppixth) *ppixth = NULL;
628 if (ppixd) *ppixd = NULL;
629 if (!ppixm && !ppixsd && !ppixth && !ppixd)
630 return ERROR_INT(
"no outputs", procName, 1);
631 if (!pixs || pixGetDepth(pixs) != 8)
632 return ERROR_INT(
"pixs undefined or not 8 bpp", procName, 1);
633 if (pixGetColormap(pixs))
634 return ERROR_INT(
"pixs is cmapped", procName, 1);
637 return ERROR_INT(
"whsize must be >= 2", procName, 1);
638 if (w < 2 * whsize + 3 || h < 2 * whsize + 3)
639 return ERROR_INT(
"whsize too large for image", procName, 1);
641 return ERROR_INT(
"factor must be >= 0", procName, 1);
645 whsize + 1, whsize + 1);
652 return ERROR_INT(
"pixg and pixsc not made", procName, 1);
655 if (ppixm || ppixth || ppixd)
657 if (ppixsd || ppixth || ppixd)
663 pixCopyResolution(pixd, pixs);
726 l_int32 i, j, w, h, tabsize, wplm, wplms, wplsd, wpld, usetab;
727 l_int32 mv, ms, var, thresh;
728 l_uint32 *datam, *datams, *datasd, *datad;
729 l_uint32 *linem, *linems, *linesd, *lined;
734 PROCNAME(
"pixSauvolaGetThreshold");
736 if (ppixsd) *ppixsd = NULL;
737 if (!pixm || pixGetDepth(pixm) != 8)
738 return (
PIX *)ERROR_PTR(
"pixm undefined or not 8 bpp", procName, NULL);
739 if (pixGetColormap(pixm))
740 return (
PIX *)ERROR_PTR(
"pixm is colormapped", procName, NULL);
741 if (!pixms || pixGetDepth(pixms) != 32)
742 return (
PIX *)ERROR_PTR(
"pixms undefined or not 32 bpp",
745 return (
PIX *)ERROR_PTR(
"factor must be >= 0", procName, NULL);
750 usetab = (w * h > 100000) ? 1 : 0;
753 tab = (l_float32 *)LEPT_CALLOC(tabsize,
sizeof(l_float32));
754 for (i = 0; i < tabsize; i++)
755 tab[i] = sqrtf((l_float32)i);
767 wplm = pixGetWpl(pixm);
768 wplms = pixGetWpl(pixms);
769 if (ppixsd) wplsd = pixGetWpl(pixsd);
770 wpld = pixGetWpl(pixd);
771 for (i = 0; i < h; i++) {
772 linem = datam + i * wplm;
773 linems = datams + i * wplms;
774 if (ppixsd) linesd = datasd + i * wplsd;
775 lined = datad + i * wpld;
776 for (j = 0; j < w; j++) {
783 sd = sqrtf((l_float32)var);
785 thresh = (l_int32)(mv * (1.0 - factor * (1.0 - sd / 128.)));
790 if (usetab) LEPT_FREE(tab);
806 l_int32 i, j, w, h, wpls, wplt, wpld, vals, valt;
807 l_uint32 *datas, *datat, *datad, *lines, *linet, *lined;
810 PROCNAME(
"pixApplyLocalThreshold");
812 if (!pixs || pixGetDepth(pixs) != 8)
813 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", procName, NULL);
814 if (pixGetColormap(pixs))
815 return (
PIX *)ERROR_PTR(
"pixs is colormapped", procName, NULL);
816 if (!pixth || pixGetDepth(pixth) != 8)
817 return (
PIX *)ERROR_PTR(
"pixth undefined or not 8 bpp", procName, NULL);
824 wpls = pixGetWpl(pixs);
825 wplt = pixGetWpl(pixth);
826 wpld = pixGetWpl(pixd);
827 for (i = 0; i < h; i++) {
828 lines = datas + i * wpls;
829 linet = datat + i * wplt;
830 lined = datad + i * wpld;
831 for (j = 0; j < w; j++) {
869 l_int32 w, h, d, nx, ny;
870 PIX *pixg, *pix1, *pixd;
872 PROCNAME(
"pixSauvolaOnContrastNorm");
874 if (ppixn) *ppixn = NULL;
875 if (ppixth) *ppixth = NULL;
876 if (!pixs || (d = pixGetDepth(pixs)) < 8)
877 return (
PIX *)ERROR_PTR(
"pixs undefined or d < 8 bpp", procName, NULL);
887 nx = L_MAX(1, (w + 125) / 250);
888 ny = L_MAX(1, (h + 125) / 250);
925 PIX *pixg, *pix1, *pixd;
927 PROCNAME(
"pixThreshOnDoubleNorm");
929 if (!pixs || (d = pixGetDepth(pixs)) < 8)
930 return (
PIX *)ERROR_PTR(
"pixs undefined or d < 8 bpp", procName, NULL);
940 ival = L_MIN(ival, 110);
1019 l_float32 threshdiff,
1020 l_int32 *pglobthresh,
1024 l_int32 i, thresh, n, n4, n8, mincounts, found, globthresh;
1025 l_float32 count4, count8, firstcount4, prevcount4, diff48, diff4;
1028 PIX *pix1, *pix2, *pix3;
1030 PROCNAME(
"pixThresholdByConnComp");
1032 if (pglobthresh) *pglobthresh = 0;
1033 if (ppixd) *ppixd = NULL;
1034 if (!pixs || pixGetDepth(pixs) == 1)
1035 return ERROR_INT(
"pixs undefined or 1 bpp", procName, 1);
1036 if (pixm && pixGetDepth(pixm) != 1)
1037 return ERROR_INT(
"pixm must be 1 bpp", procName, 1);
1040 if (start <= 0) start = 80;
1041 if (end <= 0) end = 200;
1042 if (incr <= 0) incr = 10;
1043 if (thresh48 <= 0.0) thresh48 = 0.01;
1044 if (threshdiff <= 0.0) threshdiff = 0.01;
1046 return ERROR_INT(
"invalid start,end", procName, 1);
1049 if (pixGetColormap(pixs))
1053 if (pixGetDepth(pix1) == 32)
1069 if (n4 < mincounts) {
1070 L_INFO(
"Insufficient component count: %d\n", procName, n4);
1080 for (thresh = start, i = 0; thresh <= end; thresh += incr, i++) {
1090 gplot =
gplotCreate(
"/tmp/lept/binarize", GPLOT_PNG,
1091 "number of cc vs. threshold",
1092 "threshold",
"number of cc");
1093 gplotAddPlot(gplot, NULL, na4, GPLOT_LINES,
"plot 4cc");
1094 gplotAddPlot(gplot, NULL, na8, GPLOT_LINES,
"plot 8cc");
1101 for (i = 0; i < n; i++) {
1104 prevcount4 = firstcount4;
1108 diff48 = (count4 - count8) / firstcount4;
1109 diff4 = L_ABS(prevcount4 - count4) / firstcount4;
1114 if (diff48 < thresh48 && diff4 < threshdiff) {
1118 prevcount4 = count4;
1125 globthresh = start + i * incr;
1126 if (pglobthresh) *pglobthresh = globthresh;
1129 pixCopyResolution(*ppixd, pixs);
1131 if (debugflag)
lept_stderr(
"global threshold = %d\n", globthresh);
1136 if (debugflag)
lept_stderr(
"no global threshold found\n");
1177 l_float32 maxval, fract;
1178 NUMA *na1, *na2, *na3;
1180 PROCNAME(
"pixThresholdByHisto");
1182 if (ppixhisto) *ppixhisto = NULL;
1183 if (ppixd) *ppixd = NULL;
1185 return ERROR_INT(
"&thresh not defined", procName, 1);
1187 if (!pixs || pixGetDepth(pixs) != 8)
1188 return ERROR_INT(
"pixs undefined or not 8 bpp", procName, 1);
1189 if (pixGetColormap(pixs))
1190 return ERROR_INT(
"pixs has colormap", procName, 1);
1192 return ERROR_INT(
"sampling must be >= 1", procName, 1);
1193 if (halfw <= 0) halfw = 20;
1194 if (delta <= 0.0) delta = 0.1;
1206 L_INFO(
"fractional area under first peak: %5.3f\n", procName, fract);
1210 gplotSimple1(na3, GPLOT_PNG,
"/tmp/lept/histo/histo", NULL);
1211 *ppixhisto =
pixRead(
"/tmp/lept/histo/histo.png");
1215 if (*pthresh > 0 && ppixd)
PIX * pixBackgroundNormSimple(PIX *pixs, PIX *pixim, PIX *pixg)
pixBackgroundNormSimple()
PIX * pixContrastNorm(PIX *pixd, PIX *pixs, l_int32 sx, l_int32 sy, l_int32 mindiff, l_int32 smoothx, l_int32 smoothy)
pixContrastNorm()
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 * pixBackgroundNormFlex(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 smoothx, l_int32 smoothy, l_int32 delta)
pixBackgroundNormFlex()
#define SET_DATA_BIT(pdata, n)
#define GET_DATA_BYTE(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
l_ok pixThresholdByHisto(PIX *pixs, l_int32 factor, l_int32 halfw, l_float32 delta, l_int32 *pthresh, PIX **ppixd, PIX **ppixhisto)
pixThresholdByHisto()
static PIX * pixApplyLocalThreshold(PIX *pixs, PIX *pixth)
pixApplyLocalThreshold()
l_ok pixSauvolaBinarizeTiled(PIX *pixs, l_int32 whsize, l_float32 factor, l_int32 nx, l_int32 ny, PIX **ppixth, PIX **ppixd)
pixSauvolaBinarizeTiled()
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()
static PIX * pixSauvolaGetThreshold(PIX *pixm, PIX *pixms, l_float32 factor, PIX **ppixsd)
pixSauvolaGetThreshold()
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 * pixSauvolaOnContrastNorm(PIX *pixs, l_int32 mindiff, PIX **ppixn, PIX **ppixth)
pixSauvolaOnContrastNorm()
l_ok pixSauvolaBinarize(PIX *pixs, l_int32 whsize, l_float32 factor, l_int32 addborder, PIX **ppixm, PIX **ppixsd, PIX **ppixth, PIX **ppixd)
pixSauvolaBinarize()
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()
PIX * pixThreshOnDoubleNorm(PIX *pixs, l_int32 mindiff)
pixTheshOnDoubleNorm()
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 pixCountConnComp(PIX *pixs, l_int32 connectivity, l_int32 *pcount)
pixCountConnComp()
PIX * pixWindowedMeanSquare(PIX *pixs, l_int32 wc, l_int32 hc, l_int32 hasborder)
pixWindowedMeanSquare()
PIX * pixBlockconv(PIX *pix, l_int32 wc, l_int32 hc)
pixBlockconv()
PIX * pixWindowedMean(PIX *pixs, l_int32 wc, l_int32 hc, l_int32 hasborder, l_int32 normflag)
pixWindowedMean()
l_ok gplotAddPlot(GPLOT *gplot, NUMA *nax, NUMA *nay, l_int32 plotstyle, const char *plotlabel)
gplotAddPlot()
l_ok gplotMakeOutput(GPLOT *gplot)
gplotMakeOutput()
GPLOT * gplotCreate(const char *rootname, l_int32 outformat, const char *title, const char *xlabel, const char *ylabel)
gplotCreate()
void gplotDestroy(GPLOT **pgplot)
gplotDestroy()
l_ok gplotSimple1(NUMA *na, l_int32 outformat, const char *outroot, const char *title)
gplotSimple1()
PIX * pixThresholdToBinary(PIX *pixs, l_int32 thresh)
pixThresholdToBinary()
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
NUMA * numaCreate(l_int32 n)
numaCreate()
void numaDestroy(NUMA **pna)
numaDestroy()
l_int32 numaGetCount(NUMA *na)
numaGetCount()
l_ok numaSetParameters(NUMA *na, l_float32 startx, l_float32 delx)
numaSetParameters()
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
NUMA * numaWindowedMean(NUMA *nas, l_int32 wc)
numaWindowedMean()
NUMA * numaTransform(NUMA *nas, l_float32 shift, l_float32 scale)
numaTransform()
l_ok numaFindLocForThreshold(NUMA *na, l_int32 skip, l_int32 *pthresh, l_float32 *pfract)
numaFindLocForThreshold()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
void pixDestroy(PIX **ppix)
pixDestroy()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixClone(PIX *pixs)
pixClone()
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
l_ok pixSetMasked(PIX *pixd, PIX *pixm, l_uint32 val)
pixSetMasked()
l_ok pixCombineMasked(PIX *pixd, PIX *pixs, PIX *pixm)
pixCombineMasked()
NUMA * pixGetGrayHistogram(PIX *pixs, l_int32 factor)
pixGetGrayHistogram()
l_ok pixSplitDistributionFgBg(PIX *pixs, l_float32 scorefract, l_int32 factor, l_int32 *pthresh, l_int32 *pfgval, l_int32 *pbgval, PIX **ppixdb)
pixSplitDistributionFgBg()
@ REMOVE_CMAP_BASED_ON_SRC
PIX * pixConvertRGBToGrayMinMax(PIX *pixs, l_int32 type)
pixConvertRGBToGrayMinMax()
PIX * pixConvertRGBToGray(PIX *pixs, l_float32 rwt, l_float32 gwt, l_float32 bwt)
pixConvertRGBToGray()
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
PIX * pixConvertTo1(PIX *pixs, l_int32 threshold)
pixConvertTo1()
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
l_ok pixTilingNoStripOnPaint(PIXTILING *pt)
pixTilingNoStripOnPaint()
PIX * pixTilingGetTile(PIXTILING *pt, l_int32 i, l_int32 j)
pixTilingGetTile()
void pixTilingDestroy(PIXTILING **ppt)
pixTilingDestroy()
l_ok pixTilingPaintTile(PIX *pixd, l_int32 i, l_int32 j, PIX *pixs, PIXTILING *pt)
pixTilingPaintTile()
PIXTILING * pixTilingCreate(PIX *pixs, l_int32 nx, l_int32 ny, l_int32 w, l_int32 h, l_int32 xoverlap, l_int32 yoverlap)
pixTilingCreate()
PIX * pixRead(const char *filename)
pixRead()
void lept_stderr(const char *fmt,...)
lept_stderr()
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()