Leptonica  1.82.0
Image processing and image analysis suite
pix4.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
85 #ifdef HAVE_CONFIG_H
86 #include <config_auto.h>
87 #endif /* HAVE_CONFIG_H */
88 
89 #include <string.h>
90 #include <math.h>
91 #include "allheaders.h"
92 
93 
94 /*------------------------------------------------------------------*
95  * Pixel histogram and averaging *
96  *------------------------------------------------------------------*/
114 NUMA *
116  l_int32 factor)
117 {
118 l_int32 i, j, w, h, d, wpl, val, size, count;
119 l_uint32 *data, *line;
120 l_float32 *array;
121 NUMA *na;
122 PIX *pixg;
123 
124  PROCNAME("pixGetGrayHistogram");
125 
126  if (!pixs)
127  return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
128  d = pixGetDepth(pixs);
129  if (d > 16)
130  return (NUMA *)ERROR_PTR("depth not in {1,2,4,8,16}", procName, NULL);
131  if (factor < 1)
132  return (NUMA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
133 
134  if (pixGetColormap(pixs))
136  else
137  pixg = pixClone(pixs);
138 
139  pixGetDimensions(pixg, &w, &h, &d);
140  size = 1 << d;
141  if ((na = numaCreate(size)) == NULL) {
142  pixDestroy(&pixg);
143  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
144  }
145  numaSetCount(na, size); /* all initialized to 0.0 */
146  array = numaGetFArray(na, L_NOCOPY);
147 
148  if (d == 1) { /* special case */
149  pixCountPixels(pixg, &count, NULL);
150  array[0] = w * h - count;
151  array[1] = count;
152  pixDestroy(&pixg);
153  return na;
154  }
155 
156  wpl = pixGetWpl(pixg);
157  data = pixGetData(pixg);
158  for (i = 0; i < h; i += factor) {
159  line = data + i * wpl;
160  if (d == 2) {
161  for (j = 0; j < w; j += factor) {
162  val = GET_DATA_DIBIT(line, j);
163  array[val] += 1.0;
164  }
165  } else if (d == 4) {
166  for (j = 0; j < w; j += factor) {
167  val = GET_DATA_QBIT(line, j);
168  array[val] += 1.0;
169  }
170  } else if (d == 8) {
171  for (j = 0; j < w; j += factor) {
172  val = GET_DATA_BYTE(line, j);
173  array[val] += 1.0;
174  }
175  } else { /* d == 16 */
176  for (j = 0; j < w; j += factor) {
177  val = GET_DATA_TWO_BYTES(line, j);
178  array[val] += 1.0;
179  }
180  }
181  }
182 
183  pixDestroy(&pixg);
184  return na;
185 }
186 
187 
210 NUMA *
212  PIX *pixm,
213  l_int32 x,
214  l_int32 y,
215  l_int32 factor)
216 {
217 l_int32 i, j, w, h, wm, hm, dm, wplg, wplm, val;
218 l_uint32 *datag, *datam, *lineg, *linem;
219 l_float32 *array;
220 NUMA *na;
221 PIX *pixg;
222 
223  PROCNAME("pixGetGrayHistogramMasked");
224 
225  if (!pixm)
226  return pixGetGrayHistogram(pixs, factor);
227  if (!pixs)
228  return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
229  if (pixGetDepth(pixs) != 8 && !pixGetColormap(pixs))
230  return (NUMA *)ERROR_PTR("pixs neither 8 bpp nor colormapped",
231  procName, NULL);
232  pixGetDimensions(pixm, &wm, &hm, &dm);
233  if (dm != 1)
234  return (NUMA *)ERROR_PTR("pixm not 1 bpp", procName, NULL);
235  if (factor < 1)
236  return (NUMA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
237 
238  if ((na = numaCreate(256)) == NULL)
239  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
240  numaSetCount(na, 256); /* all initialized to 0.0 */
241  array = numaGetFArray(na, L_NOCOPY);
242 
243  if (pixGetColormap(pixs))
245  else
246  pixg = pixClone(pixs);
247  pixGetDimensions(pixg, &w, &h, NULL);
248  datag = pixGetData(pixg);
249  wplg = pixGetWpl(pixg);
250  datam = pixGetData(pixm);
251  wplm = pixGetWpl(pixm);
252 
253  /* Generate the histogram */
254  for (i = 0; i < hm; i += factor) {
255  if (y + i < 0 || y + i >= h) continue;
256  lineg = datag + (y + i) * wplg;
257  linem = datam + i * wplm;
258  for (j = 0; j < wm; j += factor) {
259  if (x + j < 0 || x + j >= w) continue;
260  if (GET_DATA_BIT(linem, j)) {
261  val = GET_DATA_BYTE(lineg, x + j);
262  array[val] += 1.0;
263  }
264  }
265  }
266 
267  pixDestroy(&pixg);
268  return na;
269 }
270 
271 
290 NUMA *
292  BOX *box,
293  l_int32 factor)
294 {
295 l_int32 i, j, bx, by, bw, bh, w, h, wplg, val;
296 l_uint32 *datag, *lineg;
297 l_float32 *array;
298 NUMA *na;
299 PIX *pixg;
300 
301  PROCNAME("pixGetGrayHistogramInRect");
302 
303  if (!box)
304  return pixGetGrayHistogram(pixs, factor);
305  if (!pixs)
306  return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
307  if (pixGetDepth(pixs) != 8 && !pixGetColormap(pixs))
308  return (NUMA *)ERROR_PTR("pixs neither 8 bpp nor colormapped",
309  procName, NULL);
310  if (factor < 1)
311  return (NUMA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
312 
313  if ((na = numaCreate(256)) == NULL)
314  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
315  numaSetCount(na, 256); /* all initialized to 0.0 */
316  array = numaGetFArray(na, L_NOCOPY);
317 
318  if (pixGetColormap(pixs))
320  else
321  pixg = pixClone(pixs);
322  pixGetDimensions(pixg, &w, &h, NULL);
323  datag = pixGetData(pixg);
324  wplg = pixGetWpl(pixg);
325  boxGetGeometry(box, &bx, &by, &bw, &bh);
326 
327  /* Generate the histogram */
328  for (i = 0; i < bh; i += factor) {
329  if (by + i < 0 || by + i >= h) continue;
330  lineg = datag + (by + i) * wplg;
331  for (j = 0; j < bw; j += factor) {
332  if (bx + j < 0 || bx + j >= w) continue;
333  val = GET_DATA_BYTE(lineg, bx + j);
334  array[val] += 1.0;
335  }
336  }
337 
338  pixDestroy(&pixg);
339  return na;
340 }
341 
342 
358 NUMAA *
360  l_int32 factor,
361  l_int32 nx,
362  l_int32 ny)
363 {
364 l_int32 i, n;
365 NUMA *na;
366 NUMAA *naa;
367 PIX *pix1, *pix2;
368 PIXA *pixa;
369 
370  PROCNAME("pixGetGrayHistogramTiled");
371 
372  if (!pixs)
373  return (NUMAA *)ERROR_PTR("pixs not defined", procName, NULL);
374  if (factor < 1)
375  return (NUMAA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
376  if (nx < 1 || ny < 1)
377  return (NUMAA *)ERROR_PTR("nx and ny must both be > 0", procName, NULL);
378 
379  n = nx * ny;
380  if ((naa = numaaCreate(n)) == NULL)
381  return (NUMAA *)ERROR_PTR("naa not made", procName, NULL);
382 
383  pix1 = pixConvertTo8(pixs, FALSE);
384  pixa = pixaSplitPix(pix1, nx, ny, 0, 0);
385  for (i = 0; i < n; i++) {
386  pix2 = pixaGetPix(pixa, i, L_CLONE);
387  na = pixGetGrayHistogram(pix2, factor);
388  numaaAddNuma(naa, na, L_INSERT);
389  pixDestroy(&pix2);
390  }
391 
392  pixDestroy(&pix1);
393  pixaDestroy(&pixa);
394  return naa;
395 }
396 
397 
415 l_ok
417  l_int32 factor,
418  NUMA **pnar,
419  NUMA **pnag,
420  NUMA **pnab)
421 {
422 l_int32 i, j, w, h, d, wpl, index, rval, gval, bval;
423 l_uint32 *data, *line;
424 l_float32 *rarray, *garray, *barray;
425 NUMA *nar, *nag, *nab;
426 PIXCMAP *cmap;
427 
428  PROCNAME("pixGetColorHistogram");
429 
430  if (pnar) *pnar = NULL;
431  if (pnag) *pnag = NULL;
432  if (pnab) *pnab = NULL;
433  if (!pnar || !pnag || !pnab)
434  return ERROR_INT("&nar, &nag, &nab not all defined", procName, 1);
435  if (!pixs)
436  return ERROR_INT("pixs not defined", procName, 1);
437  pixGetDimensions(pixs, &w, &h, &d);
438  cmap = pixGetColormap(pixs);
439  if (cmap && (d != 2 && d != 4 && d != 8))
440  return ERROR_INT("colormap and not 2, 4, or 8 bpp", procName, 1);
441  if (!cmap && d != 32)
442  return ERROR_INT("no colormap and not rgb", procName, 1);
443  if (factor < 1)
444  return ERROR_INT("sampling factor must be >= 1", procName, 1);
445 
446  /* Set up the histogram arrays */
447  nar = numaCreate(256);
448  nag = numaCreate(256);
449  nab = numaCreate(256);
450  numaSetCount(nar, 256);
451  numaSetCount(nag, 256);
452  numaSetCount(nab, 256);
453  rarray = numaGetFArray(nar, L_NOCOPY);
454  garray = numaGetFArray(nag, L_NOCOPY);
455  barray = numaGetFArray(nab, L_NOCOPY);
456  *pnar = nar;
457  *pnag = nag;
458  *pnab = nab;
459 
460  /* Generate the color histograms */
461  data = pixGetData(pixs);
462  wpl = pixGetWpl(pixs);
463  if (cmap) {
464  for (i = 0; i < h; i += factor) {
465  line = data + i * wpl;
466  for (j = 0; j < w; j += factor) {
467  if (d == 8)
468  index = GET_DATA_BYTE(line, j);
469  else if (d == 4)
470  index = GET_DATA_QBIT(line, j);
471  else /* 2 bpp */
472  index = GET_DATA_DIBIT(line, j);
473  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
474  rarray[rval] += 1.0;
475  garray[gval] += 1.0;
476  barray[bval] += 1.0;
477  }
478  }
479  } else { /* 32 bpp rgb */
480  for (i = 0; i < h; i += factor) {
481  line = data + i * wpl;
482  for (j = 0; j < w; j += factor) {
483  extractRGBValues(line[j], &rval, &gval, &bval);
484  rarray[rval] += 1.0;
485  garray[gval] += 1.0;
486  barray[bval] += 1.0;
487  }
488  }
489  }
490 
491  return 0;
492 }
493 
494 
517 l_ok
519  PIX *pixm,
520  l_int32 x,
521  l_int32 y,
522  l_int32 factor,
523  NUMA **pnar,
524  NUMA **pnag,
525  NUMA **pnab)
526 {
527 l_int32 i, j, w, h, d, wm, hm, dm, wpls, wplm, index, rval, gval, bval;
528 l_uint32 *datas, *datam, *lines, *linem;
529 l_float32 *rarray, *garray, *barray;
530 NUMA *nar, *nag, *nab;
531 PIXCMAP *cmap;
532 
533  PROCNAME("pixGetColorHistogramMasked");
534 
535  if (!pixm)
536  return pixGetColorHistogram(pixs, factor, pnar, pnag, pnab);
537 
538  if (pnar) *pnar = NULL;
539  if (pnag) *pnag = NULL;
540  if (pnab) *pnab = NULL;
541  if (!pnar || !pnag || !pnab)
542  return ERROR_INT("&nar, &nag, &nab not all defined", procName, 1);
543  if (!pixs)
544  return ERROR_INT("pixs not defined", procName, 1);
545  pixGetDimensions(pixs, &w, &h, &d);
546  cmap = pixGetColormap(pixs);
547  if (cmap && (d != 2 && d != 4 && d != 8))
548  return ERROR_INT("colormap and not 2, 4, or 8 bpp", procName, 1);
549  if (!cmap && d != 32)
550  return ERROR_INT("no colormap and not rgb", procName, 1);
551  pixGetDimensions(pixm, &wm, &hm, &dm);
552  if (dm != 1)
553  return ERROR_INT("pixm not 1 bpp", procName, 1);
554  if (factor < 1)
555  return ERROR_INT("sampling factor must be >= 1", procName, 1);
556 
557  /* Set up the histogram arrays */
558  nar = numaCreate(256);
559  nag = numaCreate(256);
560  nab = numaCreate(256);
561  numaSetCount(nar, 256);
562  numaSetCount(nag, 256);
563  numaSetCount(nab, 256);
564  rarray = numaGetFArray(nar, L_NOCOPY);
565  garray = numaGetFArray(nag, L_NOCOPY);
566  barray = numaGetFArray(nab, L_NOCOPY);
567  *pnar = nar;
568  *pnag = nag;
569  *pnab = nab;
570 
571  /* Generate the color histograms */
572  datas = pixGetData(pixs);
573  wpls = pixGetWpl(pixs);
574  datam = pixGetData(pixm);
575  wplm = pixGetWpl(pixm);
576  if (cmap) {
577  for (i = 0; i < hm; i += factor) {
578  if (y + i < 0 || y + i >= h) continue;
579  lines = datas + (y + i) * wpls;
580  linem = datam + i * wplm;
581  for (j = 0; j < wm; j += factor) {
582  if (x + j < 0 || x + j >= w) continue;
583  if (GET_DATA_BIT(linem, j)) {
584  if (d == 8)
585  index = GET_DATA_BYTE(lines, x + j);
586  else if (d == 4)
587  index = GET_DATA_QBIT(lines, x + j);
588  else /* 2 bpp */
589  index = GET_DATA_DIBIT(lines, x + j);
590  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
591  rarray[rval] += 1.0;
592  garray[gval] += 1.0;
593  barray[bval] += 1.0;
594  }
595  }
596  }
597  } else { /* 32 bpp rgb */
598  for (i = 0; i < hm; i += factor) {
599  if (y + i < 0 || y + i >= h) continue;
600  lines = datas + (y + i) * wpls;
601  linem = datam + i * wplm;
602  for (j = 0; j < wm; j += factor) {
603  if (x + j < 0 || x + j >= w) continue;
604  if (GET_DATA_BIT(linem, j)) {
605  extractRGBValues(lines[x + j], &rval, &gval, &bval);
606  rarray[rval] += 1.0;
607  garray[gval] += 1.0;
608  barray[bval] += 1.0;
609  }
610  }
611  }
612  }
613 
614  return 0;
615 }
616 
617 
632 NUMA *
634  l_int32 factor)
635 {
636 l_int32 i, j, w, h, d, wpl, val, size;
637 l_uint32 *data, *line;
638 l_float32 *array;
639 NUMA *na;
640 
641  PROCNAME("pixGetCmapHistogram");
642 
643  if (!pixs)
644  return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
645  if (pixGetColormap(pixs) == NULL)
646  return (NUMA *)ERROR_PTR("pixs not cmapped", procName, NULL);
647  if (factor < 1)
648  return (NUMA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
649  pixGetDimensions(pixs, &w, &h, &d);
650  if (d != 2 && d != 4 && d != 8)
651  return (NUMA *)ERROR_PTR("d not 2, 4 or 8", procName, NULL);
652 
653  size = 1 << d;
654  if ((na = numaCreate(size)) == NULL)
655  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
656  numaSetCount(na, size); /* all initialized to 0.0 */
657  array = numaGetFArray(na, L_NOCOPY);
658 
659  wpl = pixGetWpl(pixs);
660  data = pixGetData(pixs);
661  for (i = 0; i < h; i += factor) {
662  line = data + i * wpl;
663  for (j = 0; j < w; j += factor) {
664  if (d == 8)
665  val = GET_DATA_BYTE(line, j);
666  else if (d == 4)
667  val = GET_DATA_QBIT(line, j);
668  else /* d == 2 */
669  val = GET_DATA_DIBIT(line, j);
670  array[val] += 1.0;
671  }
672  }
673 
674  return na;
675 }
676 
677 
697 NUMA *
699  PIX *pixm,
700  l_int32 x,
701  l_int32 y,
702  l_int32 factor)
703 {
704 l_int32 i, j, w, h, d, wm, hm, dm, wpls, wplm, val, size;
705 l_uint32 *datas, *datam, *lines, *linem;
706 l_float32 *array;
707 NUMA *na;
708 
709  PROCNAME("pixGetCmapHistogramMasked");
710 
711  if (!pixm)
712  return pixGetCmapHistogram(pixs, factor);
713 
714  if (!pixs)
715  return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
716  if (pixGetColormap(pixs) == NULL)
717  return (NUMA *)ERROR_PTR("pixs not cmapped", procName, NULL);
718  pixGetDimensions(pixm, &wm, &hm, &dm);
719  if (dm != 1)
720  return (NUMA *)ERROR_PTR("pixm not 1 bpp", procName, NULL);
721  if (factor < 1)
722  return (NUMA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
723  pixGetDimensions(pixs, &w, &h, &d);
724  if (d != 2 && d != 4 && d != 8)
725  return (NUMA *)ERROR_PTR("d not 2, 4 or 8", procName, NULL);
726 
727  size = 1 << d;
728  if ((na = numaCreate(size)) == NULL)
729  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
730  numaSetCount(na, size); /* all initialized to 0.0 */
731  array = numaGetFArray(na, L_NOCOPY);
732 
733  datas = pixGetData(pixs);
734  wpls = pixGetWpl(pixs);
735  datam = pixGetData(pixm);
736  wplm = pixGetWpl(pixm);
737 
738  for (i = 0; i < hm; i += factor) {
739  if (y + i < 0 || y + i >= h) continue;
740  lines = datas + (y + i) * wpls;
741  linem = datam + i * wplm;
742  for (j = 0; j < wm; j += factor) {
743  if (x + j < 0 || x + j >= w) continue;
744  if (GET_DATA_BIT(linem, j)) {
745  if (d == 8)
746  val = GET_DATA_BYTE(lines, x + j);
747  else if (d == 4)
748  val = GET_DATA_QBIT(lines, x + j);
749  else /* d == 2 */
750  val = GET_DATA_DIBIT(lines, x + j);
751  array[val] += 1.0;
752  }
753  }
754  }
755 
756  return na;
757 }
758 
759 
777 NUMA *
779  BOX *box,
780  l_int32 factor)
781 {
782 l_int32 i, j, bx, by, bw, bh, w, h, d, wpls, val, size;
783 l_uint32 *datas, *lines;
784 l_float32 *array;
785 NUMA *na;
786 
787  PROCNAME("pixGetCmapHistogramInRect");
788 
789  if (!box)
790  return pixGetCmapHistogram(pixs, factor);
791  if (!pixs)
792  return (NUMA *)ERROR_PTR("pixs not defined", procName, NULL);
793  if (pixGetColormap(pixs) == NULL)
794  return (NUMA *)ERROR_PTR("pixs not cmapped", procName, NULL);
795  if (factor < 1)
796  return (NUMA *)ERROR_PTR("sampling must be >= 1", procName, NULL);
797  pixGetDimensions(pixs, &w, &h, &d);
798  if (d != 2 && d != 4 && d != 8)
799  return (NUMA *)ERROR_PTR("d not 2, 4 or 8", procName, NULL);
800 
801  size = 1 << d;
802  if ((na = numaCreate(size)) == NULL)
803  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
804  numaSetCount(na, size); /* all initialized to 0.0 */
805  array = numaGetFArray(na, L_NOCOPY);
806 
807  datas = pixGetData(pixs);
808  wpls = pixGetWpl(pixs);
809  boxGetGeometry(box, &bx, &by, &bw, &bh);
810 
811  for (i = 0; i < bh; i += factor) {
812  if (by + i < 0 || by + i >= h) continue;
813  lines = datas + (by + i) * wpls;
814  for (j = 0; j < bw; j += factor) {
815  if (bx + j < 0 || bx + j >= w) continue;
816  if (d == 8)
817  val = GET_DATA_BYTE(lines, bx + j);
818  else if (d == 4)
819  val = GET_DATA_QBIT(lines, bx + j);
820  else /* d == 2 */
821  val = GET_DATA_DIBIT(lines, bx + j);
822  array[val] += 1.0;
823  }
824  }
825 
826  return na;
827 }
828 
829 
843 l_ok
845  l_int32 *pncolors)
846 {
847 L_DNA *da1, *da2;
848 
849  PROCNAME("pixCountRGBColorsByHash");
850 
851  if (!pncolors)
852  return ERROR_INT("&ncolors not defined", procName, 1);
853  *pncolors = 0;
854  if (!pixs || pixGetDepth(pixs) != 32)
855  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
856  da1 = pixConvertDataToDna(pixs);
857  l_dnaRemoveDupsByHmap(da1, &da2, NULL);
858  *pncolors = l_dnaGetCount(da2);
859  l_dnaDestroy(&da1);
860  l_dnaDestroy(&da2);
861  return 0;
862 }
863 
864 
879 l_ok
881  l_int32 factor,
882  l_int32 *pncolors)
883 {
884 L_AMAP *amap;
885 
886  PROCNAME("pixCountRGBColors");
887 
888  if (!pncolors)
889  return ERROR_INT("&ncolors not defined", procName, 1);
890  *pncolors = 0;
891  if (!pixs || pixGetDepth(pixs) != 32)
892  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
893  if (factor <= 0)
894  return ERROR_INT("factor must be > 0", procName, 1);
895  amap = pixGetColorAmapHistogram(pixs, factor);
896  *pncolors = l_amapSize(amap);
897  l_amapDestroy(&amap);
898  return 0;
899 }
900 
901 
915 L_AMAP *
917  l_int32 factor)
918 {
919 l_int32 i, j, w, h, wpl;
920 l_uint32 *data, *line;
921 L_AMAP *amap;
922 RB_TYPE key, value;
923 RB_TYPE *pval;
924 
925  PROCNAME("pixGetColorAmapHistogram");
926 
927  if (!pixs)
928  return (L_AMAP *)ERROR_PTR("pixs not defined", procName, NULL);
929  if (pixGetDepth(pixs) != 32)
930  return (L_AMAP *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
931  if (factor <= 0)
932  return (L_AMAP *)ERROR_PTR("factor must be > 0", procName, NULL);
933  pixGetDimensions(pixs, &w, &h, NULL);
934  data = pixGetData(pixs);
935  wpl = pixGetWpl(pixs);
936  amap = l_amapCreate(L_UINT_TYPE);
937  for (i = 0; i < h; i += factor) {
938  line = data + i * wpl;
939  for (j = 0; j < w; j += factor) {
940  key.utype = line[j];
941  pval = l_amapFind(amap, key);
942  if (!pval)
943  value.itype = 1;
944  else
945  value.itype = 1 + pval->itype;
946  l_amapInsert(amap, key, value);
947  }
948  }
949 
950  return amap;
951 }
952 
953 
966 l_int32
968  l_uint32 val)
969 {
970 RB_TYPE key;
971 RB_TYPE *pval;
972 
973  PROCNAME("amapGetCountForColor");
974 
975  if (!amap)
976  return ERROR_INT("amap not defined", procName, -1);
977 
978  key.utype = val;
979  pval = l_amapFind(amap, key);
980  return (pval) ? pval->itype : 0;
981 }
982 
983 
1005 l_ok
1007  l_int32 factor,
1008  l_float32 rank,
1009  l_uint32 *pvalue)
1010 {
1011 l_int32 d;
1012 l_float32 val, rval, gval, bval;
1013 PIX *pixt;
1014 PIXCMAP *cmap;
1015 
1016  PROCNAME("pixGetRankValue");
1017 
1018  if (!pvalue)
1019  return ERROR_INT("&value not defined", procName, 1);
1020  *pvalue = 0;
1021  if (!pixs)
1022  return ERROR_INT("pixs not defined", procName, 1);
1023  d = pixGetDepth(pixs);
1024  cmap = pixGetColormap(pixs);
1025  if (d != 8 && d != 32 && !cmap)
1026  return ERROR_INT("pixs not 8 or 32 bpp, or cmapped", procName, 1);
1027  if (cmap)
1029  else
1030  pixt = pixClone(pixs);
1031  d = pixGetDepth(pixt);
1032 
1033  if (d == 8) {
1034  pixGetRankValueMasked(pixt, NULL, 0, 0, factor, rank, &val, NULL);
1035  *pvalue = lept_roundftoi(val);
1036  } else {
1037  pixGetRankValueMaskedRGB(pixt, NULL, 0, 0, factor, rank,
1038  &rval, &gval, &bval);
1040  lept_roundftoi(bval), pvalue);
1041  }
1042 
1043  pixDestroy(&pixt);
1044  return 0;
1045 }
1046 
1047 
1075 l_ok
1077  PIX *pixm,
1078  l_int32 x,
1079  l_int32 y,
1080  l_int32 factor,
1081  l_float32 rank,
1082  l_float32 *prval,
1083  l_float32 *pgval,
1084  l_float32 *pbval)
1085 {
1086 l_float32 scale;
1087 PIX *pixmt, *pixt;
1088 
1089  PROCNAME("pixGetRankValueMaskedRGB");
1090 
1091  if (prval) *prval = 0.0;
1092  if (pgval) *pgval = 0.0;
1093  if (pbval) *pbval = 0.0;
1094  if (!prval && !pgval && !pbval)
1095  return ERROR_INT("no results requested", procName, 1);
1096  if (!pixs)
1097  return ERROR_INT("pixs not defined", procName, 1);
1098  if (pixGetDepth(pixs) != 32)
1099  return ERROR_INT("pixs not 32 bpp", procName, 1);
1100  if (pixm && pixGetDepth(pixm) != 1)
1101  return ERROR_INT("pixm not 1 bpp", procName, 1);
1102  if (factor < 1)
1103  return ERROR_INT("sampling factor must be >= 1", procName, 1);
1104  if (rank < 0.0 || rank > 1.0)
1105  return ERROR_INT("rank not in [0.0 ... 1.0]", procName, 1);
1106 
1107  pixmt = NULL;
1108  if (pixm) {
1109  scale = 1.0 / (l_float32)factor;
1110  pixmt = pixScale(pixm, scale, scale);
1111  }
1112  if (prval) {
1113  pixt = pixScaleRGBToGrayFast(pixs, factor, COLOR_RED);
1114  pixGetRankValueMasked(pixt, pixmt, x / factor, y / factor,
1115  factor, rank, prval, NULL);
1116  pixDestroy(&pixt);
1117  }
1118  if (pgval) {
1119  pixt = pixScaleRGBToGrayFast(pixs, factor, COLOR_GREEN);
1120  pixGetRankValueMasked(pixt, pixmt, x / factor, y / factor,
1121  factor, rank, pgval, NULL);
1122  pixDestroy(&pixt);
1123  }
1124  if (pbval) {
1125  pixt = pixScaleRGBToGrayFast(pixs, factor, COLOR_BLUE);
1126  pixGetRankValueMasked(pixt, pixmt, x / factor, y / factor,
1127  factor, rank, pbval, NULL);
1128  pixDestroy(&pixt);
1129  }
1130  pixDestroy(&pixmt);
1131  return 0;
1132 }
1133 
1134 
1167 l_ok
1169  PIX *pixm,
1170  l_int32 x,
1171  l_int32 y,
1172  l_int32 factor,
1173  l_float32 rank,
1174  l_float32 *pval,
1175  NUMA **pna)
1176 {
1177 NUMA *na;
1178 
1179  PROCNAME("pixGetRankValueMasked");
1180 
1181  if (pna) *pna = NULL;
1182  if (!pval)
1183  return ERROR_INT("&val not defined", procName, 1);
1184  *pval = 0.0;
1185  if (!pixs)
1186  return ERROR_INT("pixs not defined", procName, 1);
1187  if (pixGetDepth(pixs) != 8 && !pixGetColormap(pixs))
1188  return ERROR_INT("pixs neither 8 bpp nor colormapped", procName, 1);
1189  if (pixm && pixGetDepth(pixm) != 1)
1190  return ERROR_INT("pixm not 1 bpp", procName, 1);
1191  if (factor < 1)
1192  return ERROR_INT("sampling factor must be >= 1", procName, 1);
1193  if (rank < 0.0 || rank > 1.0)
1194  return ERROR_INT("rank not in [0.0 ... 1.0]", procName, 1);
1195 
1196  if ((na = pixGetGrayHistogramMasked(pixs, pixm, x, y, factor)) == NULL)
1197  return ERROR_INT("na not made", procName, 1);
1198  numaHistogramGetValFromRank(na, rank, pval);
1199  if (pna)
1200  *pna = na;
1201  else
1202  numaDestroy(&na);
1203 
1204  return 0;
1205 }
1206 
1207 
1238 l_ok
1240  PIX *pixm,
1241  l_int32 x,
1242  l_int32 y,
1243  l_int32 factor,
1244  l_uint32 *pval)
1245 {
1246 l_int32 i, j, w, h, d, wm, hm, wpl1, wplm, val, rval, gval, bval, count;
1247 l_uint32 *data1, *datam, *line1, *linem;
1248 l_float64 sum, rsum, gsum, bsum;
1249 PIX *pix1;
1250 
1251  PROCNAME("pixGetPixelAverage");
1252 
1253  if (!pval)
1254  return ERROR_INT("&val not defined", procName, 1);
1255  *pval = 0;
1256  if (!pixs)
1257  return ERROR_INT("pixs not defined", procName, 1);
1258  d = pixGetDepth(pixs);
1259  if (d != 32 && !pixGetColormap(pixs))
1260  return ERROR_INT("pixs not rgb or colormapped", procName, 1);
1261  if (pixm && pixGetDepth(pixm) != 1)
1262  return ERROR_INT("pixm not 1 bpp", procName, 1);
1263  if (factor < 1)
1264  return ERROR_INT("sampling factor must be >= 1", procName, 1);
1265 
1266  if (pixGetColormap(pixs))
1268  else
1269  pix1 = pixClone(pixs);
1270  pixGetDimensions(pix1, &w, &h, &d);
1271  if (d == 1) {
1272  pixDestroy(&pix1);
1273  return ERROR_INT("pix1 is just 1 bpp", procName, 1);
1274  }
1275  data1 = pixGetData(pix1);
1276  wpl1 = pixGetWpl(pix1);
1277 
1278  sum = rsum = gsum = bsum = 0.0;
1279  count = 0;
1280  if (!pixm) {
1281  for (i = 0; i < h; i += factor) {
1282  line1 = data1 + i * wpl1;
1283  for (j = 0; j < w; j += factor) {
1284  if (d == 8) {
1285  val = GET_DATA_BYTE(line1, j);
1286  sum += val;
1287  } else { /* rgb */
1288  extractRGBValues(*(line1 + j), &rval, &gval, &bval);
1289  rsum += rval;
1290  gsum += gval;
1291  bsum += bval;
1292  }
1293  count++;
1294  }
1295  }
1296  } else { /* masked */
1297  pixGetDimensions(pixm, &wm, &hm, NULL);
1298  datam = pixGetData(pixm);
1299  wplm = pixGetWpl(pixm);
1300  for (i = 0; i < hm; i += factor) {
1301  if (y + i < 0 || y + i >= h) continue;
1302  line1 = data1 + (y + i) * wpl1;
1303  linem = datam + i * wplm;
1304  for (j = 0; j < wm; j += factor) {
1305  if (x + j < 0 || x + j >= w) continue;
1306  if (GET_DATA_BIT(linem, j)) {
1307  if (d == 8) {
1308  val = GET_DATA_BYTE(line1, x + j);
1309  sum += val;
1310  } else { /* rgb */
1311  extractRGBValues(*(line1 + x + j), &rval, &gval, &bval);
1312  rsum += rval;
1313  gsum += gval;
1314  bsum += bval;
1315  }
1316  count++;
1317  }
1318  }
1319  }
1320  }
1321 
1322  pixDestroy(&pix1);
1323  if (count == 0)
1324  return ERROR_INT("no pixels sampled", procName, 1);
1325  if (d == 8) {
1326  *pval = (l_uint32)(sum / (l_float64)count);
1327  } else { /* d == 32 */
1328  rval = (l_uint32)(rsum / (l_float64)count);
1329  gval = (l_uint32)(gsum / (l_float64)count);
1330  bval = (l_uint32)(bsum / (l_float64)count);
1331  composeRGBPixel(rval, gval, bval, pval);
1332  }
1333 
1334  return 0;
1335 }
1336 
1337 
1356 l_ok
1358  l_int32 factor,
1359  l_int32 type,
1360  l_uint32 *pvalue)
1361 {
1362 l_int32 d;
1363 l_float32 val, rval, gval, bval;
1364 PIX *pixt;
1365 PIXCMAP *cmap;
1366 
1367  PROCNAME("pixGetPixelStats");
1368 
1369  if (!pvalue)
1370  return ERROR_INT("&value not defined", procName, 1);
1371  *pvalue = 0;
1372  if (!pixs)
1373  return ERROR_INT("pixs not defined", procName, 1);
1374  d = pixGetDepth(pixs);
1375  cmap = pixGetColormap(pixs);
1376  if (d != 8 && d != 32 && !cmap)
1377  return ERROR_INT("pixs not 8 or 32 bpp, or cmapped", procName, 1);
1378  if (cmap)
1380  else
1381  pixt = pixClone(pixs);
1382  d = pixGetDepth(pixt);
1383 
1384  if (d == 8) {
1385  pixGetAverageMasked(pixt, NULL, 0, 0, factor, type, &val);
1386  *pvalue = lept_roundftoi(val);
1387  } else {
1388  pixGetAverageMaskedRGB(pixt, NULL, 0, 0, factor, type,
1389  &rval, &gval, &bval);
1391  lept_roundftoi(bval), pvalue);
1392  }
1393 
1394  pixDestroy(&pixt);
1395  return 0;
1396 }
1397 
1398 
1423 l_ok
1425  PIX *pixm,
1426  l_int32 x,
1427  l_int32 y,
1428  l_int32 factor,
1429  l_int32 type,
1430  l_float32 *prval,
1431  l_float32 *pgval,
1432  l_float32 *pbval)
1433 {
1434 l_int32 empty;
1435 PIX *pixt;
1436 PIXCMAP *cmap;
1437 
1438  PROCNAME("pixGetAverageMaskedRGB");
1439 
1440  if (prval) *prval = 0.0;
1441  if (pgval) *pgval = 0.0;
1442  if (pbval) *pbval = 0.0;
1443  if (!prval && !pgval && !pbval)
1444  return ERROR_INT("no values requested", procName, 1);
1445  if (!pixs)
1446  return ERROR_INT("pixs not defined", procName, 1);
1447  cmap = pixGetColormap(pixs);
1448  if (pixGetDepth(pixs) != 32 && !cmap)
1449  return ERROR_INT("pixs neither 32 bpp nor colormapped", procName, 1);
1450  if (pixm && pixGetDepth(pixm) != 1)
1451  return ERROR_INT("pixm not 1 bpp", procName, 1);
1452  if (factor < 1)
1453  return ERROR_INT("sampling factor must be >= 1", procName, 1);
1454  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1455  type != L_STANDARD_DEVIATION && type != L_VARIANCE)
1456  return ERROR_INT("invalid measure type", procName, 1);
1457  if (pixm) {
1458  pixZero(pixm, &empty);
1459  if (empty)
1460  return ERROR_INT("empty mask", procName, 1);
1461  }
1462 
1463  if (prval) {
1464  if (cmap)
1465  pixt = pixGetRGBComponentCmap(pixs, COLOR_RED);
1466  else
1467  pixt = pixGetRGBComponent(pixs, COLOR_RED);
1468  pixGetAverageMasked(pixt, pixm, x, y, factor, type, prval);
1469  pixDestroy(&pixt);
1470  }
1471  if (pgval) {
1472  if (cmap)
1473  pixt = pixGetRGBComponentCmap(pixs, COLOR_GREEN);
1474  else
1475  pixt = pixGetRGBComponent(pixs, COLOR_GREEN);
1476  pixGetAverageMasked(pixt, pixm, x, y, factor, type, pgval);
1477  pixDestroy(&pixt);
1478  }
1479  if (pbval) {
1480  if (cmap)
1481  pixt = pixGetRGBComponentCmap(pixs, COLOR_BLUE);
1482  else
1483  pixt = pixGetRGBComponent(pixs, COLOR_BLUE);
1484  pixGetAverageMasked(pixt, pixm, x, y, factor, type, pbval);
1485  pixDestroy(&pixt);
1486  }
1487 
1488  return 0;
1489 }
1490 
1491 
1525 l_ok
1527  PIX *pixm,
1528  l_int32 x,
1529  l_int32 y,
1530  l_int32 factor,
1531  l_int32 type,
1532  l_float32 *pval)
1533 {
1534 l_int32 i, j, w, h, d, wm, hm, wplg, wplm, val, count, empty;
1535 l_uint32 *datag, *datam, *lineg, *linem;
1536 l_float64 sumave, summs, ave, meansq, var;
1537 PIX *pixg;
1538 
1539  PROCNAME("pixGetAverageMasked");
1540 
1541  if (!pval)
1542  return ERROR_INT("&val not defined", procName, 1);
1543  *pval = 0.0;
1544  if (!pixs)
1545  return ERROR_INT("pixs not defined", procName, 1);
1546  d = pixGetDepth(pixs);
1547  if (d != 8 && d != 16 && !pixGetColormap(pixs))
1548  return ERROR_INT("pixs not 8 or 16 bpp or colormapped", procName, 1);
1549  if (pixm && pixGetDepth(pixm) != 1)
1550  return ERROR_INT("pixm not 1 bpp", procName, 1);
1551  if (factor < 1)
1552  return ERROR_INT("sampling factor must be >= 1", procName, 1);
1553  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1554  type != L_STANDARD_DEVIATION && type != L_VARIANCE)
1555  return ERROR_INT("invalid measure type", procName, 1);
1556  if (pixm) {
1557  pixZero(pixm, &empty);
1558  if (empty)
1559  return ERROR_INT("empty mask", procName, 1);
1560  }
1561 
1562  if (pixGetColormap(pixs))
1564  else
1565  pixg = pixClone(pixs);
1566  pixGetDimensions(pixg, &w, &h, &d);
1567  datag = pixGetData(pixg);
1568  wplg = pixGetWpl(pixg);
1569 
1570  sumave = summs = 0.0;
1571  count = 0;
1572  if (!pixm) {
1573  for (i = 0; i < h; i += factor) {
1574  lineg = datag + i * wplg;
1575  for (j = 0; j < w; j += factor) {
1576  if (d == 8)
1577  val = GET_DATA_BYTE(lineg, j);
1578  else /* d == 16 */
1579  val = GET_DATA_TWO_BYTES(lineg, j);
1580  if (type != L_ROOT_MEAN_SQUARE)
1581  sumave += val;
1582  if (type != L_MEAN_ABSVAL)
1583  summs += (l_float64)(val) * val;
1584  count++;
1585  }
1586  }
1587  } else {
1588  pixGetDimensions(pixm, &wm, &hm, NULL);
1589  datam = pixGetData(pixm);
1590  wplm = pixGetWpl(pixm);
1591  for (i = 0; i < hm; i += factor) {
1592  if (y + i < 0 || y + i >= h) continue;
1593  lineg = datag + (y + i) * wplg;
1594  linem = datam + i * wplm;
1595  for (j = 0; j < wm; j += factor) {
1596  if (x + j < 0 || x + j >= w) continue;
1597  if (GET_DATA_BIT(linem, j)) {
1598  if (d == 8)
1599  val = GET_DATA_BYTE(lineg, x + j);
1600  else /* d == 16 */
1601  val = GET_DATA_TWO_BYTES(lineg, x + j);
1602  if (type != L_ROOT_MEAN_SQUARE)
1603  sumave += val;
1604  if (type != L_MEAN_ABSVAL)
1605  summs += (l_float64)(val) * val;
1606  count++;
1607  }
1608  }
1609  }
1610  }
1611 
1612  pixDestroy(&pixg);
1613  if (count == 0)
1614  return ERROR_INT("no pixels sampled", procName, 1);
1615  ave = sumave / (l_float64)count;
1616  meansq = summs / (l_float64)count;
1617  var = meansq - ave * ave;
1618  if (type == L_MEAN_ABSVAL)
1619  *pval = (l_float32)ave;
1620  else if (type == L_ROOT_MEAN_SQUARE)
1621  *pval = (l_float32)sqrt(meansq);
1622  else if (type == L_STANDARD_DEVIATION)
1623  *pval = (l_float32)sqrt(var);
1624  else /* type == L_VARIANCE */
1625  *pval = (l_float32)var;
1626 
1627  return 0;
1628 }
1629 
1630 
1649 l_ok
1651  l_int32 sx,
1652  l_int32 sy,
1653  l_int32 type,
1654  PIX **ppixr,
1655  PIX **ppixg,
1656  PIX **ppixb)
1657 {
1658 PIX *pixt;
1659 PIXCMAP *cmap;
1660 
1661  PROCNAME("pixGetAverageTiledRGB");
1662 
1663  if (ppixr) *ppixr = NULL;
1664  if (ppixg) *ppixg = NULL;
1665  if (ppixb) *ppixb = NULL;
1666  if (!ppixr && !ppixg && !ppixb)
1667  return ERROR_INT("no data requested", procName, 1);
1668  if (!pixs)
1669  return ERROR_INT("pixs not defined", procName, 1);
1670  cmap = pixGetColormap(pixs);
1671  if (pixGetDepth(pixs) != 32 && !cmap)
1672  return ERROR_INT("pixs neither 32 bpp nor colormapped", procName, 1);
1673  if (sx < 2 || sy < 2)
1674  return ERROR_INT("sx and sy not both > 1", procName, 1);
1675  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1676  type != L_STANDARD_DEVIATION)
1677  return ERROR_INT("invalid measure type", procName, 1);
1678 
1679  if (ppixr) {
1680  if (cmap)
1681  pixt = pixGetRGBComponentCmap(pixs, COLOR_RED);
1682  else
1683  pixt = pixGetRGBComponent(pixs, COLOR_RED);
1684  *ppixr = pixGetAverageTiled(pixt, sx, sy, type);
1685  pixDestroy(&pixt);
1686  }
1687  if (ppixg) {
1688  if (cmap)
1689  pixt = pixGetRGBComponentCmap(pixs, COLOR_GREEN);
1690  else
1691  pixt = pixGetRGBComponent(pixs, COLOR_GREEN);
1692  *ppixg = pixGetAverageTiled(pixt, sx, sy, type);
1693  pixDestroy(&pixt);
1694  }
1695  if (ppixb) {
1696  if (cmap)
1697  pixt = pixGetRGBComponentCmap(pixs, COLOR_BLUE);
1698  else
1699  pixt = pixGetRGBComponent(pixs, COLOR_BLUE);
1700  *ppixb = pixGetAverageTiled(pixt, sx, sy, type);
1701  pixDestroy(&pixt);
1702  }
1703 
1704  return 0;
1705 }
1706 
1707 
1726 PIX *
1728  l_int32 sx,
1729  l_int32 sy,
1730  l_int32 type)
1731 {
1732 l_int32 i, j, k, m, w, h, wd, hd, d, pos, wplt, wpld, valt;
1733 l_uint32 *datat, *datad, *linet, *lined, *startt;
1734 l_float64 sumave, summs, ave, meansq, normfact;
1735 PIX *pixt, *pixd;
1736 
1737  PROCNAME("pixGetAverageTiled");
1738 
1739  if (!pixs)
1740  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1741  pixGetDimensions(pixs, &w, &h, &d);
1742  if (d != 8 && !pixGetColormap(pixs))
1743  return (PIX *)ERROR_PTR("pixs not 8 bpp or cmapped", procName, NULL);
1744  if (sx < 2 || sy < 2)
1745  return (PIX *)ERROR_PTR("sx and sy not both > 1", procName, NULL);
1746  wd = w / sx;
1747  hd = h / sy;
1748  if (wd < 1 || hd < 1)
1749  return (PIX *)ERROR_PTR("wd or hd == 0", procName, NULL);
1750  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1751  type != L_STANDARD_DEVIATION)
1752  return (PIX *)ERROR_PTR("invalid measure type", procName, NULL);
1753 
1755  pixd = pixCreate(wd, hd, 8);
1756  datat = pixGetData(pixt);
1757  wplt = pixGetWpl(pixt);
1758  datad = pixGetData(pixd);
1759  wpld = pixGetWpl(pixd);
1760  normfact = 1. / (l_float64)(sx * sy);
1761  for (i = 0; i < hd; i++) {
1762  lined = datad + i * wpld;
1763  linet = datat + i * sy * wplt;
1764  for (j = 0; j < wd; j++) {
1765  if (type == L_MEAN_ABSVAL || type == L_STANDARD_DEVIATION) {
1766  sumave = 0.0;
1767  for (k = 0; k < sy; k++) {
1768  startt = linet + k * wplt;
1769  for (m = 0; m < sx; m++) {
1770  pos = j * sx + m;
1771  valt = GET_DATA_BYTE(startt, pos);
1772  sumave += valt;
1773  }
1774  }
1775  ave = normfact * sumave;
1776  }
1777  if (type == L_ROOT_MEAN_SQUARE || type == L_STANDARD_DEVIATION) {
1778  summs = 0.0;
1779  for (k = 0; k < sy; k++) {
1780  startt = linet + k * wplt;
1781  for (m = 0; m < sx; m++) {
1782  pos = j * sx + m;
1783  valt = GET_DATA_BYTE(startt, pos);
1784  summs += (l_float64)(valt) * valt;
1785  }
1786  }
1787  meansq = normfact * summs;
1788  }
1789  if (type == L_MEAN_ABSVAL)
1790  valt = (l_int32)(ave + 0.5);
1791  else if (type == L_ROOT_MEAN_SQUARE)
1792  valt = (l_int32)(sqrt(meansq) + 0.5);
1793  else /* type == L_STANDARD_DEVIATION */
1794  valt = (l_int32)(sqrt(meansq - ave * ave) + 0.5);
1795  SET_DATA_BYTE(lined, j, valt);
1796  }
1797  }
1798 
1799  pixDestroy(&pixt);
1800  return pixd;
1801 }
1802 
1803 
1829 l_int32
1831  BOX *box,
1832  NUMA **pnamean,
1833  NUMA **pnamedian,
1834  NUMA **pnamode,
1835  NUMA **pnamodecount,
1836  NUMA **pnavar,
1837  NUMA **pnarootvar)
1838 {
1839 l_int32 i, j, k, w, h, val, wpls, sum, sumsq, target, max, modeval;
1840 l_int32 xstart, xend, ystart, yend, bw, bh;
1841 l_int32 *histo;
1842 l_uint32 *lines, *datas;
1843 l_float32 norm;
1844 l_float32 *famean, *fameansq, *favar, *farootvar;
1845 l_float32 *famedian, *famode, *famodecount;
1846 
1847  PROCNAME("pixRowStats");
1848 
1849  if (pnamean) *pnamean = NULL;
1850  if (pnamedian) *pnamedian = NULL;
1851  if (pnamode) *pnamode = NULL;
1852  if (pnamodecount) *pnamodecount = NULL;
1853  if (pnavar) *pnavar = NULL;
1854  if (pnarootvar) *pnarootvar = NULL;
1855  if (!pixs || pixGetDepth(pixs) != 8)
1856  return ERROR_INT("pixs undefined or not 8 bpp", procName, 1);
1857  famean = fameansq = favar = farootvar = NULL;
1858  famedian = famode = famodecount = NULL;
1859 
1860  pixGetDimensions(pixs, &w, &h, NULL);
1861  if (boxClipToRectangleParams(box, w, h, &xstart, &ystart, &xend, &yend,
1862  &bw, &bh) == 1)
1863  return ERROR_INT("invalid clipping box", procName, 1);
1864 
1865  /* We need the mean for variance and root variance */
1866  datas = pixGetData(pixs);
1867  wpls = pixGetWpl(pixs);
1868  if (pnamean || pnavar || pnarootvar) {
1869  norm = 1. / (l_float32)bw;
1870  famean = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1871  fameansq = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1872  if (pnavar || pnarootvar) {
1873  favar = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1874  if (pnarootvar)
1875  farootvar = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1876  }
1877  for (i = ystart; i < yend; i++) {
1878  sum = sumsq = 0;
1879  lines = datas + i * wpls;
1880  for (j = xstart; j < xend; j++) {
1881  val = GET_DATA_BYTE(lines, j);
1882  sum += val;
1883  sumsq += val * val;
1884  }
1885  famean[i] = norm * sum;
1886  fameansq[i] = norm * sumsq;
1887  if (pnavar || pnarootvar) {
1888  favar[i] = fameansq[i] - famean[i] * famean[i];
1889  if (pnarootvar)
1890  farootvar[i] = sqrtf(favar[i]);
1891  }
1892  }
1893  LEPT_FREE(fameansq);
1894  if (pnamean)
1895  *pnamean = numaCreateFromFArray(famean, bh, L_INSERT);
1896  else
1897  LEPT_FREE(famean);
1898  if (pnavar)
1899  *pnavar = numaCreateFromFArray(favar, bh, L_INSERT);
1900  else
1901  LEPT_FREE(favar);
1902  if (pnarootvar)
1903  *pnarootvar = numaCreateFromFArray(farootvar, bh, L_INSERT);
1904  }
1905 
1906  /* We need a histogram to find the median and/or mode values */
1907  if (pnamedian || pnamode || pnamodecount) {
1908  histo = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
1909  if (pnamedian) {
1910  *pnamedian = numaMakeConstant(0, bh);
1911  famedian = numaGetFArray(*pnamedian, L_NOCOPY);
1912  }
1913  if (pnamode) {
1914  *pnamode = numaMakeConstant(0, bh);
1915  famode = numaGetFArray(*pnamode, L_NOCOPY);
1916  }
1917  if (pnamodecount) {
1918  *pnamodecount = numaMakeConstant(0, bh);
1919  famodecount = numaGetFArray(*pnamodecount, L_NOCOPY);
1920  }
1921  for (i = ystart; i < yend; i++) {
1922  lines = datas + i * wpls;
1923  memset(histo, 0, 1024);
1924  for (j = xstart; j < xend; j++) {
1925  val = GET_DATA_BYTE(lines, j);
1926  histo[val]++;
1927  }
1928 
1929  if (pnamedian) {
1930  sum = 0;
1931  target = (bw + 1) / 2;
1932  for (k = 0; k < 256; k++) {
1933  sum += histo[k];
1934  if (sum >= target) {
1935  famedian[i] = k;
1936  break;
1937  }
1938  }
1939  }
1940 
1941  if (pnamode || pnamodecount) {
1942  max = 0;
1943  modeval = 0;
1944  for (k = 0; k < 256; k++) {
1945  if (histo[k] > max) {
1946  max = histo[k];
1947  modeval = k;
1948  }
1949  }
1950  if (pnamode)
1951  famode[i] = modeval;
1952  if (pnamodecount)
1953  famodecount[i] = max;
1954  }
1955  }
1956  LEPT_FREE(histo);
1957  }
1958 
1959  return 0;
1960 }
1961 
1962 
1989 l_int32
1991  BOX *box,
1992  NUMA **pnamean,
1993  NUMA **pnamedian,
1994  NUMA **pnamode,
1995  NUMA **pnamodecount,
1996  NUMA **pnavar,
1997  NUMA **pnarootvar)
1998 {
1999 l_int32 i, j, k, w, h, val, wpls, sum, sumsq, target, max, modeval;
2000 l_int32 xstart, xend, ystart, yend, bw, bh;
2001 l_int32 *histo;
2002 l_uint32 *lines, *datas;
2003 l_float32 norm;
2004 l_float32 *famean, *fameansq, *favar, *farootvar;
2005 l_float32 *famedian, *famode, *famodecount;
2006 
2007  PROCNAME("pixColumnStats");
2008 
2009  if (pnamean) *pnamean = NULL;
2010  if (pnamedian) *pnamedian = NULL;
2011  if (pnamode) *pnamode = NULL;
2012  if (pnamodecount) *pnamodecount = NULL;
2013  if (pnavar) *pnavar = NULL;
2014  if (pnarootvar) *pnarootvar = NULL;
2015  if (!pixs || pixGetDepth(pixs) != 8)
2016  return ERROR_INT("pixs undefined or not 8 bpp", procName, 1);
2017  famean = fameansq = favar = farootvar = NULL;
2018  famedian = famode = famodecount = NULL;
2019 
2020  pixGetDimensions(pixs, &w, &h, NULL);
2021  if (boxClipToRectangleParams(box, w, h, &xstart, &ystart, &xend, &yend,
2022  &bw, &bh) == 1)
2023  return ERROR_INT("invalid clipping box", procName, 1);
2024 
2025  /* We need the mean for variance and root variance */
2026  datas = pixGetData(pixs);
2027  wpls = pixGetWpl(pixs);
2028  if (pnamean || pnavar || pnarootvar) {
2029  norm = 1. / (l_float32)bh;
2030  famean = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
2031  fameansq = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
2032  if (pnavar || pnarootvar) {
2033  favar = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
2034  if (pnarootvar)
2035  farootvar = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
2036  }
2037  for (j = xstart; j < xend; j++) {
2038  sum = sumsq = 0;
2039  for (i = ystart, lines = datas; i < yend; lines += wpls, i++) {
2040  val = GET_DATA_BYTE(lines, j);
2041  sum += val;
2042  sumsq += val * val;
2043  }
2044  famean[j] = norm * sum;
2045  fameansq[j] = norm * sumsq;
2046  if (pnavar || pnarootvar) {
2047  favar[j] = fameansq[j] - famean[j] * famean[j];
2048  if (pnarootvar)
2049  farootvar[j] = sqrtf(favar[j]);
2050  }
2051  }
2052  LEPT_FREE(fameansq);
2053  if (pnamean)
2054  *pnamean = numaCreateFromFArray(famean, bw, L_INSERT);
2055  else
2056  LEPT_FREE(famean);
2057  if (pnavar)
2058  *pnavar = numaCreateFromFArray(favar, bw, L_INSERT);
2059  else
2060  LEPT_FREE(favar);
2061  if (pnarootvar)
2062  *pnarootvar = numaCreateFromFArray(farootvar, bw, L_INSERT);
2063  }
2064 
2065  /* We need a histogram to find the median and/or mode values */
2066  if (pnamedian || pnamode || pnamodecount) {
2067  histo = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
2068  if (pnamedian) {
2069  *pnamedian = numaMakeConstant(0, bw);
2070  famedian = numaGetFArray(*pnamedian, L_NOCOPY);
2071  }
2072  if (pnamode) {
2073  *pnamode = numaMakeConstant(0, bw);
2074  famode = numaGetFArray(*pnamode, L_NOCOPY);
2075  }
2076  if (pnamodecount) {
2077  *pnamodecount = numaMakeConstant(0, bw);
2078  famodecount = numaGetFArray(*pnamodecount, L_NOCOPY);
2079  }
2080  for (j = xstart; j < xend; j++) {
2081  memset(histo, 0, 1024);
2082  for (i = ystart, lines = datas; i < yend; lines += wpls, i++) {
2083  val = GET_DATA_BYTE(lines, j);
2084  histo[val]++;
2085  }
2086 
2087  if (pnamedian) {
2088  sum = 0;
2089  target = (bh + 1) / 2;
2090  for (k = 0; k < 256; k++) {
2091  sum += histo[k];
2092  if (sum >= target) {
2093  famedian[j] = k;
2094  break;
2095  }
2096  }
2097  }
2098 
2099  if (pnamode || pnamodecount) {
2100  max = 0;
2101  modeval = 0;
2102  for (k = 0; k < 256; k++) {
2103  if (histo[k] > max) {
2104  max = histo[k];
2105  modeval = k;
2106  }
2107  }
2108  if (pnamode)
2109  famode[j] = modeval;
2110  if (pnamodecount)
2111  famodecount[j] = max;
2112  }
2113  }
2114  LEPT_FREE(histo);
2115  }
2116 
2117  return 0;
2118 }
2119 
2120 
2136 l_ok
2138  l_int32 factor,
2139  l_int32 color,
2140  l_int32 *pminval,
2141  l_int32 *pmaxval)
2142 {
2143 l_int32 d;
2144 PIXCMAP *cmap;
2145 
2146  PROCNAME("pixGetRangeValues");
2147 
2148  if (pminval) *pminval = 0;
2149  if (pmaxval) *pmaxval = 0;
2150  if (!pminval && !pmaxval)
2151  return ERROR_INT("no result requested", procName, 1);
2152  if (!pixs)
2153  return ERROR_INT("pixs not defined", procName, 1);
2154 
2155  cmap = pixGetColormap(pixs);
2156  if (cmap)
2157  return pixcmapGetRangeValues(cmap, color, pminval, pmaxval,
2158  NULL, NULL);
2159 
2160  if (factor < 1)
2161  return ERROR_INT("sampling factor must be >= 1", procName, 1);
2162  d = pixGetDepth(pixs);
2163  if (d != 8 && d != 32)
2164  return ERROR_INT("pixs not 8 or 32 bpp", procName, 1);
2165 
2166  if (d == 8) {
2167  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2168  NULL, NULL, NULL, pminval);
2169  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2170  NULL, NULL, NULL, pmaxval);
2171  } else if (color == L_SELECT_RED) {
2172  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2173  pminval, NULL, NULL, NULL);
2174  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2175  pmaxval, NULL, NULL, NULL);
2176  } else if (color == L_SELECT_GREEN) {
2177  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2178  NULL, pminval, NULL, NULL);
2179  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2180  NULL, pmaxval, NULL, NULL);
2181  } else if (color == L_SELECT_BLUE) {
2182  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2183  NULL, NULL, pminval, NULL);
2184  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2185  NULL, NULL, pmaxval, NULL);
2186  } else {
2187  return ERROR_INT("invalid color", procName, 1);
2188  }
2189 
2190  return 0;
2191 }
2192 
2193 
2214 l_ok
2216  l_int32 factor,
2217  l_int32 type,
2218  l_int32 *prval,
2219  l_int32 *pgval,
2220  l_int32 *pbval,
2221  l_int32 *pgrayval)
2222 {
2223 l_int32 i, j, w, h, d, wpl;
2224 l_int32 val, extval, rval, gval, bval, extrval, extgval, extbval;
2225 l_uint32 pixel;
2226 l_uint32 *data, *line;
2227 PIXCMAP *cmap;
2228 
2229  PROCNAME("pixGetExtremeValue");
2230 
2231  if (prval) *prval = -1;
2232  if (pgval) *pgval = -1;
2233  if (pbval) *pbval = -1;
2234  if (pgrayval) *pgrayval = -1;
2235  if (!pixs)
2236  return ERROR_INT("pixs not defined", procName, 1);
2237  if (type != L_SELECT_MIN && type != L_SELECT_MAX)
2238  return ERROR_INT("invalid type", procName, 1);
2239 
2240  cmap = pixGetColormap(pixs);
2241  if (cmap) {
2242  if (type == L_SELECT_MIN) {
2243  if (prval) pixcmapGetRangeValues(cmap, L_SELECT_RED, prval, NULL,
2244  NULL, NULL);
2245  if (pgval) pixcmapGetRangeValues(cmap, L_SELECT_GREEN, pgval, NULL,
2246  NULL, NULL);
2247  if (pbval) pixcmapGetRangeValues(cmap, L_SELECT_BLUE, pbval, NULL,
2248  NULL, NULL);
2249  } else { /* type == L_SELECT_MAX */
2250  if (prval) pixcmapGetRangeValues(cmap, L_SELECT_RED, NULL, prval,
2251  NULL, NULL);
2252  if (pgval) pixcmapGetRangeValues(cmap, L_SELECT_GREEN, NULL, pgval,
2253  NULL, NULL);
2254  if (pbval) pixcmapGetRangeValues(cmap, L_SELECT_BLUE, NULL, pbval,
2255  NULL, NULL);
2256  }
2257  return 0;
2258  }
2259 
2260  pixGetDimensions(pixs, &w, &h, &d);
2261  if (factor < 1)
2262  return ERROR_INT("sampling factor must be >= 1", procName, 1);
2263  if (d != 8 && d != 32)
2264  return ERROR_INT("pixs not 8 or 32 bpp", procName, 1);
2265  if (d == 8 && !pgrayval)
2266  return ERROR_INT("can't return result in grayval", procName, 1);
2267  if (d == 32 && !prval && !pgval && !pbval)
2268  return ERROR_INT("can't return result in r/g/b-val", procName, 1);
2269 
2270  data = pixGetData(pixs);
2271  wpl = pixGetWpl(pixs);
2272  if (d == 8) {
2273  if (type == L_SELECT_MIN)
2274  extval = 100000;
2275  else /* get max */
2276  extval = -1;
2277 
2278  for (i = 0; i < h; i += factor) {
2279  line = data + i * wpl;
2280  for (j = 0; j < w; j += factor) {
2281  val = GET_DATA_BYTE(line, j);
2282  if ((type == L_SELECT_MIN && val < extval) ||
2283  (type == L_SELECT_MAX && val > extval))
2284  extval = val;
2285  }
2286  }
2287  *pgrayval = extval;
2288  return 0;
2289  }
2290 
2291  /* 32 bpp rgb */
2292  if (type == L_SELECT_MIN) {
2293  extrval = 100000;
2294  extgval = 100000;
2295  extbval = 100000;
2296  } else {
2297  extrval = -1;
2298  extgval = -1;
2299  extbval = -1;
2300  }
2301  for (i = 0; i < h; i += factor) {
2302  line = data + i * wpl;
2303  for (j = 0; j < w; j += factor) {
2304  pixel = line[j];
2305  if (prval) {
2306  rval = (pixel >> L_RED_SHIFT) & 0xff;
2307  if ((type == L_SELECT_MIN && rval < extrval) ||
2308  (type == L_SELECT_MAX && rval > extrval))
2309  extrval = rval;
2310  }
2311  if (pgval) {
2312  gval = (pixel >> L_GREEN_SHIFT) & 0xff;
2313  if ((type == L_SELECT_MIN && gval < extgval) ||
2314  (type == L_SELECT_MAX && gval > extgval))
2315  extgval = gval;
2316  }
2317  if (pbval) {
2318  bval = (pixel >> L_BLUE_SHIFT) & 0xff;
2319  if ((type == L_SELECT_MIN && bval < extbval) ||
2320  (type == L_SELECT_MAX && bval > extbval))
2321  extbval = bval;
2322  }
2323  }
2324  }
2325  if (prval) *prval = extrval;
2326  if (pgval) *pgval = extgval;
2327  if (pbval) *pbval = extbval;
2328  return 0;
2329 }
2330 
2331 
2351 l_ok
2353  BOX *box,
2354  l_uint32 *pmaxval,
2355  l_int32 *pxmax,
2356  l_int32 *pymax)
2357 {
2358 l_int32 i, j, w, h, d, wpl, bw, bh;
2359 l_int32 xstart, ystart, xend, yend, xmax, ymax;
2360 l_uint32 val, maxval;
2361 l_uint32 *data, *line;
2362 
2363  PROCNAME("pixGetMaxValueInRect");
2364 
2365  if (pmaxval) *pmaxval = 0;
2366  if (pxmax) *pxmax = 0;
2367  if (pymax) *pymax = 0;
2368  if (!pmaxval && !pxmax && !pymax)
2369  return ERROR_INT("no data requested", procName, 1);
2370  if (!pixs)
2371  return ERROR_INT("pixs not defined", procName, 1);
2372  if (pixGetColormap(pixs) != NULL)
2373  return ERROR_INT("pixs has colormap", procName, 1);
2374  pixGetDimensions(pixs, &w, &h, &d);
2375  if (d != 8 && d != 16 && d != 32)
2376  return ERROR_INT("pixs not 8, 16 or 32 bpp", procName, 1);
2377 
2378  xstart = ystart = 0;
2379  xend = w - 1;
2380  yend = h - 1;
2381  if (box) {
2382  boxGetGeometry(box, &xstart, &ystart, &bw, &bh);
2383  xend = xstart + bw - 1;
2384  yend = ystart + bh - 1;
2385  }
2386 
2387  data = pixGetData(pixs);
2388  wpl = pixGetWpl(pixs);
2389  maxval = 0;
2390  xmax = ymax = 0;
2391  for (i = ystart; i <= yend; i++) {
2392  line = data + i * wpl;
2393  for (j = xstart; j <= xend; j++) {
2394  if (d == 8)
2395  val = GET_DATA_BYTE(line, j);
2396  else if (d == 16)
2397  val = GET_DATA_TWO_BYTES(line, j);
2398  else /* d == 32 */
2399  val = line[j];
2400  if (val > maxval) {
2401  maxval = val;
2402  xmax = j;
2403  ymax = i;
2404  }
2405  }
2406  }
2407  if (maxval == 0) { /* no counts; pick the center of the rectangle */
2408  xmax = (xstart + xend) / 2;
2409  ymax = (ystart + yend) / 2;
2410  }
2411 
2412  if (pmaxval) *pmaxval = maxval;
2413  if (pxmax) *pxmax = xmax;
2414  if (pymax) *pymax = ymax;
2415  return 0;
2416 }
2417 
2418 
2426 l_ok
2428  l_int32 *pmaxindex)
2429 {
2430 l_int32 i, j, w, h, d, wpl, val, max, maxval, empty;
2431 l_uint32 *data, *line;
2432 
2433  PROCNAME("pixGetMaxColorIndex");
2434 
2435  if (!pmaxindex)
2436  return ERROR_INT("&maxindex not defined", procName, 1);
2437  *pmaxindex = 0;
2438  if (!pixs)
2439  return ERROR_INT("pixs not defined", procName, 1);
2440  pixGetDimensions(pixs, &w, &h, &d);
2441  if (d != 1 && d != 2 && d != 4 && d != 8)
2442  return ERROR_INT("invalid pixs depth; not in (1,2,4,8}", procName, 1);
2443 
2444  wpl = pixGetWpl(pixs);
2445  data = pixGetData(pixs);
2446  max = 0;
2447  maxval = (1 << d) - 1;
2448  if (d == 1) {
2449  pixZero(pixs, &empty);
2450  if (!empty) max = 1;
2451  *pmaxindex = max;
2452  return 0;
2453  }
2454  for (i = 0; i < h; i++) {
2455  line = data + i * wpl;
2456  if (d == 2) {
2457  for (j = 0; j < w; j++) {
2458  val = GET_DATA_DIBIT(line, j);
2459  if (val > max) max = val;
2460  }
2461  } else if (d == 4) {
2462  for (j = 0; j < w; j++) {
2463  val = GET_DATA_QBIT(line, j);
2464  if (val > max) max = val;
2465  }
2466  } else if (d == 8) {
2467  for (j = 0; j < w; j++) {
2468  val = GET_DATA_BYTE(line, j);
2469  if (val > max) max = val;
2470  }
2471  }
2472  if (max == maxval) break;
2473  }
2474  *pmaxindex = max;
2475  return 0;
2476 }
2477 
2478 
2500 l_ok
2502  l_int32 nbins,
2503  l_int32 factor,
2504  l_int32 color,
2505  l_int32 *pminval,
2506  l_int32 *pmaxval,
2507  l_uint32 **pcarray,
2508  l_int32 fontsize)
2509 {
2510 l_int32 i, minval, maxval, rval, gval, bval;
2511 l_uint32 *carray;
2512 PIX *pixt;
2513 
2514  PROCNAME("pixGetBinnedComponentRange");
2515 
2516  if (pminval) *pminval = 0;
2517  if (pmaxval) *pmaxval = 0;
2518  if (pcarray) *pcarray = NULL;
2519  if (!pminval && !pmaxval)
2520  return ERROR_INT("no result requested", procName, 1);
2521  if (!pixs || pixGetDepth(pixs) != 32)
2522  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
2523  if (factor < 1)
2524  return ERROR_INT("sampling factor must be >= 1", procName, 1);
2525  if (color != L_SELECT_RED && color != L_SELECT_GREEN &&
2526  color != L_SELECT_BLUE)
2527  return ERROR_INT("invalid color", procName, 1);
2528  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2529  return ERROR_INT("invalid fontsize", procName, 1);
2530 
2531  pixGetRankColorArray(pixs, nbins, color, factor, &carray, NULL, 0);
2532  if (!carray)
2533  return ERROR_INT("carray not made", procName, 1);
2534 
2535  if (fontsize > 0) {
2536  for (i = 0; i < nbins; i++)
2537  L_INFO("c[%d] = %x\n", procName, i, carray[i]);
2538  pixt = pixDisplayColorArray(carray, nbins, 200, 5, fontsize);
2539  pixDisplay(pixt, 100, 100);
2540  pixDestroy(&pixt);
2541  }
2542 
2543  extractRGBValues(carray[0], &rval, &gval, &bval);
2544  minval = rval;
2545  if (color == L_SELECT_GREEN)
2546  minval = gval;
2547  else if (color == L_SELECT_BLUE)
2548  minval = bval;
2549  extractRGBValues(carray[nbins - 1], &rval, &gval, &bval);
2550  maxval = rval;
2551  if (color == L_SELECT_GREEN)
2552  maxval = gval;
2553  else if (color == L_SELECT_BLUE)
2554  maxval = bval;
2555 
2556  if (pminval) *pminval = minval;
2557  if (pmaxval) *pmaxval = maxval;
2558  if (pcarray)
2559  *pcarray = carray;
2560  else
2561  LEPT_FREE(carray);
2562  return 0;
2563 }
2564 
2565 
2599 l_ok
2601  l_int32 nbins,
2602  l_int32 type,
2603  l_int32 factor,
2604  l_uint32 **pcarray,
2605  PIXA *pixadb,
2606  l_int32 fontsize)
2607 {
2608 l_int32 ret, w, h, samplesperbin;
2609 l_uint32 *array;
2610 PIX *pix1, *pixc, *pixg, *pixd;
2611 PIXCMAP *cmap;
2612 
2613  PROCNAME("pixGetRankColorArray");
2614 
2615  if (!pcarray)
2616  return ERROR_INT("&carray not defined", procName, 1);
2617  *pcarray = NULL;
2618  if (factor < 1)
2619  return ERROR_INT("sampling factor must be >= 1", procName, 1);
2620  if (nbins < 2)
2621  return ERROR_INT("nbins must be at least 2", procName, 1);
2622  if (!pixs)
2623  return ERROR_INT("pixs not defined", procName, 1);
2624  cmap = pixGetColormap(pixs);
2625  if (pixGetDepth(pixs) != 32 && !cmap)
2626  return ERROR_INT("pixs neither 32 bpp nor cmapped", procName, 1);
2627  if (type != L_SELECT_RED && type != L_SELECT_GREEN &&
2628  type != L_SELECT_BLUE && type != L_SELECT_MIN &&
2629  type != L_SELECT_MAX && type != L_SELECT_AVERAGE &&
2630  type != L_SELECT_HUE && type != L_SELECT_SATURATION)
2631  return ERROR_INT("invalid type", procName, 1);
2632  if (pixadb) {
2633  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2) {
2634  L_WARNING("invalid fontsize %d; setting to 6\n", procName,
2635  fontsize);
2636  fontsize = 6;
2637  }
2638  }
2639  pixGetDimensions(pixs, &w, &h, NULL);
2640  samplesperbin = (w * h) / (factor * factor * nbins);
2641  if (samplesperbin < 10) {
2642  L_ERROR("samplesperbin = %d < 10\n", procName, samplesperbin);
2643  return 1;
2644  }
2645 
2646  /* Downscale by factor and remove colormap if it exists */
2647  pix1 = pixScaleByIntSampling(pixs, factor);
2648  if (cmap)
2650  else
2651  pixc = pixClone(pix1);
2652  pixDestroy(&pix1);
2653 
2654  /* Convert to an 8 bit version for ordering the pixels */
2655  pixg = pixConvertRGBToGrayGeneral(pixc, type, 0.0, 0.0, 0.0);
2656 
2657  /* Get the average color in each bin for pixels whose grayscale
2658  * values are in the range for that bin. */
2659  pixGetBinnedColor(pixc, pixg, 1, nbins, pcarray, pixadb);
2660  ret = 0;
2661  if ((array = *pcarray) == NULL) {
2662  L_ERROR("color array not returned\n", procName);
2663  ret = 1;
2664  }
2665  if (array && pixadb) {
2666  pixd = pixDisplayColorArray(array, nbins, 200, 5, fontsize);
2667  pixWriteDebug("/tmp/lept/regout/rankhisto.png", pixd, IFF_PNG);
2668  pixDestroy(&pixd);
2669  }
2670 
2671  pixDestroy(&pixc);
2672  pixDestroy(&pixg);
2673  return ret;
2674 }
2675 
2676 
2704 l_ok
2706  PIX *pixg,
2707  l_int32 factor,
2708  l_int32 nbins,
2709  l_uint32 **pcarray,
2710  PIXA *pixadb)
2711 {
2712 l_int32 i, j, k, w, h, wpls, wplg;
2713 l_int32 count, bincount, binindex, binsize, npts, avepts, ntot;
2714 l_int32 rval, gval, bval, grayval, rave, gave, bave;
2715 l_uint32 *datas, *datag, *lines, *lineg, *carray;
2716 l_float64 val64, rsum, gsum, bsum;
2717 L_DNAA *daa;
2718 NUMA *naeach;
2719 PIX *pix1;
2720 
2721  PROCNAME("pixGetBinnedColor");
2722 
2723  if (!pcarray)
2724  return ERROR_INT("&carray not defined", procName, 1);
2725  *pcarray = NULL;
2726  if (!pixs || pixGetDepth(pixs) != 32)
2727  return ERROR_INT("pixs undefined or not 32 bpp", procName, 1);
2728  if (!pixg || pixGetDepth(pixg) != 8)
2729  return ERROR_INT("pixg undefined or not 8 bpp", procName, 1);
2730  if (factor < 1) {
2731  L_WARNING("sampling factor less than 1; setting to 1\n", procName);
2732  factor = 1;
2733  }
2734  if (nbins < 1 || nbins > 100)
2735  return ERROR_INT("nbins not in [1,100]", procName, 1);
2736 
2737  /* Require that each bin has at least 5 pixels. */
2738  pixGetDimensions(pixs, &w, &h, NULL);
2739  npts = (w + factor - 1) * (h + factor - 1) / (factor * factor);
2740  avepts = (npts + nbins - 1) / nbins; /* average number of pts in a bin */
2741  if (avepts < 5) {
2742  L_ERROR("avepts = %d; must be >= 5\n", procName, avepts);
2743  return 1;
2744  }
2745 
2746  /* ------------------------------------------------------------ *
2747  * Find the average color for each bin. The colors are ordered *
2748  * by the gray value in the corresponding pixel in %pixg. *
2749  * The bins have equal numbers of pixels (within 1). *
2750  * ------------------------------------------------------------ */
2751 
2752  /* Generate a dnaa, where each dna has the colors corresponding
2753  * to the grayscale value given by the index of the dna in the dnaa */
2754  datas = pixGetData(pixs);
2755  wpls = pixGetWpl(pixs);
2756  datag = pixGetData(pixg);
2757  wplg = pixGetWpl(pixg);
2758  daa = l_dnaaCreateFull(256, 0);
2759  for (i = 0; i < h; i += factor) {
2760  lines = datas + i * wpls;
2761  lineg = datag + i * wplg;
2762  for (j = 0; j < w; j += factor) {
2763  grayval = GET_DATA_BYTE(lineg, j);
2764  l_dnaaAddNumber(daa, grayval, lines[j]);
2765  }
2766  }
2767 
2768  if (pixadb) {
2769  NUMA *na, *nabinval, *narank;
2770  na = numaCreate(256); /* grayscale histogram */
2771  for (i = 0; i < 256; i++)
2772  numaAddNumber(na, l_dnaaGetDnaCount(daa, i));
2773 
2774  /* Plot the gray bin value and the rank(gray) values */
2775  numaDiscretizeHistoInBins(na, nbins, &nabinval, &narank);
2776  pix1 = gplotSimplePix1(nabinval, "Gray value in each bin");
2777  pixaAddPix(pixadb, pix1, L_INSERT);
2778  pix1 = gplotSimplePix1(narank, "rank as function of gray value");
2779  pixaAddPix(pixadb, pix1, L_INSERT);
2780  numaDestroy(&na);
2781  numaDestroy(&nabinval);
2782  numaDestroy(&narank);
2783  }
2784 
2785  /* Get the number of items in each bin */
2786  ntot = l_dnaaGetNumberCount(daa);
2787  if ((naeach = numaGetUniformBinSizes(ntot, nbins)) == NULL) {
2788  l_dnaaDestroy(&daa);
2789  return ERROR_INT("naeach not made", procName, 1);
2790  }
2791 
2792  /* Get the average color in each bin. This algorithm is
2793  * esssentially the same as in numaDiscretizeHistoInBins() */
2794  carray = (l_uint32 *)LEPT_CALLOC(nbins, sizeof(l_uint32));
2795  rsum = gsum = bsum = 0.0;
2796  bincount = 0;
2797  binindex = 0;
2798  numaGetIValue(naeach, 0, &binsize);
2799  k = 0; /* count up to ntot */
2800  for (i = 0; i < 256; i++) {
2801  count = l_dnaaGetDnaCount(daa, i);
2802  for (j = 0; j < count; j++) {
2803  k++;
2804  bincount++;
2805  l_dnaaGetValue(daa, i, j, &val64);
2806  extractRGBValues((l_uint32)val64, &rval, &gval, &bval);
2807  rsum += rval;
2808  gsum += gval;
2809  bsum += bval;
2810  if (bincount == binsize) { /* add bin entry */
2811  rave = (l_int32)(rsum / binsize + 0.5);
2812  gave = (l_int32)(gsum / binsize + 0.5);
2813  bave = (l_int32)(bsum / binsize + 0.5);
2814  composeRGBPixel(rave, gave, bave, carray + binindex);
2815  rsum = gsum = bsum = 0.0;
2816  bincount = 0;
2817  binindex++;
2818  if (binindex == nbins) break;
2819  numaGetIValue(naeach, binindex, &binsize);
2820  }
2821  }
2822  if (binindex == nbins) break;
2823  }
2824  if (binindex != nbins)
2825  L_ERROR("binindex = %d != nbins = %d\n", procName, binindex, nbins);
2826 
2827  if (pixadb) {
2828  NUMA *nared, *nagreen, *nablue;
2829  nared = numaCreate(nbins);
2830  nagreen = numaCreate(nbins);
2831  nablue = numaCreate(nbins);
2832  for (i = 0; i < nbins; i++) {
2833  extractRGBValues(carray[i], &rval, &gval, &bval);
2834  numaAddNumber(nared, rval);
2835  numaAddNumber(nagreen, gval);
2836  numaAddNumber(nablue, bval);
2837  }
2838  lept_mkdir("lept/regout");
2839  pix1 = gplotSimplePix1(nared, "Average red val vs. rank bin");
2840  pixaAddPix(pixadb, pix1, L_INSERT);
2841  pix1 = gplotSimplePix1(nagreen, "Average green val vs. rank bin");
2842  pixaAddPix(pixadb, pix1, L_INSERT);
2843  pix1 = gplotSimplePix1(nablue, "Average blue val vs. rank bin");
2844  pixaAddPix(pixadb, pix1, L_INSERT);
2845  numaDestroy(&nared);
2846  numaDestroy(&nagreen);
2847  numaDestroy(&nablue);
2848  }
2849 
2850  *pcarray = carray;
2851  numaDestroy(&naeach);
2852  l_dnaaDestroy(&daa);
2853  return 0;
2854 }
2855 
2856 
2876 PIX *
2877 pixDisplayColorArray(l_uint32 *carray,
2878  l_int32 ncolors,
2879  l_int32 side,
2880  l_int32 ncols,
2881  l_int32 fontsize)
2882 {
2883 char textstr[256];
2884 l_int32 i, rval, gval, bval;
2885 L_BMF *bmf;
2886 PIX *pix1, *pix2, *pix3, *pix4;
2887 PIXA *pixa;
2888 
2889  PROCNAME("pixDisplayColorArray");
2890 
2891  if (!carray)
2892  return (PIX *)ERROR_PTR("carray not defined", procName, NULL);
2893  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2894  return (PIX *)ERROR_PTR("invalid fontsize", procName, NULL);
2895 
2896  bmf = (fontsize == 0) ? NULL : bmfCreate(NULL, fontsize);
2897  pixa = pixaCreate(ncolors);
2898  for (i = 0; i < ncolors; i++) {
2899  pix1 = pixCreate(side, side, 32);
2900  pixSetAllArbitrary(pix1, carray[i]);
2901  pix2 = pixAddBorder(pix1, 2, 1);
2902  if (bmf) {
2903  extractRGBValues(carray[i], &rval, &gval, &bval);
2904  snprintf(textstr, sizeof(textstr),
2905  "%d: (%d %d %d)", i, rval, gval, bval);
2906  pix3 = pixAddSingleTextblock(pix2, bmf, textstr, 0xff000000,
2907  L_ADD_BELOW, NULL);
2908  } else {
2909  pix3 = pixClone(pix2);
2910  }
2911  pixaAddPix(pixa, pix3, L_INSERT);
2912  pixDestroy(&pix1);
2913  pixDestroy(&pix2);
2914  }
2915  pix4 = pixaDisplayTiledInColumns(pixa, ncols, 1.0, 20, 2);
2916  pixaDestroy(&pixa);
2917  bmfDestroy(&bmf);
2918  return pix4;
2919 }
2920 
2921 
2952 PIX *
2954  l_int32 direction,
2955  l_int32 size,
2956  l_int32 nbins,
2957  l_int32 type)
2958 {
2959 l_int32 i, j, w, h, mindim, nstrips;
2960 l_uint32 *array;
2961 BOXA *boxa;
2962 PIX *pix1, *pix2, *pixd;
2963 PIXA *pixa;
2964 PIXCMAP *cmap;
2965 
2966  PROCNAME("pixRankBinByStrip");
2967 
2968  if (!pixs)
2969  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2970  cmap = pixGetColormap(pixs);
2971  if (pixGetDepth(pixs) != 32 && !cmap)
2972  return (PIX *)ERROR_PTR("pixs neither 32 bpp nor cmapped",
2973  procName, NULL);
2974  if (direction != L_SCAN_HORIZONTAL && direction != L_SCAN_VERTICAL)
2975  return (PIX *)ERROR_PTR("invalid direction", procName, NULL);
2976  if (size < 1)
2977  return (PIX *)ERROR_PTR("size < 1", procName, NULL);
2978  if (nbins < 2)
2979  return (PIX *)ERROR_PTR("nbins must be at least 2", procName, NULL);
2980  if (type != L_SELECT_RED && type != L_SELECT_GREEN &&
2981  type != L_SELECT_BLUE && type != L_SELECT_MIN &&
2982  type != L_SELECT_MAX && type != L_SELECT_AVERAGE &&
2983  type != L_SELECT_HUE && type != L_SELECT_SATURATION)
2984  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
2985  pixGetDimensions(pixs, &w, &h, NULL);
2986  mindim = L_MIN(w, h);
2987  if (mindim < 20 || nbins > mindim)
2988  return (PIX *)ERROR_PTR("pix too small and/or too many bins",
2989  procName, NULL);
2990 
2991  /* Remove colormap if it exists */
2992  if (cmap)
2994  else
2995  pix1 = pixClone(pixs);
2996  pixGetDimensions(pixs, &w, &h, NULL);
2997 
2998  pixd = NULL;
2999  boxa = makeMosaicStrips(w, h, direction, size);
3000  pixa = pixClipRectangles(pix1, boxa);
3001  nstrips = pixaGetCount(pixa);
3002  if (direction == L_SCAN_HORIZONTAL) {
3003  pixd = pixCreate(nstrips, nbins, 32);
3004  for (i = 0; i < nstrips; i++) {
3005  pix2 = pixaGetPix(pixa, i, L_CLONE);
3006  pixGetRankColorArray(pix2, nbins, type, 1, &array, NULL, 0);
3007  if (array) {
3008  for (j = 0; j < nbins; j++)
3009  pixSetPixel(pixd, i, j, array[j]);
3010  LEPT_FREE(array);
3011  }
3012  pixDestroy(&pix2);
3013  }
3014  } else { /* L_SCAN_VERTICAL */
3015  pixd = pixCreate(nbins, nstrips, 32);
3016  for (i = 0; i < nstrips; i++) {
3017  pix2 = pixaGetPix(pixa, i, L_CLONE);
3018  pixGetRankColorArray(pix2, nbins, type, 1, &array, NULL, 0);
3019  if (array) {
3020  for (j = 0; j < nbins; j++)
3021  pixSetPixel(pixd, j, i, array[j]);
3022  LEPT_FREE(array);
3023  }
3024  pixDestroy(&pix2);
3025  }
3026  }
3027  pixDestroy(&pix1);
3028  boxaDestroy(&boxa);
3029  pixaDestroy(&pixa);
3030  return pixd;
3031 }
3032 
3033 
3034 
3035 /*-------------------------------------------------------------*
3036  * Pixelwise aligned statistics *
3037  *-------------------------------------------------------------*/
3059 PIX *
3061  l_int32 type,
3062  l_int32 nbins,
3063  l_int32 thresh)
3064 {
3065 l_int32 j, n, w, h, d;
3066 l_float32 *colvect;
3067 PIX *pixt, *pixd;
3068 
3069  PROCNAME("pixaGetAlignedStats");
3070 
3071  if (!pixa)
3072  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
3073  if (type != L_MEAN_ABSVAL && type != L_MEDIAN_VAL &&
3074  type != L_MODE_VAL && type != L_MODE_COUNT)
3075  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
3076  n = pixaGetCount(pixa);
3077  if (n == 0)
3078  return (PIX *)ERROR_PTR("no pix in pixa", procName, NULL);
3079  pixaGetPixDimensions(pixa, 0, &w, &h, &d);
3080  if (d != 8)
3081  return (PIX *)ERROR_PTR("pix not 8 bpp", procName, NULL);
3082 
3083  pixd = pixCreate(w, h, 8);
3084  pixt = pixCreate(n, h, 8);
3085  colvect = (l_float32 *)LEPT_CALLOC(h, sizeof(l_float32));
3086  for (j = 0; j < w; j++) {
3087  pixaExtractColumnFromEachPix(pixa, j, pixt);
3088  pixGetRowStats(pixt, type, nbins, thresh, colvect);
3089  pixSetPixelColumn(pixd, j, colvect);
3090  }
3091 
3092  LEPT_FREE(colvect);
3093  pixDestroy(&pixt);
3094  return pixd;
3095 }
3096 
3097 
3106 l_ok
3108  l_int32 col,
3109  PIX *pixd)
3110 {
3111 l_int32 i, k, n, w, h, ht, val, wplt, wpld;
3112 l_uint32 *datad, *datat;
3113 PIX *pixt;
3114 
3115  PROCNAME("pixaExtractColumnFromEachPix");
3116 
3117  if (!pixa)
3118  return ERROR_INT("pixa not defined", procName, 1);
3119  if (!pixd || pixGetDepth(pixd) != 8)
3120  return ERROR_INT("pixd not defined or not 8 bpp", procName, 1);
3121  n = pixaGetCount(pixa);
3122  pixGetDimensions(pixd, &w, &h, NULL);
3123  if (n != w)
3124  return ERROR_INT("pix width != n", procName, 1);
3125  pixt = pixaGetPix(pixa, 0, L_CLONE);
3126  wplt = pixGetWpl(pixt);
3127  pixGetDimensions(pixt, NULL, &ht, NULL);
3128  pixDestroy(&pixt);
3129  if (h != ht)
3130  return ERROR_INT("pixd height != column height", procName, 1);
3131 
3132  datad = pixGetData(pixd);
3133  wpld = pixGetWpl(pixd);
3134  for (k = 0; k < n; k++) {
3135  pixt = pixaGetPix(pixa, k, L_CLONE);
3136  datat = pixGetData(pixt);
3137  for (i = 0; i < h; i++) {
3138  val = GET_DATA_BYTE(datat, col);
3139  SET_DATA_BYTE(datad + i * wpld, k, val);
3140  datat += wplt;
3141  }
3142  pixDestroy(&pixt);
3143  }
3144 
3145  return 0;
3146 }
3147 
3148 
3181 l_ok
3183  l_int32 type,
3184  l_int32 nbins,
3185  l_int32 thresh,
3186  l_float32 *colvect)
3187 {
3188 l_int32 i, j, k, w, h, val, wpls, sum, target, max, modeval;
3189 l_int32 *histo, *gray2bin, *bin2gray;
3190 l_uint32 *lines, *datas;
3191 
3192  PROCNAME("pixGetRowStats");
3193 
3194  if (!pixs || pixGetDepth(pixs) != 8)
3195  return ERROR_INT("pixs not defined or not 8 bpp", procName, 1);
3196  if (!colvect)
3197  return ERROR_INT("colvect not defined", procName, 1);
3198  if (type != L_MEAN_ABSVAL && type != L_MEDIAN_VAL &&
3199  type != L_MODE_VAL && type != L_MODE_COUNT)
3200  return ERROR_INT("invalid type", procName, 1);
3201  if (type != L_MEAN_ABSVAL && (nbins < 1 || nbins > 256))
3202  return ERROR_INT("invalid nbins", procName, 1);
3203  pixGetDimensions(pixs, &w, &h, NULL);
3204 
3205  datas = pixGetData(pixs);
3206  wpls = pixGetWpl(pixs);
3207  if (type == L_MEAN_ABSVAL) {
3208  for (i = 0; i < h; i++) {
3209  sum = 0;
3210  lines = datas + i * wpls;
3211  for (j = 0; j < w; j++)
3212  sum += GET_DATA_BYTE(lines, j);
3213  colvect[i] = (l_float32)sum / (l_float32)w;
3214  }
3215  return 0;
3216  }
3217 
3218  /* We need a histogram; binwidth ~ 256 / nbins */
3219  histo = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3220  gray2bin = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
3221  bin2gray = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3222  for (i = 0; i < 256; i++) /* gray value --> histo bin */
3223  gray2bin[i] = (i * nbins) / 256;
3224  for (i = 0; i < nbins; i++) /* histo bin --> gray value */
3225  bin2gray[i] = (i * 256 + 128) / nbins;
3226 
3227  for (i = 0; i < h; i++) {
3228  lines = datas + i * wpls;
3229  for (k = 0; k < nbins; k++)
3230  histo[k] = 0;
3231  for (j = 0; j < w; j++) {
3232  val = GET_DATA_BYTE(lines, j);
3233  histo[gray2bin[val]]++;
3234  }
3235 
3236  if (type == L_MEDIAN_VAL) {
3237  sum = 0;
3238  target = (w + 1) / 2;
3239  for (k = 0; k < nbins; k++) {
3240  sum += histo[k];
3241  if (sum >= target) {
3242  colvect[i] = bin2gray[k];
3243  break;
3244  }
3245  }
3246  } else if (type == L_MODE_VAL) {
3247  max = 0;
3248  modeval = 0;
3249  for (k = 0; k < nbins; k++) {
3250  if (histo[k] > max) {
3251  max = histo[k];
3252  modeval = k;
3253  }
3254  }
3255  if (max < thresh)
3256  colvect[i] = 0;
3257  else
3258  colvect[i] = bin2gray[modeval];
3259  } else { /* type == L_MODE_COUNT */
3260  max = 0;
3261  for (k = 0; k < nbins; k++) {
3262  if (histo[k] > max)
3263  max = histo[k];
3264  }
3265  colvect[i] = max;
3266  }
3267  }
3268 
3269  LEPT_FREE(histo);
3270  LEPT_FREE(gray2bin);
3271  LEPT_FREE(bin2gray);
3272  return 0;
3273 }
3274 
3275 
3303 l_ok
3305  l_int32 type,
3306  l_int32 nbins,
3307  l_int32 thresh,
3308  l_float32 *rowvect)
3309 {
3310 l_int32 i, j, k, w, h, val, wpls, sum, target, max, modeval;
3311 l_int32 *histo, *gray2bin, *bin2gray;
3312 l_uint32 *datas;
3313 
3314  PROCNAME("pixGetColumnStats");
3315 
3316  if (!pixs || pixGetDepth(pixs) != 8)
3317  return ERROR_INT("pixs not defined or not 8 bpp", procName, 1);
3318  if (!rowvect)
3319  return ERROR_INT("rowvect not defined", procName, 1);
3320  if (type != L_MEAN_ABSVAL && type != L_MEDIAN_VAL &&
3321  type != L_MODE_VAL && type != L_MODE_COUNT)
3322  return ERROR_INT("invalid type", procName, 1);
3323  if (type != L_MEAN_ABSVAL && (nbins < 1 || nbins > 256))
3324  return ERROR_INT("invalid nbins", procName, 1);
3325  pixGetDimensions(pixs, &w, &h, NULL);
3326 
3327  datas = pixGetData(pixs);
3328  wpls = pixGetWpl(pixs);
3329  if (type == L_MEAN_ABSVAL) {
3330  for (j = 0; j < w; j++) {
3331  sum = 0;
3332  for (i = 0; i < h; i++)
3333  sum += GET_DATA_BYTE(datas + i * wpls, j);
3334  rowvect[j] = (l_float32)sum / (l_float32)h;
3335  }
3336  return 0;
3337  }
3338 
3339  /* We need a histogram; binwidth ~ 256 / nbins */
3340  histo = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3341  gray2bin = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
3342  bin2gray = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3343  for (i = 0; i < 256; i++) /* gray value --> histo bin */
3344  gray2bin[i] = (i * nbins) / 256;
3345  for (i = 0; i < nbins; i++) /* histo bin --> gray value */
3346  bin2gray[i] = (i * 256 + 128) / nbins;
3347 
3348  for (j = 0; j < w; j++) {
3349  for (i = 0; i < h; i++) {
3350  val = GET_DATA_BYTE(datas + i * wpls, j);
3351  histo[gray2bin[val]]++;
3352  }
3353 
3354  if (type == L_MEDIAN_VAL) {
3355  sum = 0;
3356  target = (h + 1) / 2;
3357  for (k = 0; k < nbins; k++) {
3358  sum += histo[k];
3359  if (sum >= target) {
3360  rowvect[j] = bin2gray[k];
3361  break;
3362  }
3363  }
3364  } else if (type == L_MODE_VAL) {
3365  max = 0;
3366  modeval = 0;
3367  for (k = 0; k < nbins; k++) {
3368  if (histo[k] > max) {
3369  max = histo[k];
3370  modeval = k;
3371  }
3372  }
3373  if (max < thresh)
3374  rowvect[j] = 0;
3375  else
3376  rowvect[j] = bin2gray[modeval];
3377  } else { /* type == L_MODE_COUNT */
3378  max = 0;
3379  for (k = 0; k < nbins; k++) {
3380  if (histo[k] > max)
3381  max = histo[k];
3382  }
3383  rowvect[j] = max;
3384  }
3385  for (k = 0; k < nbins; k++)
3386  histo[k] = 0;
3387  }
3388 
3389  LEPT_FREE(histo);
3390  LEPT_FREE(gray2bin);
3391  LEPT_FREE(bin2gray);
3392  return 0;
3393 }
3394 
3395 
3404 l_ok
3406  l_int32 col,
3407  l_float32 *colvect)
3408 {
3409 l_int32 i, w, h, wpl;
3410 l_uint32 *data;
3411 
3412  PROCNAME("pixSetCPixelColumn");
3413 
3414  if (!pix || pixGetDepth(pix) != 8)
3415  return ERROR_INT("pix not defined or not 8 bpp", procName, 1);
3416  if (!colvect)
3417  return ERROR_INT("colvect not defined", procName, 1);
3418  pixGetDimensions(pix, &w, &h, NULL);
3419  if (col < 0 || col > w)
3420  return ERROR_INT("invalid col", procName, 1);
3421 
3422  data = pixGetData(pix);
3423  wpl = pixGetWpl(pix);
3424  for (i = 0; i < h; i++)
3425  SET_DATA_BYTE(data + i * wpl, col, (l_int32)colvect[i]);
3426 
3427  return 0;
3428 }
3429 
3430 
3431 /*-------------------------------------------------------------*
3432  * Foreground/background estimation *
3433  *-------------------------------------------------------------*/
3444 l_ok
3446  l_int32 factor,
3447  l_int32 thresh,
3448  l_int32 *pfgval,
3449  l_int32 *pbgval)
3450 {
3451 l_float32 fval;
3452 PIX *pixg, *pixm;
3453 
3454  PROCNAME("pixThresholdForFgBg");
3455 
3456  if (pfgval) *pfgval = 0;
3457  if (pbgval) *pbgval = 0;
3458  if (!pfgval && !pbgval)
3459  return ERROR_INT("no data requested", procName, 1);
3460  if (!pixs)
3461  return ERROR_INT("pixs not defined", procName, 1);
3462 
3463  /* Generate a subsampled 8 bpp version and a mask over the fg */
3464  pixg = pixConvertTo8BySampling(pixs, factor, 0);
3465  pixm = pixThresholdToBinary(pixg, thresh);
3466 
3467  if (pfgval) {
3468  pixGetAverageMasked(pixg, pixm, 0, 0, 1, L_MEAN_ABSVAL, &fval);
3469  *pfgval = (l_int32)(fval + 0.5);
3470  }
3471 
3472  if (pbgval) {
3473  pixInvert(pixm, pixm);
3474  pixGetAverageMasked(pixg, pixm, 0, 0, 1, L_MEAN_ABSVAL, &fval);
3475  *pbgval = (l_int32)(fval + 0.5);
3476  }
3477 
3478  pixDestroy(&pixg);
3479  pixDestroy(&pixm);
3480  return 0;
3481 }
3482 
3483 
3503 l_ok
3505  l_float32 scorefract,
3506  l_int32 factor,
3507  l_int32 *pthresh,
3508  l_int32 *pfgval,
3509  l_int32 *pbgval,
3510  PIX **ppixdb)
3511 {
3512 char buf[256];
3513 l_int32 thresh;
3514 l_float32 avefg, avebg, maxnum;
3515 GPLOT *gplot;
3516 NUMA *na, *nascore, *nax, *nay;
3517 PIX *pixg;
3518 
3519  PROCNAME("pixSplitDistributionFgBg");
3520 
3521  if (pthresh) *pthresh = 0;
3522  if (pfgval) *pfgval = 0;
3523  if (pbgval) *pbgval = 0;
3524  if (ppixdb) *ppixdb = NULL;
3525  if (!pthresh && !pfgval && !pbgval)
3526  return ERROR_INT("no data requested", procName, 1);
3527  if (!pixs)
3528  return ERROR_INT("pixs not defined", procName, 1);
3529 
3530  /* Generate a subsampled 8 bpp version */
3531  pixg = pixConvertTo8BySampling(pixs, factor, 0);
3532 
3533  /* Make the fg/bg estimates */
3534  na = pixGetGrayHistogram(pixg, 1);
3535  if (ppixdb) {
3536  numaSplitDistribution(na, scorefract, &thresh, &avefg, &avebg,
3537  NULL, NULL, &nascore);
3538  numaDestroy(&nascore);
3539  } else {
3540  numaSplitDistribution(na, scorefract, &thresh, &avefg, &avebg,
3541  NULL, NULL, NULL);
3542  }
3543 
3544  if (pthresh) *pthresh = thresh;
3545  if (pfgval) *pfgval = (l_int32)(avefg + 0.5);
3546  if (pbgval) *pbgval = (l_int32)(avebg + 0.5);
3547 
3548  if (ppixdb) {
3549  lept_mkdir("lept/redout");
3550  gplot = gplotCreate("/tmp/lept/redout/histplot", GPLOT_PNG, "Histogram",
3551  "Grayscale value", "Number of pixels");
3552  gplotAddPlot(gplot, NULL, na, GPLOT_LINES, NULL);
3553  nax = numaMakeConstant(thresh, 2);
3554  numaGetMax(na, &maxnum, NULL);
3555  nay = numaMakeConstant(0, 2);
3556  numaReplaceNumber(nay, 1, (l_int32)(0.5 * maxnum));
3557  snprintf(buf, sizeof(buf), "score fract = %3.1f", scorefract);
3558  gplotAddPlot(gplot, nax, nay, GPLOT_LINES, buf);
3559  *ppixdb = gplotMakeOutputPix(gplot);
3560  gplotDestroy(&gplot);
3561  numaDestroy(&nax);
3562  numaDestroy(&nay);
3563  }
3564 
3565  pixDestroy(&pixg);
3566  numaDestroy(&na);
3567  return 0;
3568 }
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:145
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:169
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:117
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:313
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
l_ok boxClipToRectangleParams(BOX *box, l_int32 w, l_int32 h, l_int32 *pxstart, l_int32 *pystart, l_int32 *pxend, l_int32 *pyend, l_int32 *pbw, l_int32 *pbh)
boxClipToRectangleParams()
Definition: boxfunc1.c:1785
BOXA * makeMosaicStrips(l_int32 w, l_int32 h, l_int32 direction, l_int32 size)
makeMosaicStrips()
Definition: boxfunc3.c:1311
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:824
l_ok pixcmapGetRangeValues(PIXCMAP *cmap, l_int32 select, l_int32 *pminval, l_int32 *pmaxval, l_int32 *pminindex, l_int32 *pmaxindex)
pixcmapGetRangeValues()
Definition: colormap.c:1520
l_int32 l_dnaaGetDnaCount(L_DNAA *daa, l_int32 index)
l_dnaaGetDnaCount()
Definition: dnabasic.c:1525
L_DNAA * l_dnaaCreateFull(l_int32 nptr, l_int32 n)
l_dnaaCreateFull()
Definition: dnabasic.c:1321
l_ok l_dnaaAddNumber(L_DNAA *daa, l_int32 index, l_float64 val)
l_dnaaAddNumber()
Definition: dnabasic.c:1684
l_int32 l_dnaaGetNumberCount(L_DNAA *daa)
l_dnaaGetNumberCount()
Definition: dnabasic.c:1546
l_ok l_dnaaGetValue(L_DNAA *daa, l_int32 i, l_int32 j, l_float64 *pval)
l_dnaaGetValue()
Definition: dnabasic.c:1644
void l_dnaDestroy(L_DNA **pda)
l_dnaDestroy()
Definition: dnabasic.c:332
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:631
void l_dnaaDestroy(L_DNAA **pdaa)
l_dnaaDestroy()
Definition: dnabasic.c:1386
l_ok l_dnaRemoveDupsByHmap(L_DNA *das, L_DNA **pdad, L_HASHMAP **phmap)
l_dnaRemoveDupsByHmap()
Definition: dnafunc1.c:565
L_DNA * pixConvertDataToDna(PIX *pix)
pixConvertDataToDna()
Definition: dnafunc1.c:296
l_ok gplotAddPlot(GPLOT *gplot, NUMA *nax, NUMA *nay, l_int32 plotstyle, const char *plotlabel)
gplotAddPlot()
Definition: gplot.c:320
GPLOT * gplotCreate(const char *rootname, l_int32 outformat, const char *title, const char *xlabel, const char *ylabel)
gplotCreate()
Definition: gplot.c:187
PIX * gplotMakeOutputPix(GPLOT *gplot)
gplotMakeOutputPix()
Definition: gplot.c:431
void gplotDestroy(GPLOT **pgplot)
gplotDestroy()
Definition: gplot.c:255
PIX * gplotSimplePix1(NUMA *na, const char *title)
gplotSimplePix1()
Definition: gplot.c:776
PIX * pixThresholdToBinary(PIX *pixs, l_int32 thresh)
pixThresholdToBinary()
Definition: grayquant.c:447
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
l_ok numaReplaceNumber(NUMA *na, l_int32 index, l_float32 val)
numaReplaceNumber()
Definition: numabasic.c:627
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_ok numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition: numabasic.c:685
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
NUMAA * numaaCreate(l_int32 n)
numaaCreate()
Definition: numabasic.c:1407
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
l_ok numaaAddNuma(NUMAA *naa, NUMA *na, l_int32 copyflag)
numaaAddNuma()
Definition: numabasic.c:1546
NUMA * numaCreateFromFArray(l_float32 *farray, l_int32 size, l_int32 copyflag)
numaCreateFromFArray()
Definition: numabasic.c:271
l_float32 * numaGetFArray(NUMA *na, l_int32 copyflag)
numaGetFArray()
Definition: numabasic.c:892
NUMA * numaMakeConstant(l_float32 val, l_int32 size)
numaMakeConstant()
Definition: numafunc1.c:851
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:496
l_ok numaDiscretizeHistoInBins(NUMA *na, l_int32 nbins, NUMA **pnabinval, NUMA **pnarank)
numaDiscretizeHistoInBins()
Definition: numafunc2.c:1783
l_ok numaSplitDistribution(NUMA *na, l_float32 scorefract, l_int32 *psplitindex, l_float32 *pave1, l_float32 *pave2, l_float32 *pnum1, l_float32 *pnum2, NUMA **pnascore)
numaSplitDistribution()
Definition: numafunc2.c:2023
l_ok numaHistogramGetValFromRank(NUMA *na, l_float32 rank, l_float32 *prval)
numaHistogramGetValFromRank()
Definition: numafunc2.c:1634
NUMA * numaGetUniformBinSizes(l_int32 ntotal, l_int32 nbins)
numaGetUniformBinSizes()
Definition: numafunc2.c:1945
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2479
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:263
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1823
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2751
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2820
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition: pix2.c:2600
l_ok pixZero(PIX *pix, l_int32 *pempty)
pixZero()
Definition: pix3.c:1815
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1509
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1937
l_ok pixCountRGBColorsByHash(PIX *pixs, l_int32 *pncolors)
pixCountRGBColorsByHash()
Definition: pix4.c:844
l_ok pixGetAverageMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_int32 type, l_float32 *pval)
pixGetAverageMasked()
Definition: pix4.c:1526
NUMA * pixGetGrayHistogramInRect(PIX *pixs, BOX *box, l_int32 factor)
pixGetGrayHistogramInRect()
Definition: pix4.c:291
l_ok pixGetColorHistogram(PIX *pixs, l_int32 factor, NUMA **pnar, NUMA **pnag, NUMA **pnab)
pixGetColorHistogram()
Definition: pix4.c:416
PIX * pixDisplayColorArray(l_uint32 *carray, l_int32 ncolors, l_int32 side, l_int32 ncols, l_int32 fontsize)
pixDisplayColorArray()
Definition: pix4.c:2877
PIX * pixRankBinByStrip(PIX *pixs, l_int32 direction, l_int32 size, l_int32 nbins, l_int32 type)
pixRankBinByStrip()
Definition: pix4.c:2953
l_ok pixGetRankValueMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_float32 rank, l_float32 *pval, NUMA **pna)
pixGetRankValueMasked()
Definition: pix4.c:1168
L_AMAP * pixGetColorAmapHistogram(PIX *pixs, l_int32 factor)
pixGetColorAmapHistogram()
Definition: pix4.c:916
l_ok pixGetBinnedComponentRange(PIX *pixs, l_int32 nbins, l_int32 factor, l_int32 color, l_int32 *pminval, l_int32 *pmaxval, l_uint32 **pcarray, l_int32 fontsize)
pixGetBinnedComponentRange()
Definition: pix4.c:2501
NUMA * pixGetGrayHistogram(PIX *pixs, l_int32 factor)
pixGetGrayHistogram()
Definition: pix4.c:115
NUMA * pixGetCmapHistogramInRect(PIX *pixs, BOX *box, l_int32 factor)
pixGetCmapHistogramInRect()
Definition: pix4.c:778
NUMA * pixGetGrayHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor)
pixGetGrayHistogramMasked()
Definition: pix4.c:211
l_ok pixGetColorHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, NUMA **pnar, NUMA **pnag, NUMA **pnab)
pixGetColorHistogramMasked()
Definition: pix4.c:518
l_ok pixGetMaxColorIndex(PIX *pixs, l_int32 *pmaxindex)
pixGetMaxColorIndex()
Definition: pix4.c:2427
l_ok pixGetRangeValues(PIX *pixs, l_int32 factor, l_int32 color, l_int32 *pminval, l_int32 *pmaxval)
pixGetRangeValues()
Definition: pix4.c:2137
l_ok pixGetRankValueMaskedRGB(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_float32 rank, l_float32 *prval, l_float32 *pgval, l_float32 *pbval)
pixGetRankValueMaskedRGB()
Definition: pix4.c:1076
l_ok pixSplitDistributionFgBg(PIX *pixs, l_float32 scorefract, l_int32 factor, l_int32 *pthresh, l_int32 *pfgval, l_int32 *pbgval, PIX **ppixdb)
pixSplitDistributionFgBg()
Definition: pix4.c:3504
l_ok pixGetRowStats(PIX *pixs, l_int32 type, l_int32 nbins, l_int32 thresh, l_float32 *colvect)
pixGetRowStats()
Definition: pix4.c:3182
NUMA * pixGetCmapHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor)
pixGetCmapHistogramMasked()
Definition: pix4.c:698
l_ok pixaExtractColumnFromEachPix(PIXA *pixa, l_int32 col, PIX *pixd)
pixaExtractColumnFromEachPix()
Definition: pix4.c:3107
l_ok pixGetRankColorArray(PIX *pixs, l_int32 nbins, l_int32 type, l_int32 factor, l_uint32 **pcarray, PIXA *pixadb, l_int32 fontsize)
pixGetRankColorArray()
Definition: pix4.c:2600
l_ok pixGetAverageTiledRGB(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 type, PIX **ppixr, PIX **ppixg, PIX **ppixb)
pixGetAverageTiledRGB()
Definition: pix4.c:1650
PIX * pixGetAverageTiled(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 type)
pixGetAverageTiled()
Definition: pix4.c:1727
l_int32 pixColumnStats(PIX *pixs, BOX *box, NUMA **pnamean, NUMA **pnamedian, NUMA **pnamode, NUMA **pnamodecount, NUMA **pnavar, NUMA **pnarootvar)
pixColumnStats()
Definition: pix4.c:1990
l_ok pixGetPixelStats(PIX *pixs, l_int32 factor, l_int32 type, l_uint32 *pvalue)
pixGetPixelStats()
Definition: pix4.c:1357
l_ok pixCountRGBColors(PIX *pixs, l_int32 factor, l_int32 *pncolors)
pixCountRGBColors()
Definition: pix4.c:880
l_ok pixGetBinnedColor(PIX *pixs, PIX *pixg, l_int32 factor, l_int32 nbins, l_uint32 **pcarray, PIXA *pixadb)
pixGetBinnedColor()
Definition: pix4.c:2705
l_ok pixGetExtremeValue(PIX *pixs, l_int32 factor, l_int32 type, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *pgrayval)
pixGetExtremeValue()
Definition: pix4.c:2215
NUMAA * pixGetGrayHistogramTiled(PIX *pixs, l_int32 factor, l_int32 nx, l_int32 ny)
pixGetGrayHistogramTiled()
Definition: pix4.c:359
l_ok pixSetPixelColumn(PIX *pix, l_int32 col, l_float32 *colvect)
pixSetPixelColumn()
Definition: pix4.c:3405
l_ok pixThresholdForFgBg(PIX *pixs, l_int32 factor, l_int32 thresh, l_int32 *pfgval, l_int32 *pbgval)
pixThresholdForFgBg()
Definition: pix4.c:3445
l_ok pixGetRankValue(PIX *pixs, l_int32 factor, l_float32 rank, l_uint32 *pvalue)
pixGetRankValue()
Definition: pix4.c:1006
l_int32 pixRowStats(PIX *pixs, BOX *box, NUMA **pnamean, NUMA **pnamedian, NUMA **pnamode, NUMA **pnamodecount, NUMA **pnavar, NUMA **pnarootvar)
pixRowStats()
Definition: pix4.c:1830
NUMA * pixGetCmapHistogram(PIX *pixs, l_int32 factor)
pixGetCmapHistogram()
Definition: pix4.c:633
PIX * pixaGetAlignedStats(PIXA *pixa, l_int32 type, l_int32 nbins, l_int32 thresh)
pixaGetAlignedStats()
Definition: pix4.c:3060
l_ok pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2352
l_ok pixGetAverageMaskedRGB(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_int32 type, l_float32 *prval, l_float32 *pgval, l_float32 *pbval)
pixGetAverageMaskedRGB()
Definition: pix4.c:1424
l_int32 amapGetCountForColor(L_AMAP *amap, l_uint32 val)
amapGetCountForColor()
Definition: pix4.c:967
l_ok pixGetPixelAverage(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_uint32 *pval)
pixGetPixelAverage()
Definition: pix4.c:1239
l_ok pixGetColumnStats(PIX *pixs, l_int32 type, l_int32 nbins, l_int32 thresh, l_float32 *rowvect)
pixGetColumnStats()
Definition: pix4.c:3304
PIXA * pixClipRectangles(PIX *pixs, BOXA *boxa)
pixClipRectangles()
Definition: pix5.c:960
@ COLOR_BLUE
Definition: pix.h:206
@ COLOR_RED
Definition: pix.h:204
@ COLOR_GREEN
Definition: pix.h:205
@ L_SELECT_MAX
Definition: pix.h:826
@ L_SELECT_GREEN
Definition: pix.h:823
@ L_SELECT_SATURATION
Definition: pix.h:829
@ L_SELECT_BLUE
Definition: pix.h:824
@ L_SELECT_AVERAGE
Definition: pix.h:827
@ L_SELECT_MIN
Definition: pix.h:825
@ L_SELECT_HUE
Definition: pix.h:828
@ L_SELECT_RED
Definition: pix.h:822
@ REMOVE_CMAP_TO_FULL_COLOR
Definition: pix.h:258
@ REMOVE_CMAP_TO_GRAYSCALE
Definition: pix.h:257
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:260
@ L_ADD_BELOW
Definition: pix.h:1210
@ L_CLONE
Definition: pix.h:713
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
@ L_SCAN_VERTICAL
Definition: pix.h:1042
@ L_SCAN_HORIZONTAL
Definition: pix.h:1041
@ L_MODE_VAL
Definition: pix.h:970
@ L_ROOT_MEAN_SQUARE
Definition: pix.h:972
@ L_MODE_COUNT
Definition: pix.h:971
@ L_MEAN_ABSVAL
Definition: pix.h:968
@ L_VARIANCE
Definition: pix.h:974
@ L_STANDARD_DEVIATION
Definition: pix.h:973
@ L_MEDIAN_VAL
Definition: pix.h:969
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
PIXA * pixaSplitPix(PIX *pixs, l_int32 nx, l_int32 ny, l_int32 borderwidth, l_uint32 bordercolor)
pixaSplitPix()
Definition: pixabasic.c:350
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:726
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
PIX * pixaDisplayTiledInColumns(PIXA *pixas, l_int32 nx, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayTiledInColumns()
Definition: pixafunc2.c:930
PIX * pixConvertRGBToGrayGeneral(PIX *pixs, l_int32 type, l_float32 rwt, l_float32 gwt, l_float32 bwt)
pixConvertRGBToGrayGeneral()
Definition: pixconv.c:766
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
PIX * pixConvertTo8BySampling(PIX *pixs, l_int32 factor, l_int32 cmapflag)
pixConvertTo8BySampling()
Definition: pixconv.c:3204
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
PIX * pixScaleRGBToGrayFast(PIX *pixs, l_int32 factor, l_int32 color)
pixScaleRGBToGrayFast()
Definition: scale1.c:1486
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
PIX * pixScaleByIntSampling(PIX *pixs, l_int32 factor)
pixScaleByIntSampling()
Definition: scale1.c:1444
Definition: pix.h:481
Definition: pix.h:492
Definition: gplot.h:77
Definition: bmf.h:47
Definition: array.h:95
Definition: array.h:107
Definition: array.h:71
Definition: array.h:83
Definition: pix.h:139
Definition: pix.h:456
PIX * pixAddSingleTextblock(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location, l_int32 *poverflow)
pixAddSingleTextblock()
Definition: textops.c:120
Definition: rbtree.h:62
l_int32 lept_roundftoi(l_float32 fval)
lept_roundftoi()
Definition: utils1.c:700
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218