Leptonica  1.83.1
Image processing and image analysis suite
ptafunc1.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 
102 #ifdef HAVE_CONFIG_H
103 #include <config_auto.h>
104 #endif /* HAVE_CONFIG_H */
105 
106 #include <math.h>
107 #include "allheaders.h"
108 #include "pix_internal.h"
109 
110 #ifndef M_PI
111 #define M_PI 3.14159265358979323846
112 #endif /* M_PI */
113 
114 /*---------------------------------------------------------------------*
115  * Simple rearrangements *
116  *---------------------------------------------------------------------*/
124 PTA *
126  l_int32 subfactor)
127 {
128 l_int32 n, i;
129 l_float32 x, y;
130 PTA *ptad;
131 
132  if (!ptas)
133  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
134  if (subfactor < 1)
135  return (PTA *)ERROR_PTR("subfactor < 1", __func__, NULL);
136 
137  ptad = ptaCreate(0);
138  n = ptaGetCount(ptas);
139  for (i = 0; i < n; i++) {
140  if (i % subfactor != 0) continue;
141  ptaGetPt(ptas, i, &x, &y);
142  ptaAddPt(ptad, x, y);
143  }
144 
145  return ptad;
146 }
147 
148 
165 l_ok
166 ptaJoin(PTA *ptad,
167  PTA *ptas,
168  l_int32 istart,
169  l_int32 iend)
170 {
171 l_int32 n, i, x, y;
172 
173  if (!ptad)
174  return ERROR_INT("ptad not defined", __func__, 1);
175  if (!ptas)
176  return 0;
177 
178  if (istart < 0)
179  istart = 0;
180  n = ptaGetCount(ptas);
181  if (iend < 0 || iend >= n)
182  iend = n - 1;
183  if (istart > iend)
184  return ERROR_INT("istart > iend; no pts", __func__, 1);
185 
186  for (i = istart; i <= iend; i++) {
187  ptaGetIPt(ptas, i, &x, &y);
188  if (ptaAddPt(ptad, x, y) == 1) {
189  L_ERROR("failed to add pt at i = %d\n", __func__, i);
190  return 1;
191  }
192  }
193  return 0;
194 }
195 
196 
213 l_ok
214 ptaaJoin(PTAA *ptaad,
215  PTAA *ptaas,
216  l_int32 istart,
217  l_int32 iend)
218 {
219 l_int32 n, i;
220 PTA *pta;
221 
222  if (!ptaad)
223  return ERROR_INT("ptaad not defined", __func__, 1);
224  if (!ptaas)
225  return 0;
226 
227  if (istart < 0)
228  istart = 0;
229  n = ptaaGetCount(ptaas);
230  if (iend < 0 || iend >= n)
231  iend = n - 1;
232  if (istart > iend)
233  return ERROR_INT("istart > iend; no pts", __func__, 1);
234 
235  for (i = istart; i <= iend; i++) {
236  pta = ptaaGetPta(ptaas, i, L_CLONE);
237  ptaaAddPta(ptaad, pta, L_INSERT);
238  }
239 
240  return 0;
241 }
242 
243 
251 PTA *
253  l_int32 type)
254 {
255 l_int32 n, i, ix, iy;
256 l_float32 x, y;
257 PTA *ptad;
258 
259  if (!ptas)
260  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
261 
262  n = ptaGetCount(ptas);
263  if ((ptad = ptaCreate(n)) == NULL)
264  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
265  for (i = n - 1; i >= 0; i--) {
266  if (type == 0) {
267  ptaGetPt(ptas, i, &x, &y);
268  ptaAddPt(ptad, x, y);
269  } else { /* type == 1 */
270  ptaGetIPt(ptas, i, &ix, &iy);
271  ptaAddPt(ptad, ix, iy);
272  }
273  }
274 
275  return ptad;
276 }
277 
278 
285 PTA *
287 {
288 l_int32 n, i;
289 l_float32 x, y;
290 PTA *ptad;
291 
292  if (!ptas)
293  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
294 
295  n = ptaGetCount(ptas);
296  if ((ptad = ptaCreate(n)) == NULL)
297  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
298  for (i = 0; i < n; i++) {
299  ptaGetPt(ptas, i, &x, &y);
300  ptaAddPt(ptad, y, x);
301  }
302 
303  return ptad;
304 }
305 
306 
323 PTA *
325  l_int32 xs,
326  l_int32 ys)
327 {
328 l_int32 n, i, x, y, j, index, state;
329 l_int32 x1, y1, x2, y2;
330 PTA *ptad;
331 
332  if (!ptas)
333  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
334 
335  n = ptaGetCount(ptas);
336 
337  /* Verify input data */
338  ptaGetIPt(ptas, 0, &x1, &y1);
339  ptaGetIPt(ptas, n - 1, &x2, &y2);
340  if (x1 != x2 || y1 != y2)
341  return (PTA *)ERROR_PTR("start and end pts not same", __func__, NULL);
342  state = L_NOT_FOUND;
343  for (i = 0; i < n; i++) {
344  ptaGetIPt(ptas, i, &x, &y);
345  if (x == xs && y == ys) {
346  state = L_FOUND;
347  break;
348  }
349  }
350  if (state == L_NOT_FOUND)
351  return (PTA *)ERROR_PTR("start pt not in ptas", __func__, NULL);
352 
353  if ((ptad = ptaCreate(n)) == NULL)
354  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
355  for (j = 0; j < n - 1; j++) {
356  if (i + j < n - 1)
357  index = i + j;
358  else
359  index = (i + j + 1) % n;
360  ptaGetIPt(ptas, index, &x, &y);
361  ptaAddPt(ptad, x, y);
362  }
363  ptaAddPt(ptad, xs, ys);
364 
365  return ptad;
366 }
367 
368 
377 PTA *
379  l_int32 first,
380  l_int32 last)
381 {
382 l_int32 n, npt, i;
383 l_float32 x, y;
384 PTA *ptad;
385 
386  if (!ptas)
387  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
388  if ((n = ptaGetCount(ptas)) == 0) {
389  L_WARNING("ptas is empty\n", __func__);
390  return ptaCopy(ptas);
391  }
392  first = L_MAX(0, first);
393  if (last < 0) last = n - 1;
394  if (first >= n)
395  return (PTA *)ERROR_PTR("invalid first", __func__, NULL);
396  if (last >= n) {
397  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
398  __func__, last, n - 1);
399  last = n - 1;
400  }
401  if (first > last)
402  return (PTA *)ERROR_PTR("first > last", __func__, NULL);
403 
404  npt = last - first + 1;
405  ptad = ptaCreate(npt);
406  for (i = first; i <= last; i++) {
407  ptaGetPt(ptas, i, &x, &y);
408  ptaAddPt(ptad, x, y);
409  }
410  return ptad;
411 }
412 
413 
414 /*---------------------------------------------------------------------*
415  * Geometric *
416  *---------------------------------------------------------------------*/
430 BOX *
432 {
433 l_int32 n, i, x, y, minx, maxx, miny, maxy;
434 
435  if (!pta)
436  return (BOX *)ERROR_PTR("pta not defined", __func__, NULL);
437 
438  minx = 10000000;
439  miny = 10000000;
440  maxx = -10000000;
441  maxy = -10000000;
442  n = ptaGetCount(pta);
443  for (i = 0; i < n; i++) {
444  ptaGetIPt(pta, i, &x, &y);
445  if (x < minx) minx = x;
446  if (x > maxx) maxx = x;
447  if (y < miny) miny = y;
448  if (y > maxy) maxy = y;
449  }
450 
451  return boxCreate(minx, miny, maxx - minx + 1, maxy - miny + 1);
452 }
453 
454 
472 l_ok
474  l_float32 *pminx,
475  l_float32 *pmaxx,
476  l_float32 *pminy,
477  l_float32 *pmaxy)
478 {
479 l_int32 n, i;
480 l_float32 x, y, minx, maxx, miny, maxy;
481 
482  if (!pminx && !pmaxx && !pminy && !pmaxy)
483  return ERROR_INT("no output requested", __func__, 1);
484  if (pminx) *pminx = 0;
485  if (pmaxx) *pmaxx = 0;
486  if (pminy) *pminy = 0;
487  if (pmaxy) *pmaxy = 0;
488  if (!pta)
489  return ERROR_INT("pta not defined", __func__, 1);
490  if ((n = ptaGetCount(pta)) == 0)
491  return ERROR_INT("no points in pta", __func__, 1);
492 
493  ptaGetPt(pta, 0, &x, &y);
494  minx = x;
495  maxx = x;
496  miny = y;
497  maxy = y;
498  for (i = 1; i < n; i++) {
499  ptaGetPt(pta, i, &x, &y);
500  if (x < minx) minx = x;
501  if (x > maxx) maxx = x;
502  if (y < miny) miny = y;
503  if (y > maxy) maxy = y;
504  }
505  if (pminx) *pminx = minx;
506  if (pmaxx) *pmaxx = maxx;
507  if (pminy) *pminy = miny;
508  if (pmaxy) *pmaxy = maxy;
509  return 0;
510 }
511 
512 
520 PTA *
522  BOX *box)
523 {
524 PTA *ptad;
525 l_int32 n, i, contains;
526 l_float32 x, y;
527 
528  if (!ptas)
529  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
530  if (!box)
531  return (PTA *)ERROR_PTR("box not defined", __func__, NULL);
532 
533  n = ptaGetCount(ptas);
534  ptad = ptaCreate(0);
535  for (i = 0; i < n; i++) {
536  ptaGetPt(ptas, i, &x, &y);
537  boxContainsPt(box, x, y, &contains);
538  if (contains)
539  ptaAddPt(ptad, x, y);
540  }
541 
542  return ptad;
543 }
544 
545 
558 PTA *
560 {
561 l_int32 i, j, x, y, w, h, wpl, mindim, found;
562 l_uint32 *data, *line;
563 PTA *pta;
564 
565  if (!pixs)
566  return (PTA *)ERROR_PTR("pixs not defined", __func__, NULL);
567  if (pixGetDepth(pixs) != 1)
568  return (PTA *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
569 
570  w = pixGetWidth(pixs);
571  h = pixGetHeight(pixs);
572  mindim = L_MIN(w, h);
573  data = pixGetData(pixs);
574  wpl = pixGetWpl(pixs);
575 
576  if ((pta = ptaCreate(4)) == NULL)
577  return (PTA *)ERROR_PTR("pta not made", __func__, NULL);
578 
579  for (found = FALSE, i = 0; i < mindim; i++) {
580  for (j = 0; j <= i; j++) {
581  y = i - j;
582  line = data + y * wpl;
583  if (GET_DATA_BIT(line, j)) {
584  ptaAddPt(pta, j, y);
585  found = TRUE;
586  break;
587  }
588  }
589  if (found == TRUE)
590  break;
591  }
592 
593  for (found = FALSE, i = 0; i < mindim; i++) {
594  for (j = 0; j <= i; j++) {
595  y = i - j;
596  line = data + y * wpl;
597  x = w - 1 - j;
598  if (GET_DATA_BIT(line, x)) {
599  ptaAddPt(pta, x, y);
600  found = TRUE;
601  break;
602  }
603  }
604  if (found == TRUE)
605  break;
606  }
607 
608  for (found = FALSE, i = 0; i < mindim; i++) {
609  for (j = 0; j <= i; j++) {
610  y = h - 1 - i + j;
611  line = data + y * wpl;
612  if (GET_DATA_BIT(line, j)) {
613  ptaAddPt(pta, j, y);
614  found = TRUE;
615  break;
616  }
617  }
618  if (found == TRUE)
619  break;
620  }
621 
622  for (found = FALSE, i = 0; i < mindim; i++) {
623  for (j = 0; j <= i; j++) {
624  y = h - 1 - i + j;
625  line = data + y * wpl;
626  x = w - 1 - j;
627  if (GET_DATA_BIT(line, x)) {
628  ptaAddPt(pta, x, y);
629  found = TRUE;
630  break;
631  }
632  }
633  if (found == TRUE)
634  break;
635  }
636 
637  return pta;
638 }
639 
640 
648 l_int32
650  l_int32 x,
651  l_int32 y)
652 {
653 l_int32 i, n, ix, iy;
654 
655  if (!pta)
656  return ERROR_INT("pta not defined", __func__, 0);
657 
658  n = ptaGetCount(pta);
659  for (i = 0; i < n; i++) {
660  ptaGetIPt(pta, i, &ix, &iy);
661  if (x == ix && y == iy)
662  return 1;
663  }
664  return 0;
665 }
666 
667 
675 l_int32
677  PTA *pta2)
678 {
679 l_int32 i, j, n1, n2, x1, y1, x2, y2;
680 
681  if (!pta1)
682  return ERROR_INT("pta1 not defined", __func__, 0);
683  if (!pta2)
684  return ERROR_INT("pta2 not defined", __func__, 0);
685 
686  n1 = ptaGetCount(pta1);
687  n2 = ptaGetCount(pta2);
688  for (i = 0; i < n1; i++) {
689  ptaGetIPt(pta1, i, &x1, &y1);
690  for (j = 0; j < n2; j++) {
691  ptaGetIPt(pta2, i, &x2, &y2);
692  if (x1 == x2 && y1 == y2)
693  return 1;
694  }
695  }
696 
697  return 0;
698 }
699 
700 
714 PTA *
716  l_int32 shiftx,
717  l_int32 shifty,
718  l_float32 scalex,
719  l_float32 scaley)
720 {
721 l_int32 n, i, x, y;
722 PTA *ptad;
723 
724  if (!ptas)
725  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
726  n = ptaGetCount(ptas);
727  ptad = ptaCreate(n);
728  for (i = 0; i < n; i++) {
729  ptaGetIPt(ptas, i, &x, &y);
730  x = (l_int32)(scalex * (x + shiftx) + 0.5);
731  y = (l_int32)(scaley * (y + shifty) + 0.5);
732  ptaAddPt(ptad, x, y);
733  }
734 
735  return ptad;
736 }
737 
738 
752 l_int32
754  l_float32 x,
755  l_float32 y,
756  l_int32 *pinside)
757 {
758 l_int32 i, n;
759 l_float32 sum, x1, y1, x2, y2, xp1, yp1, xp2, yp2;
760 
761  if (!pinside)
762  return ERROR_INT("&inside not defined", __func__, 1);
763  *pinside = 0;
764  if (!pta)
765  return ERROR_INT("pta not defined", __func__, 1);
766 
767  /* Think of (x1,y1) as the end point of a vector that starts
768  * from the origin (0,0), and ditto for (x2,y2). */
769  n = ptaGetCount(pta);
770  sum = 0.0;
771  for (i = 0; i < n; i++) {
772  ptaGetPt(pta, i, &xp1, &yp1);
773  ptaGetPt(pta, (i + 1) % n, &xp2, &yp2);
774  x1 = xp1 - x;
775  y1 = yp1 - y;
776  x2 = xp2 - x;
777  y2 = yp2 - y;
778  sum += l_angleBetweenVectors(x1, y1, x2, y2);
779  }
780 
781  if (L_ABS(sum) > M_PI)
782  *pinside = 1;
783  return 0;
784 }
785 
786 
802 l_float32
804  l_float32 y1,
805  l_float32 x2,
806  l_float32 y2)
807 {
808 l_float64 ang;
809 
810  ang = atan2(y2, x2) - atan2(y1, x1);
811  if (ang > M_PI) ang -= 2.0 * M_PI;
812  if (ang < -M_PI) ang += 2.0 * M_PI;
813  return ang;
814 }
815 
816 
837 l_int32
839  l_int32 *pisconvex)
840 {
841 l_int32 i, n;
842 l_float32 x0, y0, x1, y1, x2, y2;
843 l_float64 cprod;
844 
845  if (!pisconvex)
846  return ERROR_INT("&isconvex not defined", __func__, 1);
847  *pisconvex = 0;
848  if (!pta)
849  return ERROR_INT("pta not defined", __func__, 1);
850  if ((n = ptaGetCount(pta)) < 3)
851  return ERROR_INT("pta has < 3 pts", __func__, 1);
852 
853  for (i = 0; i < n; i++) {
854  ptaGetPt(pta, i, &x0, &y0);
855  ptaGetPt(pta, (i + 1) % n, &x1, &y1);
856  ptaGetPt(pta, (i + 2) % n, &x2, &y2);
857  /* The vector v02 from p0 to p2 must be to the right of the
858  vector v01 from p0 to p1. This is true if the cross
859  product v02 x v01 > 0. In coordinates:
860  v02x * v01y - v01x * v02y, where
861  v01x = x1 - x0, v01y = y1 - y0,
862  v02x = x2 - x0, v02y = y2 - y0 */
863  cprod = (x2 - x0) * (y1 - y0) - (x1 - x0) * (y2 - y0);
864  if (cprod < -0.0001) /* small delta for float accuracy; test fails */
865  return 0;
866  }
867  *pisconvex = 1;
868  return 0;
869 }
870 
871 
872 /*---------------------------------------------------------------------*
873  * Min/max and filtering *
874  *---------------------------------------------------------------------*/
886 l_ok
888  l_float32 *pxmin,
889  l_float32 *pymin,
890  l_float32 *pxmax,
891  l_float32 *pymax)
892 {
893 l_int32 i, n;
894 l_float32 x, y, xmin, ymin, xmax, ymax;
895 
896  if (pxmin) *pxmin = -1.0;
897  if (pymin) *pymin = -1.0;
898  if (pxmax) *pxmax = -1.0;
899  if (pymax) *pymax = -1.0;
900  if (!pta)
901  return ERROR_INT("pta not defined", __func__, 1);
902  if (!pxmin && !pxmax && !pymin && !pymax)
903  return ERROR_INT("no output requested", __func__, 1);
904  if ((n = ptaGetCount(pta)) == 0) {
905  L_WARNING("pta is empty\n", __func__);
906  return 0;
907  }
908 
909  xmin = ymin = 1.0e20;
910  xmax = ymax = -1.0e20;
911  for (i = 0; i < n; i++) {
912  ptaGetPt(pta, i, &x, &y);
913  if (x < xmin) xmin = x;
914  if (y < ymin) ymin = y;
915  if (x > xmax) xmax = x;
916  if (y > ymax) ymax = y;
917  }
918  if (pxmin) *pxmin = xmin;
919  if (pymin) *pymin = ymin;
920  if (pxmax) *pxmax = xmax;
921  if (pymax) *pymax = ymax;
922  return 0;
923 }
924 
925 
937 PTA *
939  l_float32 xth,
940  l_float32 yth,
941  l_int32 type,
942  l_int32 relation)
943 {
944 l_int32 i, n;
945 l_float32 x, y;
946 PTA *ptad;
947 
948  if (!ptas)
949  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
950  if (ptaGetCount(ptas) == 0) {
951  L_WARNING("ptas is empty\n", __func__);
952  return ptaCopy(ptas);
953  }
954  if (type != L_SELECT_XVAL && type != L_SELECT_YVAL &&
955  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
956  return (PTA *)ERROR_PTR("invalid type", __func__, NULL);
957  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
958  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
959  return (PTA *)ERROR_PTR("invalid relation", __func__, NULL);
960 
961  n = ptaGetCount(ptas);
962  ptad = ptaCreate(n);
963  for (i = 0; i < n; i++) {
964  ptaGetPt(ptas, i, &x, &y);
965  if (type == L_SELECT_XVAL) {
966  if ((relation == L_SELECT_IF_LT && x < xth) ||
967  (relation == L_SELECT_IF_GT && x > xth) ||
968  (relation == L_SELECT_IF_LTE && x <= xth) ||
969  (relation == L_SELECT_IF_GTE && x >= xth))
970  ptaAddPt(ptad, x, y);
971  } else if (type == L_SELECT_YVAL) {
972  if ((relation == L_SELECT_IF_LT && y < yth) ||
973  (relation == L_SELECT_IF_GT && y > yth) ||
974  (relation == L_SELECT_IF_LTE && y <= yth) ||
975  (relation == L_SELECT_IF_GTE && y >= yth))
976  ptaAddPt(ptad, x, y);
977  } else if (type == L_SELECT_IF_EITHER) {
978  if (((relation == L_SELECT_IF_LT) && (x < xth || y < yth)) ||
979  ((relation == L_SELECT_IF_GT) && (x > xth || y > yth)) ||
980  ((relation == L_SELECT_IF_LTE) && (x <= xth || y <= yth)) ||
981  ((relation == L_SELECT_IF_GTE) && (x >= xth || y >= yth)))
982  ptaAddPt(ptad, x, y);
983  } else { /* L_SELECT_IF_BOTH */
984  if (((relation == L_SELECT_IF_LT) && (x < xth && y < yth)) ||
985  ((relation == L_SELECT_IF_GT) && (x > xth && y > yth)) ||
986  ((relation == L_SELECT_IF_LTE) && (x <= xth && y <= yth)) ||
987  ((relation == L_SELECT_IF_GTE) && (x >= xth && y >= yth)))
988  ptaAddPt(ptad, x, y);
989  }
990  }
991 
992  return ptad;
993 }
994 
995 
1003 PTA *
1005  PIX *pixm)
1006 {
1007 l_int32 i, n, x, y;
1008 l_uint32 val;
1009 PTA *ptad;
1010 
1011  if (!ptas)
1012  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
1013  if (!pixm || pixGetDepth(pixm) != 1)
1014  return (PTA *)ERROR_PTR("pixm undefined or not 1 bpp", __func__, NULL);
1015  if (ptaGetCount(ptas) == 0) {
1016  L_INFO("ptas is empty\n", __func__);
1017  return ptaCopy(ptas);
1018  }
1019 
1020  n = ptaGetCount(ptas);
1021  ptad = ptaCreate(n);
1022  for (i = 0; i < n; i++) {
1023  ptaGetIPt(ptas, i, &x, &y);
1024  pixGetPixel(pixm, x, y, &val);
1025  if (val == 1)
1026  ptaAddPt(ptad, x, y);
1027  }
1028  return ptad;
1029 }
1030 
1031 
1032 /*---------------------------------------------------------------------*
1033  * Least Squares Fit *
1034  *---------------------------------------------------------------------*/
1068 l_ok
1070  l_float32 *pa,
1071  l_float32 *pb,
1072  NUMA **pnafit)
1073 {
1074 l_int32 n, i;
1075 l_float32 a, b, factor, sx, sy, sxx, sxy, val;
1076 l_float32 *xa, *ya;
1077 
1078  if (pa) *pa = 0.0;
1079  if (pb) *pb = 0.0;
1080  if (pnafit) *pnafit = NULL;
1081  if (!pa && !pb && !pnafit)
1082  return ERROR_INT("no output requested", __func__, 1);
1083  if (!pta)
1084  return ERROR_INT("pta not defined", __func__, 1);
1085  if ((n = ptaGetCount(pta)) < 2)
1086  return ERROR_INT("less than 2 pts found", __func__, 1);
1087 
1088  xa = pta->x; /* not a copy */
1089  ya = pta->y; /* not a copy */
1090  sx = sy = sxx = sxy = 0.;
1091  if (pa && pb) { /* general line */
1092  for (i = 0; i < n; i++) {
1093  sx += xa[i];
1094  sy += ya[i];
1095  sxx += xa[i] * xa[i];
1096  sxy += xa[i] * ya[i];
1097  }
1098  factor = n * sxx - sx * sx;
1099  if (factor == 0.0)
1100  return ERROR_INT("no solution found", __func__, 1);
1101  factor = 1. / factor;
1102 
1103  a = factor * ((l_float32)n * sxy - sx * sy);
1104  b = factor * (sxx * sy - sx * sxy);
1105  } else if (pa) { /* b = 0; line through origin */
1106  for (i = 0; i < n; i++) {
1107  sxx += xa[i] * xa[i];
1108  sxy += xa[i] * ya[i];
1109  }
1110  if (sxx == 0.0)
1111  return ERROR_INT("no solution found", __func__, 1);
1112  a = sxy / sxx;
1113  b = 0.0;
1114  } else { /* a = 0; horizontal line */
1115  for (i = 0; i < n; i++)
1116  sy += ya[i];
1117  a = 0.0;
1118  b = sy / (l_float32)n;
1119  }
1120 
1121  if (pnafit) {
1122  *pnafit = numaCreate(n);
1123  for (i = 0; i < n; i++) {
1124  val = a * xa[i] + b;
1125  numaAddNumber(*pnafit, val);
1126  }
1127  }
1128 
1129  if (pa) *pa = a;
1130  if (pb) *pb = b;
1131  return 0;
1132 }
1133 
1134 
1167 l_ok
1169  l_float32 *pa,
1170  l_float32 *pb,
1171  l_float32 *pc,
1172  NUMA **pnafit)
1173 {
1174 l_int32 n, i, ret;
1175 l_float32 x, y, sx, sy, sx2, sx3, sx4, sxy, sx2y;
1176 l_float32 *xa, *ya;
1177 l_float32 *f[3];
1178 l_float32 g[3];
1179 
1180  if (pa) *pa = 0.0;
1181  if (pb) *pb = 0.0;
1182  if (pc) *pc = 0.0;
1183  if (pnafit) *pnafit = NULL;
1184  if (!pa && !pb && !pc && !pnafit)
1185  return ERROR_INT("no output requested", __func__, 1);
1186  if (!pta)
1187  return ERROR_INT("pta not defined", __func__, 1);
1188  if ((n = ptaGetCount(pta)) < 3)
1189  return ERROR_INT("less than 3 pts found", __func__, 1);
1190 
1191  xa = pta->x; /* not a copy */
1192  ya = pta->y; /* not a copy */
1193  sx = sy = sx2 = sx3 = sx4 = sxy = sx2y = 0.;
1194  for (i = 0; i < n; i++) {
1195  x = xa[i];
1196  y = ya[i];
1197  sx += x;
1198  sy += y;
1199  sx2 += x * x;
1200  sx3 += x * x * x;
1201  sx4 += x * x * x * x;
1202  sxy += x * y;
1203  sx2y += x * x * y;
1204  }
1205 
1206  for (i = 0; i < 3; i++)
1207  f[i] = (l_float32 *)LEPT_CALLOC(3, sizeof(l_float32));
1208  f[0][0] = sx4;
1209  f[0][1] = sx3;
1210  f[0][2] = sx2;
1211  f[1][0] = sx3;
1212  f[1][1] = sx2;
1213  f[1][2] = sx;
1214  f[2][0] = sx2;
1215  f[2][1] = sx;
1216  f[2][2] = n;
1217  g[0] = sx2y;
1218  g[1] = sxy;
1219  g[2] = sy;
1220 
1221  /* Solve for the unknowns, also putting f-inverse into f */
1222  ret = gaussjordan(f, g, 3);
1223  for (i = 0; i < 3; i++)
1224  LEPT_FREE(f[i]);
1225  if (ret)
1226  return ERROR_INT("quadratic solution failed", __func__, 1);
1227 
1228  if (pa) *pa = g[0];
1229  if (pb) *pb = g[1];
1230  if (pc) *pc = g[2];
1231  if (pnafit) {
1232  *pnafit = numaCreate(n);
1233  for (i = 0; i < n; i++) {
1234  x = xa[i];
1235  y = g[0] * x * x + g[1] * x + g[2];
1236  numaAddNumber(*pnafit, y);
1237  }
1238  }
1239  return 0;
1240 }
1241 
1242 
1278 l_ok
1280  l_float32 *pa,
1281  l_float32 *pb,
1282  l_float32 *pc,
1283  l_float32 *pd,
1284  NUMA **pnafit)
1285 {
1286 l_int32 n, i, ret;
1287 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sxy, sx2y, sx3y;
1288 l_float32 *xa, *ya;
1289 l_float32 *f[4];
1290 l_float32 g[4];
1291 
1292  if (pa) *pa = 0.0;
1293  if (pb) *pb = 0.0;
1294  if (pc) *pc = 0.0;
1295  if (pd) *pd = 0.0;
1296  if (pnafit) *pnafit = NULL;
1297  if (!pa && !pb && !pc && !pd && !pnafit)
1298  return ERROR_INT("no output requested", __func__, 1);
1299  if (!pta)
1300  return ERROR_INT("pta not defined", __func__, 1);
1301  if ((n = ptaGetCount(pta)) < 4)
1302  return ERROR_INT("less than 4 pts found", __func__, 1);
1303 
1304  xa = pta->x; /* not a copy */
1305  ya = pta->y; /* not a copy */
1306  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sxy = sx2y = sx3y = 0.;
1307  for (i = 0; i < n; i++) {
1308  x = xa[i];
1309  y = ya[i];
1310  sx += x;
1311  sy += y;
1312  sx2 += x * x;
1313  sx3 += x * x * x;
1314  sx4 += x * x * x * x;
1315  sx5 += x * x * x * x * x;
1316  sx6 += x * x * x * x * x * x;
1317  sxy += x * y;
1318  sx2y += x * x * y;
1319  sx3y += x * x * x * y;
1320  }
1321 
1322  for (i = 0; i < 4; i++)
1323  f[i] = (l_float32 *)LEPT_CALLOC(4, sizeof(l_float32));
1324  f[0][0] = sx6;
1325  f[0][1] = sx5;
1326  f[0][2] = sx4;
1327  f[0][3] = sx3;
1328  f[1][0] = sx5;
1329  f[1][1] = sx4;
1330  f[1][2] = sx3;
1331  f[1][3] = sx2;
1332  f[2][0] = sx4;
1333  f[2][1] = sx3;
1334  f[2][2] = sx2;
1335  f[2][3] = sx;
1336  f[3][0] = sx3;
1337  f[3][1] = sx2;
1338  f[3][2] = sx;
1339  f[3][3] = n;
1340  g[0] = sx3y;
1341  g[1] = sx2y;
1342  g[2] = sxy;
1343  g[3] = sy;
1344 
1345  /* Solve for the unknowns, also putting f-inverse into f */
1346  ret = gaussjordan(f, g, 4);
1347  for (i = 0; i < 4; i++)
1348  LEPT_FREE(f[i]);
1349  if (ret)
1350  return ERROR_INT("cubic solution failed", __func__, 1);
1351 
1352  if (pa) *pa = g[0];
1353  if (pb) *pb = g[1];
1354  if (pc) *pc = g[2];
1355  if (pd) *pd = g[3];
1356  if (pnafit) {
1357  *pnafit = numaCreate(n);
1358  for (i = 0; i < n; i++) {
1359  x = xa[i];
1360  y = g[0] * x * x * x + g[1] * x * x + g[2] * x + g[3];
1361  numaAddNumber(*pnafit, y);
1362  }
1363  }
1364  return 0;
1365 }
1366 
1367 
1406 l_ok
1408  l_float32 *pa,
1409  l_float32 *pb,
1410  l_float32 *pc,
1411  l_float32 *pd,
1412  l_float32 *pe,
1413  NUMA **pnafit)
1414 {
1415 l_int32 n, i, ret;
1416 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sx7, sx8;
1417 l_float32 sxy, sx2y, sx3y, sx4y;
1418 l_float32 *xa, *ya;
1419 l_float32 *f[5];
1420 l_float32 g[5];
1421 
1422  if (pa) *pa = 0.0;
1423  if (pb) *pb = 0.0;
1424  if (pc) *pc = 0.0;
1425  if (pd) *pd = 0.0;
1426  if (pe) *pe = 0.0;
1427  if (pnafit) *pnafit = NULL;
1428  if (!pa && !pb && !pc && !pd && !pe && !pnafit)
1429  return ERROR_INT("no output requested", __func__, 1);
1430  if (!pta)
1431  return ERROR_INT("pta not defined", __func__, 1);
1432  if ((n = ptaGetCount(pta)) < 5)
1433  return ERROR_INT("less than 5 pts found", __func__, 1);
1434 
1435  xa = pta->x; /* not a copy */
1436  ya = pta->y; /* not a copy */
1437  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sx7 = sx8 = 0;
1438  sxy = sx2y = sx3y = sx4y = 0.;
1439  for (i = 0; i < n; i++) {
1440  x = xa[i];
1441  y = ya[i];
1442  sx += x;
1443  sy += y;
1444  sx2 += x * x;
1445  sx3 += x * x * x;
1446  sx4 += x * x * x * x;
1447  sx5 += x * x * x * x * x;
1448  sx6 += x * x * x * x * x * x;
1449  sx7 += x * x * x * x * x * x * x;
1450  sx8 += x * x * x * x * x * x * x * x;
1451  sxy += x * y;
1452  sx2y += x * x * y;
1453  sx3y += x * x * x * y;
1454  sx4y += x * x * x * x * y;
1455  }
1456 
1457  for (i = 0; i < 5; i++)
1458  f[i] = (l_float32 *)LEPT_CALLOC(5, sizeof(l_float32));
1459  f[0][0] = sx8;
1460  f[0][1] = sx7;
1461  f[0][2] = sx6;
1462  f[0][3] = sx5;
1463  f[0][4] = sx4;
1464  f[1][0] = sx7;
1465  f[1][1] = sx6;
1466  f[1][2] = sx5;
1467  f[1][3] = sx4;
1468  f[1][4] = sx3;
1469  f[2][0] = sx6;
1470  f[2][1] = sx5;
1471  f[2][2] = sx4;
1472  f[2][3] = sx3;
1473  f[2][4] = sx2;
1474  f[3][0] = sx5;
1475  f[3][1] = sx4;
1476  f[3][2] = sx3;
1477  f[3][3] = sx2;
1478  f[3][4] = sx;
1479  f[4][0] = sx4;
1480  f[4][1] = sx3;
1481  f[4][2] = sx2;
1482  f[4][3] = sx;
1483  f[4][4] = n;
1484  g[0] = sx4y;
1485  g[1] = sx3y;
1486  g[2] = sx2y;
1487  g[3] = sxy;
1488  g[4] = sy;
1489 
1490  /* Solve for the unknowns, also putting f-inverse into f */
1491  ret = gaussjordan(f, g, 5);
1492  for (i = 0; i < 5; i++)
1493  LEPT_FREE(f[i]);
1494  if (ret)
1495  return ERROR_INT("quartic solution failed", __func__, 1);
1496 
1497  if (pa) *pa = g[0];
1498  if (pb) *pb = g[1];
1499  if (pc) *pc = g[2];
1500  if (pd) *pd = g[3];
1501  if (pe) *pe = g[4];
1502  if (pnafit) {
1503  *pnafit = numaCreate(n);
1504  for (i = 0; i < n; i++) {
1505  x = xa[i];
1506  y = g[0] * x * x * x * x + g[1] * x * x * x + g[2] * x * x
1507  + g[3] * x + g[4];
1508  numaAddNumber(*pnafit, y);
1509  }
1510  }
1511  return 0;
1512 }
1513 
1514 
1540 l_ok
1542  l_float32 factor,
1543  PTA **pptad,
1544  l_float32 *pa,
1545  l_float32 *pb,
1546  l_float32 *pmederr,
1547  NUMA **pnafit)
1548 {
1549 l_int32 n, i, ret;
1550 l_float32 x, y, yf, val, mederr;
1551 NUMA *nafit, *naerror;
1552 PTA *ptad;
1553 
1554  if (pptad) *pptad = NULL;
1555  if (pa) *pa = 0.0;
1556  if (pb) *pb = 0.0;
1557  if (pmederr) *pmederr = 0.0;
1558  if (pnafit) *pnafit = NULL;
1559  if (!pptad && !pa && !pb && !pnafit)
1560  return ERROR_INT("no output requested", __func__, 1);
1561  if (!pta)
1562  return ERROR_INT("pta not defined", __func__, 1);
1563  if (factor <= 0.0)
1564  return ERROR_INT("factor must be > 0.0", __func__, 1);
1565  if ((n = ptaGetCount(pta)) < 3)
1566  return ERROR_INT("less than 2 pts found", __func__, 1);
1567 
1568  if (ptaGetLinearLSF(pta, pa, pb, &nafit) != 0)
1569  return ERROR_INT("error in linear LSF", __func__, 1);
1570 
1571  /* Get the median error */
1572  naerror = numaCreate(n);
1573  for (i = 0; i < n; i++) {
1574  ptaGetPt(pta, i, &x, &y);
1575  numaGetFValue(nafit, i, &yf);
1576  numaAddNumber(naerror, L_ABS(y - yf));
1577  }
1578  numaGetMedian(naerror, &mederr);
1579  if (pmederr) *pmederr = mederr;
1580  numaDestroy(&nafit);
1581 
1582  /* Remove outliers */
1583  ptad = ptaCreate(n);
1584  for (i = 0; i < n; i++) {
1585  ptaGetPt(pta, i, &x, &y);
1586  numaGetFValue(naerror, i, &val);
1587  if (val <= factor * mederr) /* <= in case mederr = 0 */
1588  ptaAddPt(ptad, x, y);
1589  }
1590  numaDestroy(&naerror);
1591 
1592  /* Do LSF again */
1593  ret = ptaGetLinearLSF(ptad, pa, pb, pnafit);
1594  if (pptad)
1595  *pptad = ptad;
1596  else
1597  ptaDestroy(&ptad);
1598 
1599  return ret;
1600 }
1601 
1602 
1625 l_ok
1627  l_float32 factor,
1628  PTA **pptad,
1629  l_float32 *pa,
1630  l_float32 *pb,
1631  l_float32 *pc,
1632  l_float32 *pmederr,
1633  NUMA **pnafit)
1634 {
1635 l_int32 n, i, ret;
1636 l_float32 x, y, yf, val, mederr;
1637 NUMA *nafit, *naerror;
1638 PTA *ptad;
1639 
1640  if (pptad) *pptad = NULL;
1641  if (pa) *pa = 0.0;
1642  if (pb) *pb = 0.0;
1643  if (pc) *pc = 0.0;
1644  if (pmederr) *pmederr = 0.0;
1645  if (pnafit) *pnafit = NULL;
1646  if (!pptad && !pa && !pb && !pc && !pnafit)
1647  return ERROR_INT("no output requested", __func__, 1);
1648  if (factor <= 0.0)
1649  return ERROR_INT("factor must be > 0.0", __func__, 1);
1650  if (!pta)
1651  return ERROR_INT("pta not defined", __func__, 1);
1652  if ((n = ptaGetCount(pta)) < 3)
1653  return ERROR_INT("less than 3 pts found", __func__, 1);
1654 
1655  if (ptaGetQuadraticLSF(pta, NULL, NULL, NULL, &nafit) != 0)
1656  return ERROR_INT("error in quadratic LSF", __func__, 1);
1657 
1658  /* Get the median error */
1659  naerror = numaCreate(n);
1660  for (i = 0; i < n; i++) {
1661  ptaGetPt(pta, i, &x, &y);
1662  numaGetFValue(nafit, i, &yf);
1663  numaAddNumber(naerror, L_ABS(y - yf));
1664  }
1665  numaGetMedian(naerror, &mederr);
1666  if (pmederr) *pmederr = mederr;
1667  numaDestroy(&nafit);
1668 
1669  /* Remove outliers */
1670  ptad = ptaCreate(n);
1671  for (i = 0; i < n; i++) {
1672  ptaGetPt(pta, i, &x, &y);
1673  numaGetFValue(naerror, i, &val);
1674  if (val <= factor * mederr) /* <= in case mederr = 0 */
1675  ptaAddPt(ptad, x, y);
1676  }
1677  numaDestroy(&naerror);
1678  n = ptaGetCount(ptad);
1679  if ((n = ptaGetCount(ptad)) < 3) {
1680  ptaDestroy(&ptad);
1681  return ERROR_INT("less than 3 pts found", __func__, 1);
1682  }
1683 
1684  /* Do LSF again */
1685  ret = ptaGetQuadraticLSF(ptad, pa, pb, pc, pnafit);
1686  if (pptad)
1687  *pptad = ptad;
1688  else
1689  ptaDestroy(&ptad);
1690 
1691  return ret;
1692 }
1693 
1694 
1703 l_ok
1704 applyLinearFit(l_float32 a,
1705  l_float32 b,
1706  l_float32 x,
1707  l_float32 *py)
1708 {
1709  if (!py)
1710  return ERROR_INT("&y not defined", __func__, 1);
1711 
1712  *py = a * x + b;
1713  return 0;
1714 }
1715 
1716 
1725 l_ok
1726 applyQuadraticFit(l_float32 a,
1727  l_float32 b,
1728  l_float32 c,
1729  l_float32 x,
1730  l_float32 *py)
1731 {
1732  if (!py)
1733  return ERROR_INT("&y not defined", __func__, 1);
1734 
1735  *py = a * x * x + b * x + c;
1736  return 0;
1737 }
1738 
1739 
1748 l_ok
1749 applyCubicFit(l_float32 a,
1750  l_float32 b,
1751  l_float32 c,
1752  l_float32 d,
1753  l_float32 x,
1754  l_float32 *py)
1755 {
1756  if (!py)
1757  return ERROR_INT("&y not defined", __func__, 1);
1758 
1759  *py = a * x * x * x + b * x * x + c * x + d;
1760  return 0;
1761 }
1762 
1763 
1772 l_ok
1773 applyQuarticFit(l_float32 a,
1774  l_float32 b,
1775  l_float32 c,
1776  l_float32 d,
1777  l_float32 e,
1778  l_float32 x,
1779  l_float32 *py)
1780 {
1781 l_float32 x2;
1782 
1783  if (!py)
1784  return ERROR_INT("&y not defined", __func__, 1);
1785 
1786  x2 = x * x;
1787  *py = a * x2 * x2 + b * x2 * x + c * x2 + d * x + e;
1788  return 0;
1789 }
1790 
1791 
1792 /*---------------------------------------------------------------------*
1793  * Interconversions with Pix *
1794  *---------------------------------------------------------------------*/
1811 l_ok
1813  PTA *pta,
1814  l_int32 outformat,
1815  const char *title)
1816 {
1817 char buffer[128];
1818 char *rtitle, *gtitle, *btitle;
1819 static l_int32 count = 0; /* require separate temp files for each call */
1820 l_int32 i, x, y, d, w, h, npts, rval, gval, bval;
1821 l_uint32 val;
1822 NUMA *na, *nar, *nag, *nab;
1823 PIX *pixt;
1824 
1825  lept_mkdir("lept/plot");
1826 
1827  if (!pixs)
1828  return ERROR_INT("pixs not defined", __func__, 1);
1829  if (!pta)
1830  return ERROR_INT("pta not defined", __func__, 1);
1831  if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
1832  outformat != GPLOT_EPS && outformat != GPLOT_LATEX) {
1833  L_WARNING("outformat invalid; using GPLOT_PNG\n", __func__);
1834  outformat = GPLOT_PNG;
1835  }
1836 
1838  d = pixGetDepth(pixt);
1839  w = pixGetWidth(pixt);
1840  h = pixGetHeight(pixt);
1841  npts = ptaGetCount(pta);
1842  if (d == 32) {
1843  nar = numaCreate(npts);
1844  nag = numaCreate(npts);
1845  nab = numaCreate(npts);
1846  for (i = 0; i < npts; i++) {
1847  ptaGetIPt(pta, i, &x, &y);
1848  if (x < 0 || x >= w)
1849  continue;
1850  if (y < 0 || y >= h)
1851  continue;
1852  pixGetPixel(pixt, x, y, &val);
1853  rval = GET_DATA_BYTE(&val, COLOR_RED);
1854  gval = GET_DATA_BYTE(&val, COLOR_GREEN);
1855  bval = GET_DATA_BYTE(&val, COLOR_BLUE);
1856  numaAddNumber(nar, rval);
1857  numaAddNumber(nag, gval);
1858  numaAddNumber(nab, bval);
1859  }
1860 
1861  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1862  rtitle = stringJoin("Red: ", title);
1863  gplotSimple1(nar, outformat, buffer, rtitle);
1864  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1865  gtitle = stringJoin("Green: ", title);
1866  gplotSimple1(nag, outformat, buffer, gtitle);
1867  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1868  btitle = stringJoin("Blue: ", title);
1869  gplotSimple1(nab, outformat, buffer, btitle);
1870  numaDestroy(&nar);
1871  numaDestroy(&nag);
1872  numaDestroy(&nab);
1873  LEPT_FREE(rtitle);
1874  LEPT_FREE(gtitle);
1875  LEPT_FREE(btitle);
1876  } else {
1877  na = numaCreate(npts);
1878  for (i = 0; i < npts; i++) {
1879  ptaGetIPt(pta, i, &x, &y);
1880  if (x < 0 || x >= w)
1881  continue;
1882  if (y < 0 || y >= h)
1883  continue;
1884  pixGetPixel(pixt, x, y, &val);
1885  numaAddNumber(na, (l_float32)val);
1886  }
1887 
1888  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1889  gplotSimple1(na, outformat, buffer, title);
1890  numaDestroy(&na);
1891  }
1892  pixDestroy(&pixt);
1893  return 0;
1894 }
1895 
1896 
1910 PTA *
1912  BOX *box)
1913 {
1914 l_int32 i, j, w, h, wpl, xstart, xend, ystart, yend, bw, bh;
1915 l_uint32 *data, *line;
1916 PTA *pta;
1917 
1918  if (!pixs || (pixGetDepth(pixs) != 1))
1919  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
1920 
1921  pixGetDimensions(pixs, &w, &h, NULL);
1922  data = pixGetData(pixs);
1923  wpl = pixGetWpl(pixs);
1924  xstart = ystart = 0;
1925  xend = w - 1;
1926  yend = h - 1;
1927  if (box) {
1928  boxGetGeometry(box, &xstart, &ystart, &bw, &bh);
1929  xend = xstart + bw - 1;
1930  yend = ystart + bh - 1;
1931  }
1932 
1933  if ((pta = ptaCreate(0)) == NULL)
1934  return (PTA *)ERROR_PTR("pta not made", __func__, NULL);
1935  for (i = ystart; i <= yend; i++) {
1936  line = data + i * wpl;
1937  for (j = xstart; j <= xend; j++) {
1938  if (GET_DATA_BIT(line, j))
1939  ptaAddPt(pta, j, i);
1940  }
1941  }
1942 
1943  return pta;
1944 }
1945 
1946 
1961 PIX *
1963  l_int32 w,
1964  l_int32 h)
1965 {
1966 l_int32 n, i, x, y;
1967 PIX *pix;
1968 
1969  if (!pta)
1970  return (PIX *)ERROR_PTR("pta not defined", __func__, NULL);
1971 
1972  if ((pix = pixCreate(w, h, 1)) == NULL)
1973  return (PIX *)ERROR_PTR("pix not made", __func__, NULL);
1974  n = ptaGetCount(pta);
1975  for (i = 0; i < n; i++) {
1976  ptaGetIPt(pta, i, &x, &y);
1977  if (x < 0 || x >= w || y < 0 || y >= h)
1978  continue;
1979  pixSetPixel(pix, x, y, 1);
1980  }
1981 
1982  return pix;
1983 }
1984 
1985 
2000 PTA *
2002  l_int32 type)
2003 {
2004 PIX *pixt;
2005 PTA *pta;
2006 
2007  if (!pixs || (pixGetDepth(pixs) != 1))
2008  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
2009  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2010  return (PTA *)ERROR_PTR("invalid type", __func__, NULL);
2011 
2012  if (type == L_BOUNDARY_FG)
2013  pixt = pixMorphSequence(pixs, "e3.3", 0);
2014  else
2015  pixt = pixMorphSequence(pixs, "d3.3", 0);
2016  pixXor(pixt, pixt, pixs);
2017  pta = ptaGetPixelsFromPix(pixt, NULL);
2018 
2019  pixDestroy(&pixt);
2020  return pta;
2021 }
2022 
2023 
2047 PTAA *
2049  l_int32 type,
2050  l_int32 connectivity,
2051  BOXA **pboxa,
2052  PIXA **ppixa)
2053 {
2054 l_int32 i, n, w, h, x, y, bw, bh, left, right, top, bot;
2055 BOXA *boxa;
2056 PIX *pixt1, *pixt2;
2057 PIXA *pixa;
2058 PTA *pta1, *pta2;
2059 PTAA *ptaa;
2060 
2061  if (pboxa) *pboxa = NULL;
2062  if (ppixa) *ppixa = NULL;
2063  if (!pixs || (pixGetDepth(pixs) != 1))
2064  return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
2065  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2066  return (PTAA *)ERROR_PTR("invalid type", __func__, NULL);
2067  if (connectivity != 4 && connectivity != 8)
2068  return (PTAA *)ERROR_PTR("connectivity not 4 or 8", __func__, NULL);
2069 
2070  pixGetDimensions(pixs, &w, &h, NULL);
2071  boxa = pixConnComp(pixs, &pixa, connectivity);
2072  n = boxaGetCount(boxa);
2073  ptaa = ptaaCreate(0);
2074  for (i = 0; i < n; i++) {
2075  pixt1 = pixaGetPix(pixa, i, L_CLONE);
2076  boxaGetBoxGeometry(boxa, i, &x, &y, &bw, &bh);
2077  left = right = top = bot = 0;
2078  if (type == L_BOUNDARY_BG) {
2079  if (x > 0) left = 1;
2080  if (y > 0) top = 1;
2081  if (x + bw < w) right = 1;
2082  if (y + bh < h) bot = 1;
2083  pixt2 = pixAddBorderGeneral(pixt1, left, right, top, bot, 0);
2084  } else {
2085  pixt2 = pixClone(pixt1);
2086  }
2087  pta1 = ptaGetBoundaryPixels(pixt2, type);
2088  pta2 = ptaTransform(pta1, x - left, y - top, 1.0, 1.0);
2089  ptaaAddPta(ptaa, pta2, L_INSERT);
2090  ptaDestroy(&pta1);
2091  pixDestroy(&pixt1);
2092  pixDestroy(&pixt2);
2093  }
2094 
2095  if (pboxa)
2096  *pboxa = boxa;
2097  else
2098  boxaDestroy(&boxa);
2099  if (ppixa)
2100  *ppixa = pixa;
2101  else
2102  pixaDestroy(&pixa);
2103  return ptaa;
2104 }
2105 
2106 
2128 PTAA *
2130  l_int32 *pncc)
2131 {
2132 l_int32 wpl, index, i, j, w, h;
2133 l_uint32 maxval;
2134 l_uint32 *data, *line;
2135 PTA *pta;
2136 PTAA *ptaa;
2137 
2138  if (pncc) *pncc = 0;
2139  if (!pixs || (pixGetDepth(pixs) != 32))
2140  return (PTAA *)ERROR_PTR("pixs undef or not 32 bpp", __func__, NULL);
2141 
2142  /* The number of c.c. is the maximum pixel value. Use this to
2143  * initialize ptaa with sufficient pta arrays */
2144  pixGetMaxValueInRect(pixs, NULL, &maxval, NULL, NULL);
2145  if (pncc) *pncc = maxval;
2146  pta = ptaCreate(1);
2147  ptaa = ptaaCreate(maxval + 1);
2148  ptaaInitFull(ptaa, pta);
2149  ptaDestroy(&pta);
2150 
2151  /* Sweep over %pixs, saving the pixel coordinates of each pixel
2152  * with nonzero value in the appropriate pta, indexed by that value. */
2153  pixGetDimensions(pixs, &w, &h, NULL);
2154  data = pixGetData(pixs);
2155  wpl = pixGetWpl(pixs);
2156  for (i = 0; i < h; i++) {
2157  line = data + wpl * i;
2158  for (j = 0; j < w; j++) {
2159  index = line[j];
2160  if (index > 0)
2161  ptaaAddPt(ptaa, index, j, i);
2162  }
2163  }
2164 
2165  return ptaa;
2166 }
2167 
2168 
2183 PTA *
2185  l_int32 x,
2186  l_int32 y,
2187  l_int32 conn)
2188 {
2189 l_int32 w, h;
2190 PTA *pta;
2191 
2192  if (!pixs)
2193  return (PTA *)ERROR_PTR("pixs not defined", __func__, NULL);
2194  pixGetDimensions(pixs, &w, &h, NULL);
2195  if (x < 0 || x >= w || y < 0 || y >= h)
2196  return (PTA *)ERROR_PTR("(x,y) not in pixs", __func__, NULL);
2197  if (conn != 4 && conn != 8)
2198  return (PTA *)ERROR_PTR("conn not 4 or 8", __func__, NULL);
2199 
2200  pta = ptaCreate(conn);
2201  if (x > 0)
2202  ptaAddPt(pta, x - 1, y);
2203  if (x < w - 1)
2204  ptaAddPt(pta, x + 1, y);
2205  if (y > 0)
2206  ptaAddPt(pta, x, y - 1);
2207  if (y < h - 1)
2208  ptaAddPt(pta, x, y + 1);
2209  if (conn == 8) {
2210  if (x > 0) {
2211  if (y > 0)
2212  ptaAddPt(pta, x - 1, y - 1);
2213  if (y < h - 1)
2214  ptaAddPt(pta, x - 1, y + 1);
2215  }
2216  if (x < w - 1) {
2217  if (y > 0)
2218  ptaAddPt(pta, x + 1, y - 1);
2219  if (y < h - 1)
2220  ptaAddPt(pta, x + 1, y + 1);
2221  }
2222  }
2223 
2224  return pta;
2225 }
2226 
2227 
2228 /*---------------------------------------------------------------------*
2229  * Interconversion with Numa *
2230  *---------------------------------------------------------------------*/
2237 PTA *
2239 {
2240 l_int32 i, n;
2241 l_float32 startx, delx, val;
2242 PTA *pta;
2243 
2244  if (!na)
2245  return (PTA *)ERROR_PTR("na not defined", __func__, NULL);
2246 
2247  n = numaGetCount(na);
2248  pta = ptaCreate(n);
2249  numaGetParameters(na, &startx, &delx);
2250  for (i = 0; i < n; i++) {
2251  numaGetFValue(na, i, &val);
2252  ptaAddPt(pta, startx + i * delx, val);
2253  }
2254  return pta;
2255 }
2256 
2257 
2265 PTA *
2267  NUMA *nay)
2268 {
2269 l_int32 i, n, nx, ny;
2270 l_float32 valx, valy;
2271 PTA *pta;
2272 
2273  if (!nax || !nay)
2274  return (PTA *)ERROR_PTR("nax and nay not both defined", __func__, NULL);
2275 
2276  nx = numaGetCount(nax);
2277  ny = numaGetCount(nay);
2278  n = L_MIN(nx, ny);
2279  if (nx != ny)
2280  L_WARNING("nx = %d does not equal ny = %d\n", __func__, nx, ny);
2281  pta = ptaCreate(n);
2282  for (i = 0; i < n; i++) {
2283  numaGetFValue(nax, i, &valx);
2284  numaGetFValue(nay, i, &valy);
2285  ptaAddPt(pta, valx, valy);
2286  }
2287  return pta;
2288 }
2289 
2290 
2299 l_ok
2301  NUMA **pnax,
2302  NUMA **pnay)
2303 {
2304 l_int32 i, n;
2305 l_float32 valx, valy;
2306 
2307  if (pnax) *pnax = NULL;
2308  if (pnay) *pnay = NULL;
2309  if (!pnax || !pnay)
2310  return ERROR_INT("&nax and &nay not both defined", __func__, 1);
2311  if (!pta)
2312  return ERROR_INT("pta not defined", __func__, 1);
2313 
2314  n = ptaGetCount(pta);
2315  *pnax = numaCreate(n);
2316  *pnay = numaCreate(n);
2317  for (i = 0; i < n; i++) {
2318  ptaGetPt(pta, i, &valx, &valy);
2319  numaAddNumber(*pnax, valx);
2320  numaAddNumber(*pnay, valy);
2321  }
2322  return 0;
2323 }
2324 
2325 
2326 /*---------------------------------------------------------------------*
2327  * Display Pta and Ptaa *
2328  *---------------------------------------------------------------------*/
2348 PIX *
2350  PIX *pixs,
2351  PTA *pta)
2352 {
2353 l_int32 i, n, w, h, x, y;
2354 l_uint32 rpixel, gpixel, bpixel;
2355 
2356  if (!pixs)
2357  return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
2358  if (!pta)
2359  return (PIX *)ERROR_PTR("pta not defined", __func__, pixd);
2360  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2361  return (PIX *)ERROR_PTR("invalid pixd", __func__, pixd);
2362 
2363  if (!pixd)
2364  pixd = pixConvertTo32(pixs);
2365  pixGetDimensions(pixd, &w, &h, NULL);
2366  composeRGBPixel(255, 0, 0, &rpixel); /* start point */
2367  composeRGBPixel(0, 255, 0, &gpixel);
2368  composeRGBPixel(0, 0, 255, &bpixel); /* end point */
2369 
2370  n = ptaGetCount(pta);
2371  for (i = 0; i < n; i++) {
2372  ptaGetIPt(pta, i, &x, &y);
2373  if (x < 0 || x >= w || y < 0 || y >= h)
2374  continue;
2375  if (i == 0)
2376  pixSetPixel(pixd, x, y, rpixel);
2377  else if (i < n - 1)
2378  pixSetPixel(pixd, x, y, gpixel);
2379  else
2380  pixSetPixel(pixd, x, y, bpixel);
2381  }
2382 
2383  return pixd;
2384 }
2385 
2386 
2412 PIX *
2414  PIX *pixs,
2415  PTAA *ptaa,
2416  PIX *pixp,
2417  l_int32 cx,
2418  l_int32 cy)
2419 {
2420 l_int32 i, n;
2421 l_uint32 color;
2422 PIXCMAP *cmap;
2423 PTA *pta;
2424 
2425  if (!pixs)
2426  return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
2427  if (!ptaa)
2428  return (PIX *)ERROR_PTR("ptaa not defined", __func__, pixd);
2429  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2430  return (PIX *)ERROR_PTR("invalid pixd", __func__, pixd);
2431  if (!pixp)
2432  return (PIX *)ERROR_PTR("pixp not defined", __func__, pixd);
2433 
2434  if (!pixd)
2435  pixd = pixConvertTo32(pixs);
2436 
2437  /* Use 256 random colors */
2438  cmap = pixcmapCreateRandom(8, 0, 0);
2439  n = ptaaGetCount(ptaa);
2440  for (i = 0; i < n; i++) {
2441  pixcmapGetColor32(cmap, i % 256, &color);
2442  pta = ptaaGetPta(ptaa, i, L_CLONE);
2443  pixDisplayPtaPattern(pixd, pixd, pta, pixp, cx, cy, color);
2444  ptaDestroy(&pta);
2445  }
2446 
2447  pixcmapDestroy(&cmap);
2448  return pixd;
2449 }
2450 
2451 
2477 PIX *
2479  PIX *pixs,
2480  PTA *pta,
2481  PIX *pixp,
2482  l_int32 cx,
2483  l_int32 cy,
2484  l_uint32 color)
2485 {
2486 l_int32 i, n, w, h, x, y;
2487 PTA *ptat;
2488 
2489  if (!pixs)
2490  return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
2491  if (!pta)
2492  return (PIX *)ERROR_PTR("pta not defined", __func__, pixd);
2493  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2494  return (PIX *)ERROR_PTR("invalid pixd", __func__, pixd);
2495  if (!pixp)
2496  return (PIX *)ERROR_PTR("pixp not defined", __func__, pixd);
2497 
2498  if (!pixd)
2499  pixd = pixConvertTo32(pixs);
2500  pixGetDimensions(pixs, &w, &h, NULL);
2501  ptat = ptaReplicatePattern(pta, pixp, NULL, cx, cy, w, h);
2502 
2503  n = ptaGetCount(ptat);
2504  for (i = 0; i < n; i++) {
2505  ptaGetIPt(ptat, i, &x, &y);
2506  if (x < 0 || x >= w || y < 0 || y >= h)
2507  continue;
2508  pixSetPixel(pixd, x, y, color);
2509  }
2510 
2511  ptaDestroy(&ptat);
2512  return pixd;
2513 }
2514 
2515 
2536 PTA *
2538  PIX *pixp,
2539  PTA *ptap,
2540  l_int32 cx,
2541  l_int32 cy,
2542  l_int32 w,
2543  l_int32 h)
2544 {
2545 l_int32 i, j, n, np, x, y, xp, yp, xf, yf;
2546 PTA *ptat, *ptad;
2547 
2548  if (!ptas)
2549  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
2550  if (!pixp && !ptap)
2551  return (PTA *)ERROR_PTR("no pattern is defined", __func__, NULL);
2552  if (pixp && ptap)
2553  L_WARNING("pixp and ptap defined; using ptap\n", __func__);
2554 
2555  n = ptaGetCount(ptas);
2556  ptad = ptaCreate(n);
2557  if (ptap)
2558  ptat = ptaClone(ptap);
2559  else
2560  ptat = ptaGetPixelsFromPix(pixp, NULL);
2561  np = ptaGetCount(ptat);
2562  for (i = 0; i < n; i++) {
2563  ptaGetIPt(ptas, i, &x, &y);
2564  for (j = 0; j < np; j++) {
2565  ptaGetIPt(ptat, j, &xp, &yp);
2566  xf = x - cx + xp;
2567  yf = y - cy + yp;
2568  if (xf >= 0 && xf < w && yf >= 0 && yf < h)
2569  ptaAddPt(ptad, xf, yf);
2570  }
2571  }
2572 
2573  ptaDestroy(&ptat);
2574  return ptad;
2575 }
2576 
2577 
2586 PIX *
2588  PTAA *ptaa)
2589 {
2590 l_int32 i, j, w, h, npta, npt, x, y, rv, gv, bv;
2591 l_uint32 *pixela;
2592 NUMA *na1, *na2, *na3;
2593 PIX *pixd;
2594 PTA *pta;
2595 
2596  if (!pixs)
2597  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2598  if (!ptaa)
2599  return (PIX *)ERROR_PTR("ptaa not defined", __func__, NULL);
2600  npta = ptaaGetCount(ptaa);
2601  if (npta == 0)
2602  return (PIX *)ERROR_PTR("no pta", __func__, NULL);
2603 
2604  if ((pixd = pixConvertTo32(pixs)) == NULL)
2605  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2606  pixGetDimensions(pixd, &w, &h, NULL);
2607 
2608  /* Make a colormap for the paths */
2609  if ((pixela = (l_uint32 *)LEPT_CALLOC(npta, sizeof(l_uint32))) == NULL) {
2610  pixDestroy(&pixd);
2611  return (PIX *)ERROR_PTR("calloc fail for pixela", __func__, NULL);
2612  }
2613  na1 = numaPseudorandomSequence(256, 14657);
2614  na2 = numaPseudorandomSequence(256, 34631);
2615  na3 = numaPseudorandomSequence(256, 54617);
2616  for (i = 0; i < npta; i++) {
2617  numaGetIValue(na1, i % 256, &rv);
2618  numaGetIValue(na2, i % 256, &gv);
2619  numaGetIValue(na3, i % 256, &bv);
2620  composeRGBPixel(rv, gv, bv, &pixela[i]);
2621  }
2622  numaDestroy(&na1);
2623  numaDestroy(&na2);
2624  numaDestroy(&na3);
2625 
2626  for (i = 0; i < npta; i++) {
2627  pta = ptaaGetPta(ptaa, i, L_CLONE);
2628  npt = ptaGetCount(pta);
2629  for (j = 0; j < npt; j++) {
2630  ptaGetIPt(pta, j, &x, &y);
2631  if (x < 0 || x >= w || y < 0 || y >= h)
2632  continue;
2633  pixSetPixel(pixd, x, y, pixela[i]);
2634  }
2635  ptaDestroy(&pta);
2636  }
2637 
2638  LEPT_FREE(pixela);
2639  return pixd;
2640 }
l_int32 gaussjordan(l_float32 **a, l_float32 *b, l_int32 n)
gaussjordan()
Definition: affine.c:1314
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
l_ok boxGetGeometry(const BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:301
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:796
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:519
l_int32 boxaGetCount(const BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:661
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:171
l_ok boxContainsPt(BOX *box, l_float32 x, l_float32 y, l_int32 *pcontains)
boxContainsPt()
Definition: boxfunc1.c:1182
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:272
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:171
l_ok pixcmapGetColor32(PIXCMAP *cmap, l_int32 index, l_uint32 *pval32)
pixcmapGetColor32()
Definition: colormap.c:827
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:152
l_ok gplotSimple1(NUMA *na, l_int32 outformat, const char *outroot, const char *title)
gplotSimple1()
Definition: gplot.c:649
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
Definition: morphseq.c:137
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:460
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:687
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:193
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:357
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:720
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:882
NUMA * numaPseudorandomSequence(l_int32 size, l_int32 seed)
numaPseudorandomSequence()
Definition: numafunc1.c:3151
l_ok numaGetMedian(NUMA *na, l_float32 *pval)
numaGetMedian()
Definition: numafunc1.c:3296
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1642
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:582
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:263
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:192
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1863
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2728
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1654
l_ok pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2300
@ COLOR_BLUE
Definition: pix.h:330
@ COLOR_RED
Definition: pix.h:328
@ COLOR_GREEN
Definition: pix.h:329
@ L_SELECT_IF_LTE
Definition: pix.h:577
@ L_SELECT_IF_LT
Definition: pix.h:575
@ L_SELECT_IF_GT
Definition: pix.h:576
@ L_SELECT_IF_GTE
Definition: pix.h:578
@ L_SELECT_IF_BOTH
Definition: pix.h:599
@ L_SELECT_IF_EITHER
Definition: pix.h:597
@ L_SELECT_XVAL
Definition: pix.h:595
@ L_SELECT_YVAL
Definition: pix.h:596
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:384
@ L_CLONE
Definition: pix.h:506
@ L_INSERT
Definition: pix.h:504
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:404
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:647
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:324
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3246
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
l_ok ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1197
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1064
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:527
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:963
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:286
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1046
l_ok ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1131
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:328
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:499
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:480
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:219
l_ok applyLinearFit(l_float32 a, l_float32 b, l_float32 x, l_float32 *py)
applyLinearFit()
Definition: ptafunc1.c:1704
PTA * ptaGetBoundaryPixels(PIX *pixs, l_int32 type)
ptaGetBoundaryPixels()
Definition: ptafunc1.c:2001
l_int32 ptaContainsPt(PTA *pta, l_int32 x, l_int32 y)
ptaContainsPt()
Definition: ptafunc1.c:649
PTA * ptaSubsample(PTA *ptas, l_int32 subfactor)
ptaSubsample()
Definition: ptafunc1.c:125
l_ok pixPlotAlongPta(PIX *pixs, PTA *pta, l_int32 outformat, const char *title)
pixPlotAlongPta()
Definition: ptafunc1.c:1812
BOX * ptaGetBoundingRegion(PTA *pta)
ptaGetBoundingRegion()
Definition: ptafunc1.c:431
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1911
l_ok ptaGetQuarticLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pd, l_float32 *pe, NUMA **pnafit)
ptaGetQuarticLSF()
Definition: ptafunc1.c:1407
PTA * ptaCyclicPerm(PTA *ptas, l_int32 xs, l_int32 ys)
ptaCyclicPerm()
Definition: ptafunc1.c:324
PIX * pixDisplayPtaPattern(PIX *pixd, PIX *pixs, PTA *pta, PIX *pixp, l_int32 cx, l_int32 cy, l_uint32 color)
pixDisplayPtaPattern()
Definition: ptafunc1.c:2478
PTA * numaConvertToPta1(NUMA *na)
numaConvertToPta1()
Definition: ptafunc1.c:2238
l_ok applyQuadraticFit(l_float32 a, l_float32 b, l_float32 c, l_float32 x, l_float32 *py)
applyQuadraticFit()
Definition: ptafunc1.c:1726
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:753
PTA * ptaGetInsideBox(PTA *ptas, BOX *box)
ptaGetInsideBox()
Definition: ptafunc1.c:521
l_int32 ptaTestIntersection(PTA *pta1, PTA *pta2)
ptaTestIntersection()
Definition: ptafunc1.c:676
PTA * ptaTranspose(PTA *ptas)
ptaTranspose()
Definition: ptafunc1.c:286
PTA * ptaGetNeighborPixLocs(PIX *pixs, l_int32 x, l_int32 y, l_int32 conn)
ptaGetNeighborPixLocs()
Definition: ptafunc1.c:2184
PIX * pixDisplayPtaa(PIX *pixs, PTAA *ptaa)
pixDisplayPtaa()
Definition: ptafunc1.c:2587
PTA * ptaSelectRange(PTA *ptas, l_int32 first, l_int32 last)
ptaSelectRange()
Definition: ptafunc1.c:378
l_ok ptaGetMinMax(PTA *pta, l_float32 *pxmin, l_float32 *pymin, l_float32 *pxmax, l_float32 *pymax)
ptaGetMinMax()
Definition: ptafunc1.c:887
l_ok ptaGetCubicLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pd, NUMA **pnafit)
ptaGetCubicLSF()
Definition: ptafunc1.c:1279
l_ok applyQuarticFit(l_float32 a, l_float32 b, l_float32 c, l_float32 d, l_float32 e, l_float32 x, l_float32 *py)
applyQuarticFit()
Definition: ptafunc1.c:1773
PTAA * ptaaIndexLabeledPixels(PIX *pixs, l_int32 *pncc)
ptaaIndexLabeledPixels()
Definition: ptafunc1.c:2129
l_ok ptaConvertToNuma(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaConvertToNuma()
Definition: ptafunc1.c:2300
l_float32 l_angleBetweenVectors(l_float32 x1, l_float32 y1, l_float32 x2, l_float32 y2)
l_angleBetweenVectors()
Definition: ptafunc1.c:803
l_ok ptaGetQuadraticLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, NUMA **pnafit)
ptaGetQuadraticLSF()
Definition: ptafunc1.c:1168
l_ok ptaaJoin(PTAA *ptaad, PTAA *ptaas, l_int32 istart, l_int32 iend)
ptaaJoin()
Definition: ptafunc1.c:214
l_ok ptaGetLinearLSF(PTA *pta, l_float32 *pa, l_float32 *pb, NUMA **pnafit)
ptaGetLinearLSF()
Definition: ptafunc1.c:1069
l_ok ptaNoisyLinearLSF(PTA *pta, l_float32 factor, PTA **pptad, l_float32 *pa, l_float32 *pb, l_float32 *pmederr, NUMA **pnafit)
ptaNoisyLinearLSF()
Definition: ptafunc1.c:1541
PTA * ptaSelectByValue(PTA *ptas, l_float32 xth, l_float32 yth, l_int32 type, l_int32 relation)
ptaSelectByValue()
Definition: ptafunc1.c:938
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:166
PIX * pixDisplayPtaaPattern(PIX *pixd, PIX *pixs, PTAA *ptaa, PIX *pixp, l_int32 cx, l_int32 cy)
pixDisplayPtaaPattern()
Definition: ptafunc1.c:2413
l_ok ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:473
PTAA * ptaaGetBoundaryPixels(PIX *pixs, l_int32 type, l_int32 connectivity, BOXA **pboxa, PIXA **ppixa)
ptaaGetBoundaryPixels()
Definition: ptafunc1.c:2048
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2537
PIX * pixGenerateFromPta(PTA *pta, l_int32 w, l_int32 h)
pixGenerateFromPta()
Definition: ptafunc1.c:1962
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:1004
PTA * pixFindCornerPixels(PIX *pixs)
pixFindCornerPixels()
Definition: ptafunc1.c:559
PTA * ptaReverse(PTA *ptas, l_int32 type)
ptaReverse()
Definition: ptafunc1.c:252
l_int32 ptaPolygonIsConvex(PTA *pta, l_int32 *pisconvex)
ptaPolygonIsConvex()
Definition: ptafunc1.c:838
l_ok ptaNoisyQuadraticLSF(PTA *pta, l_float32 factor, PTA **pptad, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pmederr, NUMA **pnafit)
ptaNoisyQuadraticLSF()
Definition: ptafunc1.c:1626
PTA * numaConvertToPta2(NUMA *nax, NUMA *nay)
numaConvertToPta2()
Definition: ptafunc1.c:2266
PIX * pixDisplayPta(PIX *pixd, PIX *pixs, PTA *pta)
pixDisplayPta()
Definition: ptafunc1.c:2349
PTA * ptaTransform(PTA *ptas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
ptaTransform()
Definition: ptafunc1.c:715
l_ok applyCubicFit(l_float32 a, l_float32 b, l_float32 c, l_float32 d, l_float32 x, l_float32 *py)
applyCubicFit()
Definition: ptafunc1.c:1749
l_float32 * y
Definition: pix_internal.h:293
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2138
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:506