Leptonica  1.82.0
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 
109 #ifndef M_PI
110 #define M_PI 3.14159265358979323846
111 #endif /* M_PI */
112 
113 /*---------------------------------------------------------------------*
114  * Simple rearrangements *
115  *---------------------------------------------------------------------*/
123 PTA *
125  l_int32 subfactor)
126 {
127 l_int32 n, i;
128 l_float32 x, y;
129 PTA *ptad;
130 
131  PROCNAME("pixSubsample");
132 
133  if (!ptas)
134  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
135  if (subfactor < 1)
136  return (PTA *)ERROR_PTR("subfactor < 1", procName, NULL);
137 
138  ptad = ptaCreate(0);
139  n = ptaGetCount(ptas);
140  for (i = 0; i < n; i++) {
141  if (i % subfactor != 0) continue;
142  ptaGetPt(ptas, i, &x, &y);
143  ptaAddPt(ptad, x, y);
144  }
145 
146  return ptad;
147 }
148 
149 
166 l_ok
167 ptaJoin(PTA *ptad,
168  PTA *ptas,
169  l_int32 istart,
170  l_int32 iend)
171 {
172 l_int32 n, i, x, y;
173 
174  PROCNAME("ptaJoin");
175 
176  if (!ptad)
177  return ERROR_INT("ptad not defined", procName, 1);
178  if (!ptas)
179  return 0;
180 
181  if (istart < 0)
182  istart = 0;
183  n = ptaGetCount(ptas);
184  if (iend < 0 || iend >= n)
185  iend = n - 1;
186  if (istart > iend)
187  return ERROR_INT("istart > iend; no pts", procName, 1);
188 
189  for (i = istart; i <= iend; i++) {
190  ptaGetIPt(ptas, i, &x, &y);
191  if (ptaAddPt(ptad, x, y) == 1) {
192  L_ERROR("failed to add pt at i = %d\n", procName, i);
193  return 1;
194  }
195  }
196  return 0;
197 }
198 
199 
216 l_ok
217 ptaaJoin(PTAA *ptaad,
218  PTAA *ptaas,
219  l_int32 istart,
220  l_int32 iend)
221 {
222 l_int32 n, i;
223 PTA *pta;
224 
225  PROCNAME("ptaaJoin");
226 
227  if (!ptaad)
228  return ERROR_INT("ptaad not defined", procName, 1);
229  if (!ptaas)
230  return 0;
231 
232  if (istart < 0)
233  istart = 0;
234  n = ptaaGetCount(ptaas);
235  if (iend < 0 || iend >= n)
236  iend = n - 1;
237  if (istart > iend)
238  return ERROR_INT("istart > iend; no pts", procName, 1);
239 
240  for (i = istart; i <= iend; i++) {
241  pta = ptaaGetPta(ptaas, i, L_CLONE);
242  ptaaAddPta(ptaad, pta, L_INSERT);
243  }
244 
245  return 0;
246 }
247 
248 
256 PTA *
258  l_int32 type)
259 {
260 l_int32 n, i, ix, iy;
261 l_float32 x, y;
262 PTA *ptad;
263 
264  PROCNAME("ptaReverse");
265 
266  if (!ptas)
267  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
268 
269  n = ptaGetCount(ptas);
270  if ((ptad = ptaCreate(n)) == NULL)
271  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
272  for (i = n - 1; i >= 0; i--) {
273  if (type == 0) {
274  ptaGetPt(ptas, i, &x, &y);
275  ptaAddPt(ptad, x, y);
276  } else { /* type == 1 */
277  ptaGetIPt(ptas, i, &ix, &iy);
278  ptaAddPt(ptad, ix, iy);
279  }
280  }
281 
282  return ptad;
283 }
284 
285 
292 PTA *
294 {
295 l_int32 n, i;
296 l_float32 x, y;
297 PTA *ptad;
298 
299  PROCNAME("ptaTranspose");
300 
301  if (!ptas)
302  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
303 
304  n = ptaGetCount(ptas);
305  if ((ptad = ptaCreate(n)) == NULL)
306  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
307  for (i = 0; i < n; i++) {
308  ptaGetPt(ptas, i, &x, &y);
309  ptaAddPt(ptad, y, x);
310  }
311 
312  return ptad;
313 }
314 
315 
332 PTA *
334  l_int32 xs,
335  l_int32 ys)
336 {
337 l_int32 n, i, x, y, j, index, state;
338 l_int32 x1, y1, x2, y2;
339 PTA *ptad;
340 
341  PROCNAME("ptaCyclicPerm");
342 
343  if (!ptas)
344  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
345 
346  n = ptaGetCount(ptas);
347 
348  /* Verify input data */
349  ptaGetIPt(ptas, 0, &x1, &y1);
350  ptaGetIPt(ptas, n - 1, &x2, &y2);
351  if (x1 != x2 || y1 != y2)
352  return (PTA *)ERROR_PTR("start and end pts not same", procName, NULL);
353  state = L_NOT_FOUND;
354  for (i = 0; i < n; i++) {
355  ptaGetIPt(ptas, i, &x, &y);
356  if (x == xs && y == ys) {
357  state = L_FOUND;
358  break;
359  }
360  }
361  if (state == L_NOT_FOUND)
362  return (PTA *)ERROR_PTR("start pt not in ptas", procName, NULL);
363 
364  if ((ptad = ptaCreate(n)) == NULL)
365  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
366  for (j = 0; j < n - 1; j++) {
367  if (i + j < n - 1)
368  index = i + j;
369  else
370  index = (i + j + 1) % n;
371  ptaGetIPt(ptas, index, &x, &y);
372  ptaAddPt(ptad, x, y);
373  }
374  ptaAddPt(ptad, xs, ys);
375 
376  return ptad;
377 }
378 
379 
388 PTA *
390  l_int32 first,
391  l_int32 last)
392 {
393 l_int32 n, npt, i;
394 l_float32 x, y;
395 PTA *ptad;
396 
397  PROCNAME("ptaSelectRange");
398 
399  if (!ptas)
400  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
401  if ((n = ptaGetCount(ptas)) == 0) {
402  L_WARNING("ptas is empty\n", procName);
403  return ptaCopy(ptas);
404  }
405  first = L_MAX(0, first);
406  if (last < 0) last = n - 1;
407  if (first >= n)
408  return (PTA *)ERROR_PTR("invalid first", procName, NULL);
409  if (last >= n) {
410  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
411  procName, last, n - 1);
412  last = n - 1;
413  }
414  if (first > last)
415  return (PTA *)ERROR_PTR("first > last", procName, NULL);
416 
417  npt = last - first + 1;
418  ptad = ptaCreate(npt);
419  for (i = first; i <= last; i++) {
420  ptaGetPt(ptas, i, &x, &y);
421  ptaAddPt(ptad, x, y);
422  }
423  return ptad;
424 }
425 
426 
427 /*---------------------------------------------------------------------*
428  * Geometric *
429  *---------------------------------------------------------------------*/
443 BOX *
445 {
446 l_int32 n, i, x, y, minx, maxx, miny, maxy;
447 
448  PROCNAME("ptaGetBoundingRegion");
449 
450  if (!pta)
451  return (BOX *)ERROR_PTR("pta not defined", procName, NULL);
452 
453  minx = 10000000;
454  miny = 10000000;
455  maxx = -10000000;
456  maxy = -10000000;
457  n = ptaGetCount(pta);
458  for (i = 0; i < n; i++) {
459  ptaGetIPt(pta, i, &x, &y);
460  if (x < minx) minx = x;
461  if (x > maxx) maxx = x;
462  if (y < miny) miny = y;
463  if (y > maxy) maxy = y;
464  }
465 
466  return boxCreate(minx, miny, maxx - minx + 1, maxy - miny + 1);
467 }
468 
469 
487 l_ok
489  l_float32 *pminx,
490  l_float32 *pmaxx,
491  l_float32 *pminy,
492  l_float32 *pmaxy)
493 {
494 l_int32 n, i;
495 l_float32 x, y, minx, maxx, miny, maxy;
496 
497  PROCNAME("ptaGetRange");
498 
499  if (!pminx && !pmaxx && !pminy && !pmaxy)
500  return ERROR_INT("no output requested", procName, 1);
501  if (pminx) *pminx = 0;
502  if (pmaxx) *pmaxx = 0;
503  if (pminy) *pminy = 0;
504  if (pmaxy) *pmaxy = 0;
505  if (!pta)
506  return ERROR_INT("pta not defined", procName, 1);
507  if ((n = ptaGetCount(pta)) == 0)
508  return ERROR_INT("no points in pta", procName, 1);
509 
510  ptaGetPt(pta, 0, &x, &y);
511  minx = x;
512  maxx = x;
513  miny = y;
514  maxy = y;
515  for (i = 1; i < n; i++) {
516  ptaGetPt(pta, i, &x, &y);
517  if (x < minx) minx = x;
518  if (x > maxx) maxx = x;
519  if (y < miny) miny = y;
520  if (y > maxy) maxy = y;
521  }
522  if (pminx) *pminx = minx;
523  if (pmaxx) *pmaxx = maxx;
524  if (pminy) *pminy = miny;
525  if (pmaxy) *pmaxy = maxy;
526  return 0;
527 }
528 
529 
537 PTA *
539  BOX *box)
540 {
541 PTA *ptad;
542 l_int32 n, i, contains;
543 l_float32 x, y;
544 
545  PROCNAME("ptaGetInsideBox");
546 
547  if (!ptas)
548  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
549  if (!box)
550  return (PTA *)ERROR_PTR("box not defined", procName, NULL);
551 
552  n = ptaGetCount(ptas);
553  ptad = ptaCreate(0);
554  for (i = 0; i < n; i++) {
555  ptaGetPt(ptas, i, &x, &y);
556  boxContainsPt(box, x, y, &contains);
557  if (contains)
558  ptaAddPt(ptad, x, y);
559  }
560 
561  return ptad;
562 }
563 
564 
577 PTA *
579 {
580 l_int32 i, j, x, y, w, h, wpl, mindim, found;
581 l_uint32 *data, *line;
582 PTA *pta;
583 
584  PROCNAME("pixFindCornerPixels");
585 
586  if (!pixs)
587  return (PTA *)ERROR_PTR("pixs not defined", procName, NULL);
588  if (pixGetDepth(pixs) != 1)
589  return (PTA *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
590 
591  w = pixGetWidth(pixs);
592  h = pixGetHeight(pixs);
593  mindim = L_MIN(w, h);
594  data = pixGetData(pixs);
595  wpl = pixGetWpl(pixs);
596 
597  if ((pta = ptaCreate(4)) == NULL)
598  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
599 
600  for (found = FALSE, i = 0; i < mindim; i++) {
601  for (j = 0; j <= i; j++) {
602  y = i - j;
603  line = data + y * wpl;
604  if (GET_DATA_BIT(line, j)) {
605  ptaAddPt(pta, j, y);
606  found = TRUE;
607  break;
608  }
609  }
610  if (found == TRUE)
611  break;
612  }
613 
614  for (found = FALSE, i = 0; i < mindim; i++) {
615  for (j = 0; j <= i; j++) {
616  y = i - j;
617  line = data + y * wpl;
618  x = w - 1 - j;
619  if (GET_DATA_BIT(line, x)) {
620  ptaAddPt(pta, x, y);
621  found = TRUE;
622  break;
623  }
624  }
625  if (found == TRUE)
626  break;
627  }
628 
629  for (found = FALSE, i = 0; i < mindim; i++) {
630  for (j = 0; j <= i; j++) {
631  y = h - 1 - i + j;
632  line = data + y * wpl;
633  if (GET_DATA_BIT(line, j)) {
634  ptaAddPt(pta, j, y);
635  found = TRUE;
636  break;
637  }
638  }
639  if (found == TRUE)
640  break;
641  }
642 
643  for (found = FALSE, i = 0; i < mindim; i++) {
644  for (j = 0; j <= i; j++) {
645  y = h - 1 - i + j;
646  line = data + y * wpl;
647  x = w - 1 - j;
648  if (GET_DATA_BIT(line, x)) {
649  ptaAddPt(pta, x, y);
650  found = TRUE;
651  break;
652  }
653  }
654  if (found == TRUE)
655  break;
656  }
657 
658  return pta;
659 }
660 
661 
669 l_int32
671  l_int32 x,
672  l_int32 y)
673 {
674 l_int32 i, n, ix, iy;
675 
676  PROCNAME("ptaContainsPt");
677 
678  if (!pta)
679  return ERROR_INT("pta not defined", procName, 0);
680 
681  n = ptaGetCount(pta);
682  for (i = 0; i < n; i++) {
683  ptaGetIPt(pta, i, &ix, &iy);
684  if (x == ix && y == iy)
685  return 1;
686  }
687  return 0;
688 }
689 
690 
698 l_int32
700  PTA *pta2)
701 {
702 l_int32 i, j, n1, n2, x1, y1, x2, y2;
703 
704  PROCNAME("ptaTestIntersection");
705 
706  if (!pta1)
707  return ERROR_INT("pta1 not defined", procName, 0);
708  if (!pta2)
709  return ERROR_INT("pta2 not defined", procName, 0);
710 
711  n1 = ptaGetCount(pta1);
712  n2 = ptaGetCount(pta2);
713  for (i = 0; i < n1; i++) {
714  ptaGetIPt(pta1, i, &x1, &y1);
715  for (j = 0; j < n2; j++) {
716  ptaGetIPt(pta2, i, &x2, &y2);
717  if (x1 == x2 && y1 == y2)
718  return 1;
719  }
720  }
721 
722  return 0;
723 }
724 
725 
739 PTA *
741  l_int32 shiftx,
742  l_int32 shifty,
743  l_float32 scalex,
744  l_float32 scaley)
745 {
746 l_int32 n, i, x, y;
747 PTA *ptad;
748 
749  PROCNAME("ptaTransform");
750 
751  if (!ptas)
752  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
753  n = ptaGetCount(ptas);
754  ptad = ptaCreate(n);
755  for (i = 0; i < n; i++) {
756  ptaGetIPt(ptas, i, &x, &y);
757  x = (l_int32)(scalex * (x + shiftx) + 0.5);
758  y = (l_int32)(scaley * (y + shifty) + 0.5);
759  ptaAddPt(ptad, x, y);
760  }
761 
762  return ptad;
763 }
764 
765 
779 l_int32
781  l_float32 x,
782  l_float32 y,
783  l_int32 *pinside)
784 {
785 l_int32 i, n;
786 l_float32 sum, x1, y1, x2, y2, xp1, yp1, xp2, yp2;
787 
788  PROCNAME("ptaPtInsidePolygon");
789 
790  if (!pinside)
791  return ERROR_INT("&inside not defined", procName, 1);
792  *pinside = 0;
793  if (!pta)
794  return ERROR_INT("pta not defined", procName, 1);
795 
796  /* Think of (x1,y1) as the end point of a vector that starts
797  * from the origin (0,0), and ditto for (x2,y2). */
798  n = ptaGetCount(pta);
799  sum = 0.0;
800  for (i = 0; i < n; i++) {
801  ptaGetPt(pta, i, &xp1, &yp1);
802  ptaGetPt(pta, (i + 1) % n, &xp2, &yp2);
803  x1 = xp1 - x;
804  y1 = yp1 - y;
805  x2 = xp2 - x;
806  y2 = yp2 - y;
807  sum += l_angleBetweenVectors(x1, y1, x2, y2);
808  }
809 
810  if (L_ABS(sum) > M_PI)
811  *pinside = 1;
812  return 0;
813 }
814 
815 
831 l_float32
833  l_float32 y1,
834  l_float32 x2,
835  l_float32 y2)
836 {
837 l_float64 ang;
838 
839  ang = atan2(y2, x2) - atan2(y1, x1);
840  if (ang > M_PI) ang -= 2.0 * M_PI;
841  if (ang < -M_PI) ang += 2.0 * M_PI;
842  return ang;
843 }
844 
845 
866 l_int32
868  l_int32 *pisconvex)
869 {
870 l_int32 i, n;
871 l_float32 x0, y0, x1, y1, x2, y2;
872 l_float64 cprod;
873 
874  PROCNAME("ptaPolygonIsConvex");
875 
876  if (!pisconvex)
877  return ERROR_INT("&isconvex not defined", procName, 1);
878  *pisconvex = 0;
879  if (!pta)
880  return ERROR_INT("pta not defined", procName, 1);
881  if ((n = ptaGetCount(pta)) < 3)
882  return ERROR_INT("pta has < 3 pts", procName, 1);
883 
884  for (i = 0; i < n; i++) {
885  ptaGetPt(pta, i, &x0, &y0);
886  ptaGetPt(pta, (i + 1) % n, &x1, &y1);
887  ptaGetPt(pta, (i + 2) % n, &x2, &y2);
888  /* The vector v02 from p0 to p2 must be to the right of the
889  vector v01 from p0 to p1. This is true if the cross
890  product v02 x v01 > 0. In coordinates:
891  v02x * v01y - v01x * v02y, where
892  v01x = x1 - x0, v01y = y1 - y0,
893  v02x = x2 - x0, v02y = y2 - y0 */
894  cprod = (x2 - x0) * (y1 - y0) - (x1 - x0) * (y2 - y0);
895  if (cprod < -0.0001) /* small delta for float accuracy; test fails */
896  return 0;
897  }
898  *pisconvex = 1;
899  return 0;
900 }
901 
902 
903 /*---------------------------------------------------------------------*
904  * Min/max and filtering *
905  *---------------------------------------------------------------------*/
917 l_ok
919  l_float32 *pxmin,
920  l_float32 *pymin,
921  l_float32 *pxmax,
922  l_float32 *pymax)
923 {
924 l_int32 i, n;
925 l_float32 x, y, xmin, ymin, xmax, ymax;
926 
927  PROCNAME("ptaGetMinMax");
928 
929  if (pxmin) *pxmin = -1.0;
930  if (pymin) *pymin = -1.0;
931  if (pxmax) *pxmax = -1.0;
932  if (pymax) *pymax = -1.0;
933  if (!pta)
934  return ERROR_INT("pta not defined", procName, 1);
935  if (!pxmin && !pxmax && !pymin && !pymax)
936  return ERROR_INT("no output requested", procName, 1);
937  if ((n = ptaGetCount(pta)) == 0) {
938  L_WARNING("pta is empty\n", procName);
939  return 0;
940  }
941 
942  xmin = ymin = 1.0e20;
943  xmax = ymax = -1.0e20;
944  for (i = 0; i < n; i++) {
945  ptaGetPt(pta, i, &x, &y);
946  if (x < xmin) xmin = x;
947  if (y < ymin) ymin = y;
948  if (x > xmax) xmax = x;
949  if (y > ymax) ymax = y;
950  }
951  if (pxmin) *pxmin = xmin;
952  if (pymin) *pymin = ymin;
953  if (pxmax) *pxmax = xmax;
954  if (pymax) *pymax = ymax;
955  return 0;
956 }
957 
958 
970 PTA *
972  l_float32 xth,
973  l_float32 yth,
974  l_int32 type,
975  l_int32 relation)
976 {
977 l_int32 i, n;
978 l_float32 x, y;
979 PTA *ptad;
980 
981  PROCNAME("ptaSelectByValue");
982 
983  if (!ptas)
984  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
985  if (ptaGetCount(ptas) == 0) {
986  L_WARNING("ptas is empty\n", procName);
987  return ptaCopy(ptas);
988  }
989  if (type != L_SELECT_XVAL && type != L_SELECT_YVAL &&
990  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
991  return (PTA *)ERROR_PTR("invalid type", procName, NULL);
992  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
993  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
994  return (PTA *)ERROR_PTR("invalid relation", procName, NULL);
995 
996  n = ptaGetCount(ptas);
997  ptad = ptaCreate(n);
998  for (i = 0; i < n; i++) {
999  ptaGetPt(ptas, i, &x, &y);
1000  if (type == L_SELECT_XVAL) {
1001  if ((relation == L_SELECT_IF_LT && x < xth) ||
1002  (relation == L_SELECT_IF_GT && x > xth) ||
1003  (relation == L_SELECT_IF_LTE && x <= xth) ||
1004  (relation == L_SELECT_IF_GTE && x >= xth))
1005  ptaAddPt(ptad, x, y);
1006  } else if (type == L_SELECT_YVAL) {
1007  if ((relation == L_SELECT_IF_LT && y < yth) ||
1008  (relation == L_SELECT_IF_GT && y > yth) ||
1009  (relation == L_SELECT_IF_LTE && y <= yth) ||
1010  (relation == L_SELECT_IF_GTE && y >= yth))
1011  ptaAddPt(ptad, x, y);
1012  } else if (type == L_SELECT_IF_EITHER) {
1013  if (((relation == L_SELECT_IF_LT) && (x < xth || y < yth)) ||
1014  ((relation == L_SELECT_IF_GT) && (x > xth || y > yth)) ||
1015  ((relation == L_SELECT_IF_LTE) && (x <= xth || y <= yth)) ||
1016  ((relation == L_SELECT_IF_GTE) && (x >= xth || y >= yth)))
1017  ptaAddPt(ptad, x, y);
1018  } else { /* L_SELECT_IF_BOTH */
1019  if (((relation == L_SELECT_IF_LT) && (x < xth && y < yth)) ||
1020  ((relation == L_SELECT_IF_GT) && (x > xth && y > yth)) ||
1021  ((relation == L_SELECT_IF_LTE) && (x <= xth && y <= yth)) ||
1022  ((relation == L_SELECT_IF_GTE) && (x >= xth && y >= yth)))
1023  ptaAddPt(ptad, x, y);
1024  }
1025  }
1026 
1027  return ptad;
1028 }
1029 
1030 
1038 PTA *
1040  PIX *pixm)
1041 {
1042 l_int32 i, n, x, y;
1043 l_uint32 val;
1044 PTA *ptad;
1045 
1046  PROCNAME("ptaCropToMask");
1047 
1048  if (!ptas)
1049  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
1050  if (!pixm || pixGetDepth(pixm) != 1)
1051  return (PTA *)ERROR_PTR("pixm undefined or not 1 bpp", procName, NULL);
1052  if (ptaGetCount(ptas) == 0) {
1053  L_INFO("ptas is empty\n", procName);
1054  return ptaCopy(ptas);
1055  }
1056 
1057  n = ptaGetCount(ptas);
1058  ptad = ptaCreate(n);
1059  for (i = 0; i < n; i++) {
1060  ptaGetIPt(ptas, i, &x, &y);
1061  pixGetPixel(pixm, x, y, &val);
1062  if (val == 1)
1063  ptaAddPt(ptad, x, y);
1064  }
1065  return ptad;
1066 }
1067 
1068 
1069 /*---------------------------------------------------------------------*
1070  * Least Squares Fit *
1071  *---------------------------------------------------------------------*/
1105 l_ok
1107  l_float32 *pa,
1108  l_float32 *pb,
1109  NUMA **pnafit)
1110 {
1111 l_int32 n, i;
1112 l_float32 a, b, factor, sx, sy, sxx, sxy, val;
1113 l_float32 *xa, *ya;
1114 
1115  PROCNAME("ptaGetLinearLSF");
1116 
1117  if (pa) *pa = 0.0;
1118  if (pb) *pb = 0.0;
1119  if (pnafit) *pnafit = NULL;
1120  if (!pa && !pb && !pnafit)
1121  return ERROR_INT("no output requested", procName, 1);
1122  if (!pta)
1123  return ERROR_INT("pta not defined", procName, 1);
1124  if ((n = ptaGetCount(pta)) < 2)
1125  return ERROR_INT("less than 2 pts found", procName, 1);
1126 
1127  xa = pta->x; /* not a copy */
1128  ya = pta->y; /* not a copy */
1129  sx = sy = sxx = sxy = 0.;
1130  if (pa && pb) { /* general line */
1131  for (i = 0; i < n; i++) {
1132  sx += xa[i];
1133  sy += ya[i];
1134  sxx += xa[i] * xa[i];
1135  sxy += xa[i] * ya[i];
1136  }
1137  factor = n * sxx - sx * sx;
1138  if (factor == 0.0)
1139  return ERROR_INT("no solution found", procName, 1);
1140  factor = 1. / factor;
1141 
1142  a = factor * ((l_float32)n * sxy - sx * sy);
1143  b = factor * (sxx * sy - sx * sxy);
1144  } else if (pa) { /* b = 0; line through origin */
1145  for (i = 0; i < n; i++) {
1146  sxx += xa[i] * xa[i];
1147  sxy += xa[i] * ya[i];
1148  }
1149  if (sxx == 0.0)
1150  return ERROR_INT("no solution found", procName, 1);
1151  a = sxy / sxx;
1152  b = 0.0;
1153  } else { /* a = 0; horizontal line */
1154  for (i = 0; i < n; i++)
1155  sy += ya[i];
1156  a = 0.0;
1157  b = sy / (l_float32)n;
1158  }
1159 
1160  if (pnafit) {
1161  *pnafit = numaCreate(n);
1162  for (i = 0; i < n; i++) {
1163  val = a * xa[i] + b;
1164  numaAddNumber(*pnafit, val);
1165  }
1166  }
1167 
1168  if (pa) *pa = a;
1169  if (pb) *pb = b;
1170  return 0;
1171 }
1172 
1173 
1206 l_ok
1208  l_float32 *pa,
1209  l_float32 *pb,
1210  l_float32 *pc,
1211  NUMA **pnafit)
1212 {
1213 l_int32 n, i, ret;
1214 l_float32 x, y, sx, sy, sx2, sx3, sx4, sxy, sx2y;
1215 l_float32 *xa, *ya;
1216 l_float32 *f[3];
1217 l_float32 g[3];
1218 
1219  PROCNAME("ptaGetQuadraticLSF");
1220 
1221  if (pa) *pa = 0.0;
1222  if (pb) *pb = 0.0;
1223  if (pc) *pc = 0.0;
1224  if (pnafit) *pnafit = NULL;
1225  if (!pa && !pb && !pc && !pnafit)
1226  return ERROR_INT("no output requested", procName, 1);
1227  if (!pta)
1228  return ERROR_INT("pta not defined", procName, 1);
1229  if ((n = ptaGetCount(pta)) < 3)
1230  return ERROR_INT("less than 3 pts found", procName, 1);
1231 
1232  xa = pta->x; /* not a copy */
1233  ya = pta->y; /* not a copy */
1234  sx = sy = sx2 = sx3 = sx4 = sxy = sx2y = 0.;
1235  for (i = 0; i < n; i++) {
1236  x = xa[i];
1237  y = ya[i];
1238  sx += x;
1239  sy += y;
1240  sx2 += x * x;
1241  sx3 += x * x * x;
1242  sx4 += x * x * x * x;
1243  sxy += x * y;
1244  sx2y += x * x * y;
1245  }
1246 
1247  for (i = 0; i < 3; i++)
1248  f[i] = (l_float32 *)LEPT_CALLOC(3, sizeof(l_float32));
1249  f[0][0] = sx4;
1250  f[0][1] = sx3;
1251  f[0][2] = sx2;
1252  f[1][0] = sx3;
1253  f[1][1] = sx2;
1254  f[1][2] = sx;
1255  f[2][0] = sx2;
1256  f[2][1] = sx;
1257  f[2][2] = n;
1258  g[0] = sx2y;
1259  g[1] = sxy;
1260  g[2] = sy;
1261 
1262  /* Solve for the unknowns, also putting f-inverse into f */
1263  ret = gaussjordan(f, g, 3);
1264  for (i = 0; i < 3; i++)
1265  LEPT_FREE(f[i]);
1266  if (ret)
1267  return ERROR_INT("quadratic solution failed", procName, 1);
1268 
1269  if (pa) *pa = g[0];
1270  if (pb) *pb = g[1];
1271  if (pc) *pc = g[2];
1272  if (pnafit) {
1273  *pnafit = numaCreate(n);
1274  for (i = 0; i < n; i++) {
1275  x = xa[i];
1276  y = g[0] * x * x + g[1] * x + g[2];
1277  numaAddNumber(*pnafit, y);
1278  }
1279  }
1280  return 0;
1281 }
1282 
1283 
1319 l_ok
1321  l_float32 *pa,
1322  l_float32 *pb,
1323  l_float32 *pc,
1324  l_float32 *pd,
1325  NUMA **pnafit)
1326 {
1327 l_int32 n, i, ret;
1328 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sxy, sx2y, sx3y;
1329 l_float32 *xa, *ya;
1330 l_float32 *f[4];
1331 l_float32 g[4];
1332 
1333  PROCNAME("ptaGetCubicLSF");
1334 
1335  if (pa) *pa = 0.0;
1336  if (pb) *pb = 0.0;
1337  if (pc) *pc = 0.0;
1338  if (pd) *pd = 0.0;
1339  if (pnafit) *pnafit = NULL;
1340  if (!pa && !pb && !pc && !pd && !pnafit)
1341  return ERROR_INT("no output requested", procName, 1);
1342  if (!pta)
1343  return ERROR_INT("pta not defined", procName, 1);
1344  if ((n = ptaGetCount(pta)) < 4)
1345  return ERROR_INT("less than 4 pts found", procName, 1);
1346 
1347  xa = pta->x; /* not a copy */
1348  ya = pta->y; /* not a copy */
1349  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sxy = sx2y = sx3y = 0.;
1350  for (i = 0; i < n; i++) {
1351  x = xa[i];
1352  y = ya[i];
1353  sx += x;
1354  sy += y;
1355  sx2 += x * x;
1356  sx3 += x * x * x;
1357  sx4 += x * x * x * x;
1358  sx5 += x * x * x * x * x;
1359  sx6 += x * x * x * x * x * x;
1360  sxy += x * y;
1361  sx2y += x * x * y;
1362  sx3y += x * x * x * y;
1363  }
1364 
1365  for (i = 0; i < 4; i++)
1366  f[i] = (l_float32 *)LEPT_CALLOC(4, sizeof(l_float32));
1367  f[0][0] = sx6;
1368  f[0][1] = sx5;
1369  f[0][2] = sx4;
1370  f[0][3] = sx3;
1371  f[1][0] = sx5;
1372  f[1][1] = sx4;
1373  f[1][2] = sx3;
1374  f[1][3] = sx2;
1375  f[2][0] = sx4;
1376  f[2][1] = sx3;
1377  f[2][2] = sx2;
1378  f[2][3] = sx;
1379  f[3][0] = sx3;
1380  f[3][1] = sx2;
1381  f[3][2] = sx;
1382  f[3][3] = n;
1383  g[0] = sx3y;
1384  g[1] = sx2y;
1385  g[2] = sxy;
1386  g[3] = sy;
1387 
1388  /* Solve for the unknowns, also putting f-inverse into f */
1389  ret = gaussjordan(f, g, 4);
1390  for (i = 0; i < 4; i++)
1391  LEPT_FREE(f[i]);
1392  if (ret)
1393  return ERROR_INT("cubic solution failed", procName, 1);
1394 
1395  if (pa) *pa = g[0];
1396  if (pb) *pb = g[1];
1397  if (pc) *pc = g[2];
1398  if (pd) *pd = g[3];
1399  if (pnafit) {
1400  *pnafit = numaCreate(n);
1401  for (i = 0; i < n; i++) {
1402  x = xa[i];
1403  y = g[0] * x * x * x + g[1] * x * x + g[2] * x + g[3];
1404  numaAddNumber(*pnafit, y);
1405  }
1406  }
1407  return 0;
1408 }
1409 
1410 
1449 l_ok
1451  l_float32 *pa,
1452  l_float32 *pb,
1453  l_float32 *pc,
1454  l_float32 *pd,
1455  l_float32 *pe,
1456  NUMA **pnafit)
1457 {
1458 l_int32 n, i, ret;
1459 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sx7, sx8;
1460 l_float32 sxy, sx2y, sx3y, sx4y;
1461 l_float32 *xa, *ya;
1462 l_float32 *f[5];
1463 l_float32 g[5];
1464 
1465  PROCNAME("ptaGetQuarticLSF");
1466 
1467  if (pa) *pa = 0.0;
1468  if (pb) *pb = 0.0;
1469  if (pc) *pc = 0.0;
1470  if (pd) *pd = 0.0;
1471  if (pe) *pe = 0.0;
1472  if (pnafit) *pnafit = NULL;
1473  if (!pa && !pb && !pc && !pd && !pe && !pnafit)
1474  return ERROR_INT("no output requested", procName, 1);
1475  if (!pta)
1476  return ERROR_INT("pta not defined", procName, 1);
1477  if ((n = ptaGetCount(pta)) < 5)
1478  return ERROR_INT("less than 5 pts found", procName, 1);
1479 
1480  xa = pta->x; /* not a copy */
1481  ya = pta->y; /* not a copy */
1482  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sx7 = sx8 = 0;
1483  sxy = sx2y = sx3y = sx4y = 0.;
1484  for (i = 0; i < n; i++) {
1485  x = xa[i];
1486  y = ya[i];
1487  sx += x;
1488  sy += y;
1489  sx2 += x * x;
1490  sx3 += x * x * x;
1491  sx4 += x * x * x * x;
1492  sx5 += x * x * x * x * x;
1493  sx6 += x * x * x * x * x * x;
1494  sx7 += x * x * x * x * x * x * x;
1495  sx8 += x * x * x * x * x * x * x * x;
1496  sxy += x * y;
1497  sx2y += x * x * y;
1498  sx3y += x * x * x * y;
1499  sx4y += x * x * x * x * y;
1500  }
1501 
1502  for (i = 0; i < 5; i++)
1503  f[i] = (l_float32 *)LEPT_CALLOC(5, sizeof(l_float32));
1504  f[0][0] = sx8;
1505  f[0][1] = sx7;
1506  f[0][2] = sx6;
1507  f[0][3] = sx5;
1508  f[0][4] = sx4;
1509  f[1][0] = sx7;
1510  f[1][1] = sx6;
1511  f[1][2] = sx5;
1512  f[1][3] = sx4;
1513  f[1][4] = sx3;
1514  f[2][0] = sx6;
1515  f[2][1] = sx5;
1516  f[2][2] = sx4;
1517  f[2][3] = sx3;
1518  f[2][4] = sx2;
1519  f[3][0] = sx5;
1520  f[3][1] = sx4;
1521  f[3][2] = sx3;
1522  f[3][3] = sx2;
1523  f[3][4] = sx;
1524  f[4][0] = sx4;
1525  f[4][1] = sx3;
1526  f[4][2] = sx2;
1527  f[4][3] = sx;
1528  f[4][4] = n;
1529  g[0] = sx4y;
1530  g[1] = sx3y;
1531  g[2] = sx2y;
1532  g[3] = sxy;
1533  g[4] = sy;
1534 
1535  /* Solve for the unknowns, also putting f-inverse into f */
1536  ret = gaussjordan(f, g, 5);
1537  for (i = 0; i < 5; i++)
1538  LEPT_FREE(f[i]);
1539  if (ret)
1540  return ERROR_INT("quartic solution failed", procName, 1);
1541 
1542  if (pa) *pa = g[0];
1543  if (pb) *pb = g[1];
1544  if (pc) *pc = g[2];
1545  if (pd) *pd = g[3];
1546  if (pe) *pe = g[4];
1547  if (pnafit) {
1548  *pnafit = numaCreate(n);
1549  for (i = 0; i < n; i++) {
1550  x = xa[i];
1551  y = g[0] * x * x * x * x + g[1] * x * x * x + g[2] * x * x
1552  + g[3] * x + g[4];
1553  numaAddNumber(*pnafit, y);
1554  }
1555  }
1556  return 0;
1557 }
1558 
1559 
1585 l_ok
1587  l_float32 factor,
1588  PTA **pptad,
1589  l_float32 *pa,
1590  l_float32 *pb,
1591  l_float32 *pmederr,
1592  NUMA **pnafit)
1593 {
1594 l_int32 n, i, ret;
1595 l_float32 x, y, yf, val, mederr;
1596 NUMA *nafit, *naerror;
1597 PTA *ptad;
1598 
1599  PROCNAME("ptaNoisyLinearLSF");
1600 
1601  if (pptad) *pptad = NULL;
1602  if (pa) *pa = 0.0;
1603  if (pb) *pb = 0.0;
1604  if (pmederr) *pmederr = 0.0;
1605  if (pnafit) *pnafit = NULL;
1606  if (!pptad && !pa && !pb && !pnafit)
1607  return ERROR_INT("no output requested", procName, 1);
1608  if (!pta)
1609  return ERROR_INT("pta not defined", procName, 1);
1610  if (factor <= 0.0)
1611  return ERROR_INT("factor must be > 0.0", procName, 1);
1612  if ((n = ptaGetCount(pta)) < 3)
1613  return ERROR_INT("less than 2 pts found", procName, 1);
1614 
1615  if (ptaGetLinearLSF(pta, pa, pb, &nafit) != 0)
1616  return ERROR_INT("error in linear LSF", procName, 1);
1617 
1618  /* Get the median error */
1619  naerror = numaCreate(n);
1620  for (i = 0; i < n; i++) {
1621  ptaGetPt(pta, i, &x, &y);
1622  numaGetFValue(nafit, i, &yf);
1623  numaAddNumber(naerror, L_ABS(y - yf));
1624  }
1625  numaGetMedian(naerror, &mederr);
1626  if (pmederr) *pmederr = mederr;
1627  numaDestroy(&nafit);
1628 
1629  /* Remove outliers */
1630  ptad = ptaCreate(n);
1631  for (i = 0; i < n; i++) {
1632  ptaGetPt(pta, i, &x, &y);
1633  numaGetFValue(naerror, i, &val);
1634  if (val <= factor * mederr) /* <= in case mederr = 0 */
1635  ptaAddPt(ptad, x, y);
1636  }
1637  numaDestroy(&naerror);
1638 
1639  /* Do LSF again */
1640  ret = ptaGetLinearLSF(ptad, pa, pb, pnafit);
1641  if (pptad)
1642  *pptad = ptad;
1643  else
1644  ptaDestroy(&ptad);
1645 
1646  return ret;
1647 }
1648 
1649 
1672 l_ok
1674  l_float32 factor,
1675  PTA **pptad,
1676  l_float32 *pa,
1677  l_float32 *pb,
1678  l_float32 *pc,
1679  l_float32 *pmederr,
1680  NUMA **pnafit)
1681 {
1682 l_int32 n, i, ret;
1683 l_float32 x, y, yf, val, mederr;
1684 NUMA *nafit, *naerror;
1685 PTA *ptad;
1686 
1687  PROCNAME("ptaNoisyQuadraticLSF");
1688 
1689  if (pptad) *pptad = NULL;
1690  if (pa) *pa = 0.0;
1691  if (pb) *pb = 0.0;
1692  if (pc) *pc = 0.0;
1693  if (pmederr) *pmederr = 0.0;
1694  if (pnafit) *pnafit = NULL;
1695  if (!pptad && !pa && !pb && !pc && !pnafit)
1696  return ERROR_INT("no output requested", procName, 1);
1697  if (factor <= 0.0)
1698  return ERROR_INT("factor must be > 0.0", procName, 1);
1699  if (!pta)
1700  return ERROR_INT("pta not defined", procName, 1);
1701  if ((n = ptaGetCount(pta)) < 3)
1702  return ERROR_INT("less than 3 pts found", procName, 1);
1703 
1704  if (ptaGetQuadraticLSF(pta, NULL, NULL, NULL, &nafit) != 0)
1705  return ERROR_INT("error in quadratic LSF", procName, 1);
1706 
1707  /* Get the median error */
1708  naerror = numaCreate(n);
1709  for (i = 0; i < n; i++) {
1710  ptaGetPt(pta, i, &x, &y);
1711  numaGetFValue(nafit, i, &yf);
1712  numaAddNumber(naerror, L_ABS(y - yf));
1713  }
1714  numaGetMedian(naerror, &mederr);
1715  if (pmederr) *pmederr = mederr;
1716  numaDestroy(&nafit);
1717 
1718  /* Remove outliers */
1719  ptad = ptaCreate(n);
1720  for (i = 0; i < n; i++) {
1721  ptaGetPt(pta, i, &x, &y);
1722  numaGetFValue(naerror, i, &val);
1723  if (val <= factor * mederr) /* <= in case mederr = 0 */
1724  ptaAddPt(ptad, x, y);
1725  }
1726  numaDestroy(&naerror);
1727  n = ptaGetCount(ptad);
1728  if ((n = ptaGetCount(ptad)) < 3) {
1729  ptaDestroy(&ptad);
1730  return ERROR_INT("less than 3 pts found", procName, 1);
1731  }
1732 
1733  /* Do LSF again */
1734  ret = ptaGetQuadraticLSF(ptad, pa, pb, pc, pnafit);
1735  if (pptad)
1736  *pptad = ptad;
1737  else
1738  ptaDestroy(&ptad);
1739 
1740  return ret;
1741 }
1742 
1743 
1752 l_ok
1753 applyLinearFit(l_float32 a,
1754  l_float32 b,
1755  l_float32 x,
1756  l_float32 *py)
1757 {
1758  PROCNAME("applyLinearFit");
1759 
1760  if (!py)
1761  return ERROR_INT("&y not defined", procName, 1);
1762 
1763  *py = a * x + b;
1764  return 0;
1765 }
1766 
1767 
1776 l_ok
1777 applyQuadraticFit(l_float32 a,
1778  l_float32 b,
1779  l_float32 c,
1780  l_float32 x,
1781  l_float32 *py)
1782 {
1783  PROCNAME("applyQuadraticFit");
1784 
1785  if (!py)
1786  return ERROR_INT("&y not defined", procName, 1);
1787 
1788  *py = a * x * x + b * x + c;
1789  return 0;
1790 }
1791 
1792 
1801 l_ok
1802 applyCubicFit(l_float32 a,
1803  l_float32 b,
1804  l_float32 c,
1805  l_float32 d,
1806  l_float32 x,
1807  l_float32 *py)
1808 {
1809  PROCNAME("applyCubicFit");
1810 
1811  if (!py)
1812  return ERROR_INT("&y not defined", procName, 1);
1813 
1814  *py = a * x * x * x + b * x * x + c * x + d;
1815  return 0;
1816 }
1817 
1818 
1827 l_ok
1828 applyQuarticFit(l_float32 a,
1829  l_float32 b,
1830  l_float32 c,
1831  l_float32 d,
1832  l_float32 e,
1833  l_float32 x,
1834  l_float32 *py)
1835 {
1836 l_float32 x2;
1837 
1838  PROCNAME("applyQuarticFit");
1839 
1840  if (!py)
1841  return ERROR_INT("&y not defined", procName, 1);
1842 
1843  x2 = x * x;
1844  *py = a * x2 * x2 + b * x2 * x + c * x2 + d * x + e;
1845  return 0;
1846 }
1847 
1848 
1849 /*---------------------------------------------------------------------*
1850  * Interconversions with Pix *
1851  *---------------------------------------------------------------------*/
1868 l_ok
1870  PTA *pta,
1871  l_int32 outformat,
1872  const char *title)
1873 {
1874 char buffer[128];
1875 char *rtitle, *gtitle, *btitle;
1876 static l_int32 count = 0; /* require separate temp files for each call */
1877 l_int32 i, x, y, d, w, h, npts, rval, gval, bval;
1878 l_uint32 val;
1879 NUMA *na, *nar, *nag, *nab;
1880 PIX *pixt;
1881 
1882  PROCNAME("pixPlotAlongPta");
1883 
1884  lept_mkdir("lept/plot");
1885 
1886  if (!pixs)
1887  return ERROR_INT("pixs not defined", procName, 1);
1888  if (!pta)
1889  return ERROR_INT("pta not defined", procName, 1);
1890  if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
1891  outformat != GPLOT_EPS && outformat != GPLOT_LATEX) {
1892  L_WARNING("outformat invalid; using GPLOT_PNG\n", procName);
1893  outformat = GPLOT_PNG;
1894  }
1895 
1897  d = pixGetDepth(pixt);
1898  w = pixGetWidth(pixt);
1899  h = pixGetHeight(pixt);
1900  npts = ptaGetCount(pta);
1901  if (d == 32) {
1902  nar = numaCreate(npts);
1903  nag = numaCreate(npts);
1904  nab = numaCreate(npts);
1905  for (i = 0; i < npts; i++) {
1906  ptaGetIPt(pta, i, &x, &y);
1907  if (x < 0 || x >= w)
1908  continue;
1909  if (y < 0 || y >= h)
1910  continue;
1911  pixGetPixel(pixt, x, y, &val);
1912  rval = GET_DATA_BYTE(&val, COLOR_RED);
1913  gval = GET_DATA_BYTE(&val, COLOR_GREEN);
1914  bval = GET_DATA_BYTE(&val, COLOR_BLUE);
1915  numaAddNumber(nar, rval);
1916  numaAddNumber(nag, gval);
1917  numaAddNumber(nab, bval);
1918  }
1919 
1920  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1921  rtitle = stringJoin("Red: ", title);
1922  gplotSimple1(nar, outformat, buffer, rtitle);
1923  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1924  gtitle = stringJoin("Green: ", title);
1925  gplotSimple1(nag, outformat, buffer, gtitle);
1926  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1927  btitle = stringJoin("Blue: ", title);
1928  gplotSimple1(nab, outformat, buffer, btitle);
1929  numaDestroy(&nar);
1930  numaDestroy(&nag);
1931  numaDestroy(&nab);
1932  LEPT_FREE(rtitle);
1933  LEPT_FREE(gtitle);
1934  LEPT_FREE(btitle);
1935  } else {
1936  na = numaCreate(npts);
1937  for (i = 0; i < npts; i++) {
1938  ptaGetIPt(pta, i, &x, &y);
1939  if (x < 0 || x >= w)
1940  continue;
1941  if (y < 0 || y >= h)
1942  continue;
1943  pixGetPixel(pixt, x, y, &val);
1944  numaAddNumber(na, (l_float32)val);
1945  }
1946 
1947  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1948  gplotSimple1(na, outformat, buffer, title);
1949  numaDestroy(&na);
1950  }
1951  pixDestroy(&pixt);
1952  return 0;
1953 }
1954 
1955 
1969 PTA *
1971  BOX *box)
1972 {
1973 l_int32 i, j, w, h, wpl, xstart, xend, ystart, yend, bw, bh;
1974 l_uint32 *data, *line;
1975 PTA *pta;
1976 
1977  PROCNAME("ptaGetPixelsFromPix");
1978 
1979  if (!pixs || (pixGetDepth(pixs) != 1))
1980  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
1981 
1982  pixGetDimensions(pixs, &w, &h, NULL);
1983  data = pixGetData(pixs);
1984  wpl = pixGetWpl(pixs);
1985  xstart = ystart = 0;
1986  xend = w - 1;
1987  yend = h - 1;
1988  if (box) {
1989  boxGetGeometry(box, &xstart, &ystart, &bw, &bh);
1990  xend = xstart + bw - 1;
1991  yend = ystart + bh - 1;
1992  }
1993 
1994  if ((pta = ptaCreate(0)) == NULL)
1995  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
1996  for (i = ystart; i <= yend; i++) {
1997  line = data + i * wpl;
1998  for (j = xstart; j <= xend; j++) {
1999  if (GET_DATA_BIT(line, j))
2000  ptaAddPt(pta, j, i);
2001  }
2002  }
2003 
2004  return pta;
2005 }
2006 
2007 
2022 PIX *
2024  l_int32 w,
2025  l_int32 h)
2026 {
2027 l_int32 n, i, x, y;
2028 PIX *pix;
2029 
2030  PROCNAME("pixGenerateFromPta");
2031 
2032  if (!pta)
2033  return (PIX *)ERROR_PTR("pta not defined", procName, NULL);
2034 
2035  if ((pix = pixCreate(w, h, 1)) == NULL)
2036  return (PIX *)ERROR_PTR("pix not made", procName, NULL);
2037  n = ptaGetCount(pta);
2038  for (i = 0; i < n; i++) {
2039  ptaGetIPt(pta, i, &x, &y);
2040  if (x < 0 || x >= w || y < 0 || y >= h)
2041  continue;
2042  pixSetPixel(pix, x, y, 1);
2043  }
2044 
2045  return pix;
2046 }
2047 
2048 
2063 PTA *
2065  l_int32 type)
2066 {
2067 PIX *pixt;
2068 PTA *pta;
2069 
2070  PROCNAME("ptaGetBoundaryPixels");
2071 
2072  if (!pixs || (pixGetDepth(pixs) != 1))
2073  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2074  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2075  return (PTA *)ERROR_PTR("invalid type", procName, NULL);
2076 
2077  if (type == L_BOUNDARY_FG)
2078  pixt = pixMorphSequence(pixs, "e3.3", 0);
2079  else
2080  pixt = pixMorphSequence(pixs, "d3.3", 0);
2081  pixXor(pixt, pixt, pixs);
2082  pta = ptaGetPixelsFromPix(pixt, NULL);
2083 
2084  pixDestroy(&pixt);
2085  return pta;
2086 }
2087 
2088 
2112 PTAA *
2114  l_int32 type,
2115  l_int32 connectivity,
2116  BOXA **pboxa,
2117  PIXA **ppixa)
2118 {
2119 l_int32 i, n, w, h, x, y, bw, bh, left, right, top, bot;
2120 BOXA *boxa;
2121 PIX *pixt1, *pixt2;
2122 PIXA *pixa;
2123 PTA *pta1, *pta2;
2124 PTAA *ptaa;
2125 
2126  PROCNAME("ptaaGetBoundaryPixels");
2127 
2128  if (pboxa) *pboxa = NULL;
2129  if (ppixa) *ppixa = NULL;
2130  if (!pixs || (pixGetDepth(pixs) != 1))
2131  return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2132  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2133  return (PTAA *)ERROR_PTR("invalid type", procName, NULL);
2134  if (connectivity != 4 && connectivity != 8)
2135  return (PTAA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
2136 
2137  pixGetDimensions(pixs, &w, &h, NULL);
2138  boxa = pixConnComp(pixs, &pixa, connectivity);
2139  n = boxaGetCount(boxa);
2140  ptaa = ptaaCreate(0);
2141  for (i = 0; i < n; i++) {
2142  pixt1 = pixaGetPix(pixa, i, L_CLONE);
2143  boxaGetBoxGeometry(boxa, i, &x, &y, &bw, &bh);
2144  left = right = top = bot = 0;
2145  if (type == L_BOUNDARY_BG) {
2146  if (x > 0) left = 1;
2147  if (y > 0) top = 1;
2148  if (x + bw < w) right = 1;
2149  if (y + bh < h) bot = 1;
2150  pixt2 = pixAddBorderGeneral(pixt1, left, right, top, bot, 0);
2151  } else {
2152  pixt2 = pixClone(pixt1);
2153  }
2154  pta1 = ptaGetBoundaryPixels(pixt2, type);
2155  pta2 = ptaTransform(pta1, x - left, y - top, 1.0, 1.0);
2156  ptaaAddPta(ptaa, pta2, L_INSERT);
2157  ptaDestroy(&pta1);
2158  pixDestroy(&pixt1);
2159  pixDestroy(&pixt2);
2160  }
2161 
2162  if (pboxa)
2163  *pboxa = boxa;
2164  else
2165  boxaDestroy(&boxa);
2166  if (ppixa)
2167  *ppixa = pixa;
2168  else
2169  pixaDestroy(&pixa);
2170  return ptaa;
2171 }
2172 
2173 
2195 PTAA *
2197  l_int32 *pncc)
2198 {
2199 l_int32 wpl, index, i, j, w, h;
2200 l_uint32 maxval;
2201 l_uint32 *data, *line;
2202 PTA *pta;
2203 PTAA *ptaa;
2204 
2205  PROCNAME("ptaaIndexLabeledPixels");
2206 
2207  if (pncc) *pncc = 0;
2208  if (!pixs || (pixGetDepth(pixs) != 32))
2209  return (PTAA *)ERROR_PTR("pixs undef or not 32 bpp", procName, NULL);
2210 
2211  /* The number of c.c. is the maximum pixel value. Use this to
2212  * initialize ptaa with sufficient pta arrays */
2213  pixGetMaxValueInRect(pixs, NULL, &maxval, NULL, NULL);
2214  if (pncc) *pncc = maxval;
2215  pta = ptaCreate(1);
2216  ptaa = ptaaCreate(maxval + 1);
2217  ptaaInitFull(ptaa, pta);
2218  ptaDestroy(&pta);
2219 
2220  /* Sweep over %pixs, saving the pixel coordinates of each pixel
2221  * with nonzero value in the appropriate pta, indexed by that value. */
2222  pixGetDimensions(pixs, &w, &h, NULL);
2223  data = pixGetData(pixs);
2224  wpl = pixGetWpl(pixs);
2225  for (i = 0; i < h; i++) {
2226  line = data + wpl * i;
2227  for (j = 0; j < w; j++) {
2228  index = line[j];
2229  if (index > 0)
2230  ptaaAddPt(ptaa, index, j, i);
2231  }
2232  }
2233 
2234  return ptaa;
2235 }
2236 
2237 
2252 PTA *
2254  l_int32 x,
2255  l_int32 y,
2256  l_int32 conn)
2257 {
2258 l_int32 w, h;
2259 PTA *pta;
2260 
2261  PROCNAME("ptaGetNeighborPixLocs");
2262 
2263  if (!pixs)
2264  return (PTA *)ERROR_PTR("pixs not defined", procName, NULL);
2265  pixGetDimensions(pixs, &w, &h, NULL);
2266  if (x < 0 || x >= w || y < 0 || y >= h)
2267  return (PTA *)ERROR_PTR("(x,y) not in pixs", procName, NULL);
2268  if (conn != 4 && conn != 8)
2269  return (PTA *)ERROR_PTR("conn not 4 or 8", procName, NULL);
2270 
2271  pta = ptaCreate(conn);
2272  if (x > 0)
2273  ptaAddPt(pta, x - 1, y);
2274  if (x < w - 1)
2275  ptaAddPt(pta, x + 1, y);
2276  if (y > 0)
2277  ptaAddPt(pta, x, y - 1);
2278  if (y < h - 1)
2279  ptaAddPt(pta, x, y + 1);
2280  if (conn == 8) {
2281  if (x > 0) {
2282  if (y > 0)
2283  ptaAddPt(pta, x - 1, y - 1);
2284  if (y < h - 1)
2285  ptaAddPt(pta, x - 1, y + 1);
2286  }
2287  if (x < w - 1) {
2288  if (y > 0)
2289  ptaAddPt(pta, x + 1, y - 1);
2290  if (y < h - 1)
2291  ptaAddPt(pta, x + 1, y + 1);
2292  }
2293  }
2294 
2295  return pta;
2296 }
2297 
2298 
2299 /*---------------------------------------------------------------------*
2300  * Interconversion with Numa *
2301  *---------------------------------------------------------------------*/
2308 PTA *
2310 {
2311 l_int32 i, n;
2312 l_float32 startx, delx, val;
2313 PTA *pta;
2314 
2315  PROCNAME("numaConvertToPta1");
2316 
2317  if (!na)
2318  return (PTA *)ERROR_PTR("na not defined", procName, NULL);
2319 
2320  n = numaGetCount(na);
2321  pta = ptaCreate(n);
2322  numaGetParameters(na, &startx, &delx);
2323  for (i = 0; i < n; i++) {
2324  numaGetFValue(na, i, &val);
2325  ptaAddPt(pta, startx + i * delx, val);
2326  }
2327  return pta;
2328 }
2329 
2330 
2338 PTA *
2340  NUMA *nay)
2341 {
2342 l_int32 i, n, nx, ny;
2343 l_float32 valx, valy;
2344 PTA *pta;
2345 
2346  PROCNAME("numaConvertToPta2");
2347 
2348  if (!nax || !nay)
2349  return (PTA *)ERROR_PTR("nax and nay not both defined", procName, NULL);
2350 
2351  nx = numaGetCount(nax);
2352  ny = numaGetCount(nay);
2353  n = L_MIN(nx, ny);
2354  if (nx != ny)
2355  L_WARNING("nx = %d does not equal ny = %d\n", procName, nx, ny);
2356  pta = ptaCreate(n);
2357  for (i = 0; i < n; i++) {
2358  numaGetFValue(nax, i, &valx);
2359  numaGetFValue(nay, i, &valy);
2360  ptaAddPt(pta, valx, valy);
2361  }
2362  return pta;
2363 }
2364 
2365 
2374 l_ok
2376  NUMA **pnax,
2377  NUMA **pnay)
2378 {
2379 l_int32 i, n;
2380 l_float32 valx, valy;
2381 
2382  PROCNAME("ptaConvertToNuma");
2383 
2384  if (pnax) *pnax = NULL;
2385  if (pnay) *pnay = NULL;
2386  if (!pnax || !pnay)
2387  return ERROR_INT("&nax and &nay not both defined", procName, 1);
2388  if (!pta)
2389  return ERROR_INT("pta not defined", procName, 1);
2390 
2391  n = ptaGetCount(pta);
2392  *pnax = numaCreate(n);
2393  *pnay = numaCreate(n);
2394  for (i = 0; i < n; i++) {
2395  ptaGetPt(pta, i, &valx, &valy);
2396  numaAddNumber(*pnax, valx);
2397  numaAddNumber(*pnay, valy);
2398  }
2399  return 0;
2400 }
2401 
2402 
2403 /*---------------------------------------------------------------------*
2404  * Display Pta and Ptaa *
2405  *---------------------------------------------------------------------*/
2425 PIX *
2427  PIX *pixs,
2428  PTA *pta)
2429 {
2430 l_int32 i, n, w, h, x, y;
2431 l_uint32 rpixel, gpixel, bpixel;
2432 
2433  PROCNAME("pixDisplayPta");
2434 
2435  if (!pixs)
2436  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2437  if (!pta)
2438  return (PIX *)ERROR_PTR("pta not defined", procName, pixd);
2439  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2440  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2441 
2442  if (!pixd)
2443  pixd = pixConvertTo32(pixs);
2444  pixGetDimensions(pixd, &w, &h, NULL);
2445  composeRGBPixel(255, 0, 0, &rpixel); /* start point */
2446  composeRGBPixel(0, 255, 0, &gpixel);
2447  composeRGBPixel(0, 0, 255, &bpixel); /* end point */
2448 
2449  n = ptaGetCount(pta);
2450  for (i = 0; i < n; i++) {
2451  ptaGetIPt(pta, i, &x, &y);
2452  if (x < 0 || x >= w || y < 0 || y >= h)
2453  continue;
2454  if (i == 0)
2455  pixSetPixel(pixd, x, y, rpixel);
2456  else if (i < n - 1)
2457  pixSetPixel(pixd, x, y, gpixel);
2458  else
2459  pixSetPixel(pixd, x, y, bpixel);
2460  }
2461 
2462  return pixd;
2463 }
2464 
2465 
2491 PIX *
2493  PIX *pixs,
2494  PTAA *ptaa,
2495  PIX *pixp,
2496  l_int32 cx,
2497  l_int32 cy)
2498 {
2499 l_int32 i, n;
2500 l_uint32 color;
2501 PIXCMAP *cmap;
2502 PTA *pta;
2503 
2504  PROCNAME("pixDisplayPtaaPattern");
2505 
2506  if (!pixs)
2507  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2508  if (!ptaa)
2509  return (PIX *)ERROR_PTR("ptaa not defined", procName, pixd);
2510  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2511  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2512  if (!pixp)
2513  return (PIX *)ERROR_PTR("pixp not defined", procName, pixd);
2514 
2515  if (!pixd)
2516  pixd = pixConvertTo32(pixs);
2517 
2518  /* Use 256 random colors */
2519  cmap = pixcmapCreateRandom(8, 0, 0);
2520  n = ptaaGetCount(ptaa);
2521  for (i = 0; i < n; i++) {
2522  pixcmapGetColor32(cmap, i % 256, &color);
2523  pta = ptaaGetPta(ptaa, i, L_CLONE);
2524  pixDisplayPtaPattern(pixd, pixd, pta, pixp, cx, cy, color);
2525  ptaDestroy(&pta);
2526  }
2527 
2528  pixcmapDestroy(&cmap);
2529  return pixd;
2530 }
2531 
2532 
2558 PIX *
2560  PIX *pixs,
2561  PTA *pta,
2562  PIX *pixp,
2563  l_int32 cx,
2564  l_int32 cy,
2565  l_uint32 color)
2566 {
2567 l_int32 i, n, w, h, x, y;
2568 PTA *ptat;
2569 
2570  PROCNAME("pixDisplayPtaPattern");
2571 
2572  if (!pixs)
2573  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2574  if (!pta)
2575  return (PIX *)ERROR_PTR("pta not defined", procName, pixd);
2576  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2577  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2578  if (!pixp)
2579  return (PIX *)ERROR_PTR("pixp not defined", procName, pixd);
2580 
2581  if (!pixd)
2582  pixd = pixConvertTo32(pixs);
2583  pixGetDimensions(pixs, &w, &h, NULL);
2584  ptat = ptaReplicatePattern(pta, pixp, NULL, cx, cy, w, h);
2585 
2586  n = ptaGetCount(ptat);
2587  for (i = 0; i < n; i++) {
2588  ptaGetIPt(ptat, i, &x, &y);
2589  if (x < 0 || x >= w || y < 0 || y >= h)
2590  continue;
2591  pixSetPixel(pixd, x, y, color);
2592  }
2593 
2594  ptaDestroy(&ptat);
2595  return pixd;
2596 }
2597 
2598 
2619 PTA *
2621  PIX *pixp,
2622  PTA *ptap,
2623  l_int32 cx,
2624  l_int32 cy,
2625  l_int32 w,
2626  l_int32 h)
2627 {
2628 l_int32 i, j, n, np, x, y, xp, yp, xf, yf;
2629 PTA *ptat, *ptad;
2630 
2631  PROCNAME("ptaReplicatePattern");
2632 
2633  if (!ptas)
2634  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
2635  if (!pixp && !ptap)
2636  return (PTA *)ERROR_PTR("no pattern is defined", procName, NULL);
2637  if (pixp && ptap)
2638  L_WARNING("pixp and ptap defined; using ptap\n", procName);
2639 
2640  n = ptaGetCount(ptas);
2641  ptad = ptaCreate(n);
2642  if (ptap)
2643  ptat = ptaClone(ptap);
2644  else
2645  ptat = ptaGetPixelsFromPix(pixp, NULL);
2646  np = ptaGetCount(ptat);
2647  for (i = 0; i < n; i++) {
2648  ptaGetIPt(ptas, i, &x, &y);
2649  for (j = 0; j < np; j++) {
2650  ptaGetIPt(ptat, j, &xp, &yp);
2651  xf = x - cx + xp;
2652  yf = y - cy + yp;
2653  if (xf >= 0 && xf < w && yf >= 0 && yf < h)
2654  ptaAddPt(ptad, xf, yf);
2655  }
2656  }
2657 
2658  ptaDestroy(&ptat);
2659  return ptad;
2660 }
2661 
2662 
2671 PIX *
2673  PTAA *ptaa)
2674 {
2675 l_int32 i, j, w, h, npta, npt, x, y, rv, gv, bv;
2676 l_uint32 *pixela;
2677 NUMA *na1, *na2, *na3;
2678 PIX *pixd;
2679 PTA *pta;
2680 
2681  PROCNAME("pixDisplayPtaa");
2682 
2683  if (!pixs)
2684  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2685  if (!ptaa)
2686  return (PIX *)ERROR_PTR("ptaa not defined", procName, NULL);
2687  npta = ptaaGetCount(ptaa);
2688  if (npta == 0)
2689  return (PIX *)ERROR_PTR("no pta", procName, NULL);
2690 
2691  if ((pixd = pixConvertTo32(pixs)) == NULL)
2692  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2693  pixGetDimensions(pixd, &w, &h, NULL);
2694 
2695  /* Make a colormap for the paths */
2696  if ((pixela = (l_uint32 *)LEPT_CALLOC(npta, sizeof(l_uint32))) == NULL) {
2697  pixDestroy(&pixd);
2698  return (PIX *)ERROR_PTR("calloc fail for pixela", procName, NULL);
2699  }
2700  na1 = numaPseudorandomSequence(256, 14657);
2701  na2 = numaPseudorandomSequence(256, 34631);
2702  na3 = numaPseudorandomSequence(256, 54617);
2703  for (i = 0; i < npta; i++) {
2704  numaGetIValue(na1, i % 256, &rv);
2705  numaGetIValue(na2, i % 256, &gv);
2706  numaGetIValue(na3, i % 256, &bv);
2707  composeRGBPixel(rv, gv, bv, &pixela[i]);
2708  }
2709  numaDestroy(&na1);
2710  numaDestroy(&na2);
2711  numaDestroy(&na3);
2712 
2713  for (i = 0; i < npta; i++) {
2714  pta = ptaaGetPta(ptaa, i, L_CLONE);
2715  npt = ptaGetCount(pta);
2716  for (j = 0; j < npt; j++) {
2717  ptaGetIPt(pta, j, &x, &y);
2718  if (x < 0 || x >= w || y < 0 || y >= h)
2719  continue;
2720  pixSetPixel(pixd, x, y, pixela[i]);
2721  }
2722  ptaDestroy(&pta);
2723  }
2724 
2725  LEPT_FREE(pixela);
2726  return pixd;
2727 }
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:1828
l_int32 gaussjordan(l_float32 **a, l_float32 *b, l_int32 n)
gaussjordan()
Definition: affine.c:1344
l_ok ptaGetQuadraticLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, NUMA **pnafit)
ptaGetQuadraticLSF()
Definition: ptafunc1.c:1207
l_ok ptaConvertToNuma(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaConvertToNuma()
Definition: ptafunc1.c:2375
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:719
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218
l_ok pixPlotAlongPta(PIX *pixs, PTA *pta, l_int32 outformat, const char *title)
pixPlotAlongPta()
Definition: ptafunc1.c:1869
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PIX * pixGenerateFromPta(PTA *pta, l_int32 w, l_int32 h)
pixGenerateFromPta()
Definition: ptafunc1.c:2023
Definition: pix.h:204
l_ok ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1286
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:343
Definition: pix.h:713
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
l_ok boxContainsPt(BOX *box, l_float32 x, l_float32 y, l_int32 *pcontains)
boxContainsPt()
Definition: boxfunc1.c:1217
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:1450
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
l_ok numaGetMedian(NUMA *na, l_float32 *pval)
numaGetMedian()
Definition: numafunc1.c:3405
PIX * pixDisplayPtaaPattern(PIX *pixd, PIX *pixs, PTAA *ptaa, PIX *pixp, l_int32 cx, l_int32 cy)
pixDisplayPtaaPattern()
Definition: ptafunc1.c:2492
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:279
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:527
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
PTA * ptaGetBoundaryPixels(PIX *pixs, l_int32 type)
ptaGetBoundaryPixels()
Definition: ptafunc1.c:2064
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
l_ok ptaGetLinearLSF(PTA *pta, l_float32 *pa, l_float32 *pb, NUMA **pnafit)
ptaGetLinearLSF()
Definition: ptafunc1.c:1106
Definition: pix.h:491
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:1039
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:1802
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:167
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:1586
l_ok applyQuadraticFit(l_float32 a, l_float32 b, l_float32 c, l_float32 x, l_float32 *py)
applyQuadraticFit()
Definition: ptafunc1.c:1777
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:151
PTA * ptaSubsample(PTA *ptas, l_int32 subfactor)
ptaSubsample()
Definition: ptafunc1.c:124
NUMA * numaPseudorandomSequence(l_int32 size, l_int32 seed)
numaPseudorandomSequence()
Definition: numafunc1.c:3254
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:780
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1145
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
PTA * numaConvertToPta1(NUMA *na)
numaConvertToPta1()
Definition: ptafunc1.c:2309
Definition: array.h:70
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1688
PIX * pixDisplayPtaa(PIX *pixs, PTAA *ptaa)
pixDisplayPtaa()
Definition: ptafunc1.c:2672
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:297
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:879
Definition: pix.h:530
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:263
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
Definition: morphseq.c:137
l_ok ptaGetCubicLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pd, NUMA **pnafit)
ptaGetCubicLSF()
Definition: ptafunc1.c:1320
PTA * ptaCyclicPerm(PTA *ptas, l_int32 xs, l_int32 ys)
ptaCyclicPerm()
Definition: ptafunc1.c:333
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:548
PTA * ptaGetNeighborPixLocs(PIX *pixs, l_int32 x, l_int32 y, l_int32 conn)
ptaGetNeighborPixLocs()
Definition: ptafunc1.c:2253
PTA * ptaSelectByValue(PTA *ptas, l_float32 xth, l_float32 yth, l_int32 type, l_int32 relation)
ptaSelectByValue()
Definition: ptafunc1.c:971
l_int32 ptaContainsPt(PTA *pta, l_int32 x, l_int32 y)
ptaContainsPt()
Definition: ptafunc1.c:670
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
PTAA * ptaaGetBoundaryPixels(PIX *pixs, l_int32 type, l_int32 connectivity, BOXA **pboxa, PIXA **ppixa)
ptaaGetBoundaryPixels()
Definition: ptafunc1.c:2113
PTA * ptaGetInsideBox(PTA *ptas, BOX *box)
ptaGetInsideBox()
Definition: ptafunc1.c:538
l_float32 l_angleBetweenVectors(l_float32 x1, l_float32 y1, l_float32 x2, l_float32 y2)
l_angleBetweenVectors()
Definition: ptafunc1.c:832
l_ok ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1216
l_int32 ptaPolygonIsConvex(PTA *pta, l_int32 *pisconvex)
ptaPolygonIsConvex()
Definition: ptafunc1.c:867
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:963
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
Definition: pix.h:711
BOX * ptaGetBoundingRegion(PTA *pta)
ptaGetBoundingRegion()
Definition: ptafunc1.c:444
l_ok ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:488
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:226
Definition: pix.h:455
l_float32 * y
Definition: pix.h:521
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:190
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PTA * pixFindCornerPixels(PIX *pixs)
pixFindCornerPixels()
Definition: ptafunc1.c:578
l_ok applyLinearFit(l_float32 a, l_float32 b, l_float32 x, l_float32 *py)
applyLinearFit()
Definition: ptafunc1.c:1753
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1125
l_ok pixcmapGetColor32(PIXCMAP *cmap, l_int32 index, l_uint32 *pval32)
pixcmapGetColor32()
Definition: colormap.c:864
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2620
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
l_int32 ptaTestIntersection(PTA *pta1, PTA *pta2)
ptaTestIntersection()
Definition: ptafunc1.c:699
PTA * numaConvertToPta2(NUMA *nax, NUMA *nay)
numaConvertToPta2()
Definition: ptafunc1.c:2339
PIX * pixDisplayPta(PIX *pixd, PIX *pixs, PTA *pta)
pixDisplayPta()
Definition: ptafunc1.c:2426
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:518
Definition: pix.h:138
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
l_ok pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2352
l_ok ptaaJoin(PTAA *ptaad, PTAA *ptaas, l_int32 istart, l_int32 iend)
ptaaJoin()
Definition: ptafunc1.c:217
PTA * ptaSelectRange(PTA *ptas, l_int32 first, l_int32 last)
ptaSelectRange()
Definition: ptafunc1.c:389
PTAA * ptaaIndexLabeledPixels(PIX *pixs, l_int32 *pncc)
ptaaIndexLabeledPixels()
Definition: ptafunc1.c:2196
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:734
l_ok ptaGetMinMax(PTA *pta, l_float32 *pxmin, l_float32 *pymin, l_float32 *pxmax, l_float32 *pymax)
ptaGetMinMax()
Definition: ptafunc1.c:918
PTA * ptaTransform(PTA *ptas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
ptaTransform()
Definition: ptafunc1.c:740
PIX * pixDisplayPtaPattern(PIX *pixd, PIX *pixs, PTA *pta, PIX *pixp, l_int32 cx, l_int32 cy, l_uint32 color)
pixDisplayPtaPattern()
Definition: ptafunc1.c:2559
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:1673
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:578
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:1038
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2751
PTA * ptaReverse(PTA *ptas, l_int32 type)
ptaReverse()
Definition: ptafunc1.c:257
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1970
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:313
Definition: pix.h:480
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:976
l_ok gplotSimple1(NUMA *na, l_int32 outformat, const char *outroot, const char *title)
gplotSimple1()
Definition: gplot.c:665
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
PTA * ptaTranspose(PTA *ptas)
ptaTranspose()
Definition: ptafunc1.c:293
Definition: pix.h:516
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:172