Leptonica  1.77.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 
27 
102 #include <math.h>
103 #include "allheaders.h"
104 
105 #ifndef M_PI
106 #define M_PI 3.14159265358979323846
107 #endif /* M_PI */
108 
109 
110 /*---------------------------------------------------------------------*
111  * Simple rearrangements *
112  *---------------------------------------------------------------------*/
120 PTA *
122  l_int32 subfactor)
123 {
124 l_int32 n, i;
125 l_float32 x, y;
126 PTA *ptad;
127 
128  PROCNAME("pixSubsample");
129 
130  if (!ptas)
131  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
132  if (subfactor < 1)
133  return (PTA *)ERROR_PTR("subfactor < 1", procName, NULL);
134 
135  ptad = ptaCreate(0);
136  n = ptaGetCount(ptas);
137  for (i = 0; i < n; i++) {
138  if (i % subfactor != 0) continue;
139  ptaGetPt(ptas, i, &x, &y);
140  ptaAddPt(ptad, x, y);
141  }
142 
143  return ptad;
144 }
145 
146 
163 l_ok
164 ptaJoin(PTA *ptad,
165  PTA *ptas,
166  l_int32 istart,
167  l_int32 iend)
168 {
169 l_int32 n, i, x, y;
170 
171  PROCNAME("ptaJoin");
172 
173  if (!ptad)
174  return ERROR_INT("ptad not defined", procName, 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", procName, 1);
185 
186  for (i = istart; i <= iend; i++) {
187  ptaGetIPt(ptas, i, &x, &y);
188  ptaAddPt(ptad, x, y);
189  }
190 
191  return 0;
192 }
193 
194 
211 l_ok
212 ptaaJoin(PTAA *ptaad,
213  PTAA *ptaas,
214  l_int32 istart,
215  l_int32 iend)
216 {
217 l_int32 n, i;
218 PTA *pta;
219 
220  PROCNAME("ptaaJoin");
221 
222  if (!ptaad)
223  return ERROR_INT("ptaad not defined", procName, 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", procName, 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  PROCNAME("ptaReverse");
260 
261  if (!ptas)
262  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
263 
264  n = ptaGetCount(ptas);
265  if ((ptad = ptaCreate(n)) == NULL)
266  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
267  for (i = n - 1; i >= 0; i--) {
268  if (type == 0) {
269  ptaGetPt(ptas, i, &x, &y);
270  ptaAddPt(ptad, x, y);
271  } else { /* type == 1 */
272  ptaGetIPt(ptas, i, &ix, &iy);
273  ptaAddPt(ptad, ix, iy);
274  }
275  }
276 
277  return ptad;
278 }
279 
280 
287 PTA *
289 {
290 l_int32 n, i;
291 l_float32 x, y;
292 PTA *ptad;
293 
294  PROCNAME("ptaTranspose");
295 
296  if (!ptas)
297  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
298 
299  n = ptaGetCount(ptas);
300  if ((ptad = ptaCreate(n)) == NULL)
301  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
302  for (i = 0; i < n; i++) {
303  ptaGetPt(ptas, i, &x, &y);
304  ptaAddPt(ptad, y, x);
305  }
306 
307  return ptad;
308 }
309 
310 
327 PTA *
329  l_int32 xs,
330  l_int32 ys)
331 {
332 l_int32 n, i, x, y, j, index, state;
333 l_int32 x1, y1, x2, y2;
334 PTA *ptad;
335 
336  PROCNAME("ptaCyclicPerm");
337 
338  if (!ptas)
339  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
340 
341  n = ptaGetCount(ptas);
342 
343  /* Verify input data */
344  ptaGetIPt(ptas, 0, &x1, &y1);
345  ptaGetIPt(ptas, n - 1, &x2, &y2);
346  if (x1 != x2 || y1 != y2)
347  return (PTA *)ERROR_PTR("start and end pts not same", procName, NULL);
348  state = L_NOT_FOUND;
349  for (i = 0; i < n; i++) {
350  ptaGetIPt(ptas, i, &x, &y);
351  if (x == xs && y == ys) {
352  state = L_FOUND;
353  break;
354  }
355  }
356  if (state == L_NOT_FOUND)
357  return (PTA *)ERROR_PTR("start pt not in ptas", procName, NULL);
358 
359  if ((ptad = ptaCreate(n)) == NULL)
360  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
361  for (j = 0; j < n - 1; j++) {
362  if (i + j < n - 1)
363  index = i + j;
364  else
365  index = (i + j + 1) % n;
366  ptaGetIPt(ptas, index, &x, &y);
367  ptaAddPt(ptad, x, y);
368  }
369  ptaAddPt(ptad, xs, ys);
370 
371  return ptad;
372 }
373 
374 
383 PTA *
385  l_int32 first,
386  l_int32 last)
387 {
388 l_int32 n, npt, i;
389 l_float32 x, y;
390 PTA *ptad;
391 
392  PROCNAME("ptaSelectRange");
393 
394  if (!ptas)
395  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
396  if ((n = ptaGetCount(ptas)) == 0) {
397  L_WARNING("ptas is empty\n", procName);
398  return ptaCopy(ptas);
399  }
400  first = L_MAX(0, first);
401  if (last < 0) last = n - 1;
402  if (first >= n)
403  return (PTA *)ERROR_PTR("invalid first", procName, NULL);
404  if (last >= n) {
405  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
406  procName, last, n - 1);
407  last = n - 1;
408  }
409  if (first > last)
410  return (PTA *)ERROR_PTR("first > last", procName, NULL);
411 
412  npt = last - first + 1;
413  ptad = ptaCreate(npt);
414  for (i = first; i <= last; i++) {
415  ptaGetPt(ptas, i, &x, &y);
416  ptaAddPt(ptad, x, y);
417  }
418  return ptad;
419 }
420 
421 
422 /*---------------------------------------------------------------------*
423  * Geometric *
424  *---------------------------------------------------------------------*/
438 BOX *
440 {
441 l_int32 n, i, x, y, minx, maxx, miny, maxy;
442 
443  PROCNAME("ptaGetBoundingRegion");
444 
445  if (!pta)
446  return (BOX *)ERROR_PTR("pta not defined", procName, NULL);
447 
448  minx = 10000000;
449  miny = 10000000;
450  maxx = -10000000;
451  maxy = -10000000;
452  n = ptaGetCount(pta);
453  for (i = 0; i < n; i++) {
454  ptaGetIPt(pta, i, &x, &y);
455  if (x < minx) minx = x;
456  if (x > maxx) maxx = x;
457  if (y < miny) miny = y;
458  if (y > maxy) maxy = y;
459  }
460 
461  return boxCreate(minx, miny, maxx - minx + 1, maxy - miny + 1);
462 }
463 
464 
482 l_ok
484  l_float32 *pminx,
485  l_float32 *pmaxx,
486  l_float32 *pminy,
487  l_float32 *pmaxy)
488 {
489 l_int32 n, i;
490 l_float32 x, y, minx, maxx, miny, maxy;
491 
492  PROCNAME("ptaGetRange");
493 
494  if (!pminx && !pmaxx && !pminy && !pmaxy)
495  return ERROR_INT("no output requested", procName, 1);
496  if (pminx) *pminx = 0;
497  if (pmaxx) *pmaxx = 0;
498  if (pminy) *pminy = 0;
499  if (pmaxy) *pmaxy = 0;
500  if (!pta)
501  return ERROR_INT("pta not defined", procName, 1);
502  if ((n = ptaGetCount(pta)) == 0)
503  return ERROR_INT("no points in pta", procName, 1);
504 
505  ptaGetPt(pta, 0, &x, &y);
506  minx = x;
507  maxx = x;
508  miny = y;
509  maxy = y;
510  for (i = 1; i < n; i++) {
511  ptaGetPt(pta, i, &x, &y);
512  if (x < minx) minx = x;
513  if (x > maxx) maxx = x;
514  if (y < miny) miny = y;
515  if (y > maxy) maxy = y;
516  }
517  if (pminx) *pminx = minx;
518  if (pmaxx) *pmaxx = maxx;
519  if (pminy) *pminy = miny;
520  if (pmaxy) *pmaxy = maxy;
521  return 0;
522 }
523 
524 
532 PTA *
534  BOX *box)
535 {
536 PTA *ptad;
537 l_int32 n, i, contains;
538 l_float32 x, y;
539 
540  PROCNAME("ptaGetInsideBox");
541 
542  if (!ptas)
543  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
544  if (!box)
545  return (PTA *)ERROR_PTR("box not defined", procName, NULL);
546 
547  n = ptaGetCount(ptas);
548  ptad = ptaCreate(0);
549  for (i = 0; i < n; i++) {
550  ptaGetPt(ptas, i, &x, &y);
551  boxContainsPt(box, x, y, &contains);
552  if (contains)
553  ptaAddPt(ptad, x, y);
554  }
555 
556  return ptad;
557 }
558 
559 
572 PTA *
574 {
575 l_int32 i, j, x, y, w, h, wpl, mindim, found;
576 l_uint32 *data, *line;
577 PTA *pta;
578 
579  PROCNAME("pixFindCornerPixels");
580 
581  if (!pixs)
582  return (PTA *)ERROR_PTR("pixs not defined", procName, NULL);
583  if (pixGetDepth(pixs) != 1)
584  return (PTA *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
585 
586  w = pixGetWidth(pixs);
587  h = pixGetHeight(pixs);
588  mindim = L_MIN(w, h);
589  data = pixGetData(pixs);
590  wpl = pixGetWpl(pixs);
591 
592  if ((pta = ptaCreate(4)) == NULL)
593  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
594 
595  for (found = FALSE, i = 0; i < mindim; i++) {
596  for (j = 0; j <= i; j++) {
597  y = i - j;
598  line = data + y * wpl;
599  if (GET_DATA_BIT(line, j)) {
600  ptaAddPt(pta, j, y);
601  found = TRUE;
602  break;
603  }
604  }
605  if (found == TRUE)
606  break;
607  }
608 
609  for (found = FALSE, i = 0; i < mindim; i++) {
610  for (j = 0; j <= i; j++) {
611  y = i - j;
612  line = data + y * wpl;
613  x = w - 1 - j;
614  if (GET_DATA_BIT(line, x)) {
615  ptaAddPt(pta, x, y);
616  found = TRUE;
617  break;
618  }
619  }
620  if (found == TRUE)
621  break;
622  }
623 
624  for (found = FALSE, i = 0; i < mindim; i++) {
625  for (j = 0; j <= i; j++) {
626  y = h - 1 - i + j;
627  line = data + y * wpl;
628  if (GET_DATA_BIT(line, j)) {
629  ptaAddPt(pta, j, y);
630  found = TRUE;
631  break;
632  }
633  }
634  if (found == TRUE)
635  break;
636  }
637 
638  for (found = FALSE, i = 0; i < mindim; i++) {
639  for (j = 0; j <= i; j++) {
640  y = h - 1 - i + j;
641  line = data + y * wpl;
642  x = w - 1 - j;
643  if (GET_DATA_BIT(line, x)) {
644  ptaAddPt(pta, x, y);
645  found = TRUE;
646  break;
647  }
648  }
649  if (found == TRUE)
650  break;
651  }
652 
653  return pta;
654 }
655 
656 
664 l_int32
666  l_int32 x,
667  l_int32 y)
668 {
669 l_int32 i, n, ix, iy;
670 
671  PROCNAME("ptaContainsPt");
672 
673  if (!pta)
674  return ERROR_INT("pta not defined", procName, 0);
675 
676  n = ptaGetCount(pta);
677  for (i = 0; i < n; i++) {
678  ptaGetIPt(pta, i, &ix, &iy);
679  if (x == ix && y == iy)
680  return 1;
681  }
682  return 0;
683 }
684 
685 
693 l_int32
695  PTA *pta2)
696 {
697 l_int32 i, j, n1, n2, x1, y1, x2, y2;
698 
699  PROCNAME("ptaTestIntersection");
700 
701  if (!pta1)
702  return ERROR_INT("pta1 not defined", procName, 0);
703  if (!pta2)
704  return ERROR_INT("pta2 not defined", procName, 0);
705 
706  n1 = ptaGetCount(pta1);
707  n2 = ptaGetCount(pta2);
708  for (i = 0; i < n1; i++) {
709  ptaGetIPt(pta1, i, &x1, &y1);
710  for (j = 0; j < n2; j++) {
711  ptaGetIPt(pta2, i, &x2, &y2);
712  if (x1 == x2 && y1 == y2)
713  return 1;
714  }
715  }
716 
717  return 0;
718 }
719 
720 
734 PTA *
736  l_int32 shiftx,
737  l_int32 shifty,
738  l_float32 scalex,
739  l_float32 scaley)
740 {
741 l_int32 n, i, x, y;
742 PTA *ptad;
743 
744  PROCNAME("ptaTransform");
745 
746  if (!ptas)
747  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
748  n = ptaGetCount(ptas);
749  ptad = ptaCreate(n);
750  for (i = 0; i < n; i++) {
751  ptaGetIPt(ptas, i, &x, &y);
752  x = (l_int32)(scalex * (x + shiftx) + 0.5);
753  y = (l_int32)(scaley * (y + shifty) + 0.5);
754  ptaAddPt(ptad, x, y);
755  }
756 
757  return ptad;
758 }
759 
760 
774 l_int32
776  l_float32 x,
777  l_float32 y,
778  l_int32 *pinside)
779 {
780 l_int32 i, n;
781 l_float32 sum, x1, y1, x2, y2, xp1, yp1, xp2, yp2;
782 
783  PROCNAME("ptaPtInsidePolygon");
784 
785  if (!pinside)
786  return ERROR_INT("&inside not defined", procName, 1);
787  *pinside = 0;
788  if (!pta)
789  return ERROR_INT("pta not defined", procName, 1);
790 
791  /* Think of (x1,y1) as the end point of a vector that starts
792  * from the origin (0,0), and ditto for (x2,y2). */
793  n = ptaGetCount(pta);
794  sum = 0.0;
795  for (i = 0; i < n; i++) {
796  ptaGetPt(pta, i, &xp1, &yp1);
797  ptaGetPt(pta, (i + 1) % n, &xp2, &yp2);
798  x1 = xp1 - x;
799  y1 = yp1 - y;
800  x2 = xp2 - x;
801  y2 = yp2 - y;
802  sum += l_angleBetweenVectors(x1, y1, x2, y2);
803  }
804 
805  if (L_ABS(sum) > M_PI)
806  *pinside = 1;
807  return 0;
808 }
809 
810 
826 l_float32
828  l_float32 y1,
829  l_float32 x2,
830  l_float32 y2)
831 {
832 l_float64 ang;
833 
834  ang = atan2(y2, x2) - atan2(y1, x1);
835  if (ang > M_PI) ang -= 2.0 * M_PI;
836  if (ang < -M_PI) ang += 2.0 * M_PI;
837  return ang;
838 }
839 
840 
841 /*---------------------------------------------------------------------*
842  * Min/max and filtering *
843  *---------------------------------------------------------------------*/
855 l_ok
857  l_float32 *pxmin,
858  l_float32 *pymin,
859  l_float32 *pxmax,
860  l_float32 *pymax)
861 {
862 l_int32 i, n;
863 l_float32 x, y, xmin, ymin, xmax, ymax;
864 
865  PROCNAME("ptaGetMinMax");
866 
867  if (pxmin) *pxmin = -1.0;
868  if (pymin) *pymin = -1.0;
869  if (pxmax) *pxmax = -1.0;
870  if (pymax) *pymax = -1.0;
871  if (!pta)
872  return ERROR_INT("pta not defined", procName, 1);
873  if (!pxmin && !pxmax && !pymin && !pymax)
874  return ERROR_INT("no output requested", procName, 1);
875  if ((n = ptaGetCount(pta)) == 0) {
876  L_WARNING("pta is empty\n", procName);
877  return 0;
878  }
879 
880  xmin = ymin = 1.0e20;
881  xmax = ymax = -1.0e20;
882  for (i = 0; i < n; i++) {
883  ptaGetPt(pta, i, &x, &y);
884  if (x < xmin) xmin = x;
885  if (y < ymin) ymin = y;
886  if (x > xmax) xmax = x;
887  if (y > ymax) ymax = y;
888  }
889  if (pxmin) *pxmin = xmin;
890  if (pymin) *pymin = ymin;
891  if (pxmax) *pxmax = xmax;
892  if (pymax) *pymax = ymax;
893  return 0;
894 }
895 
896 
908 PTA *
910  l_float32 xth,
911  l_float32 yth,
912  l_int32 type,
913  l_int32 relation)
914 {
915 l_int32 i, n;
916 l_float32 x, y;
917 PTA *ptad;
918 
919  PROCNAME("ptaSelectByValue");
920 
921  if (!ptas)
922  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
923  if (ptaGetCount(ptas) == 0) {
924  L_WARNING("ptas is empty\n", procName);
925  return ptaCopy(ptas);
926  }
927  if (type != L_SELECT_XVAL && type != L_SELECT_YVAL &&
928  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
929  return (PTA *)ERROR_PTR("invalid type", procName, NULL);
930  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
931  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
932  return (PTA *)ERROR_PTR("invalid relation", procName, NULL);
933 
934  n = ptaGetCount(ptas);
935  ptad = ptaCreate(n);
936  for (i = 0; i < n; i++) {
937  ptaGetPt(ptas, i, &x, &y);
938  if (type == L_SELECT_XVAL) {
939  if ((relation == L_SELECT_IF_LT && x < xth) ||
940  (relation == L_SELECT_IF_GT && x > xth) ||
941  (relation == L_SELECT_IF_LTE && x <= xth) ||
942  (relation == L_SELECT_IF_GTE && x >= xth))
943  ptaAddPt(ptad, x, y);
944  } else if (type == L_SELECT_YVAL) {
945  if ((relation == L_SELECT_IF_LT && y < yth) ||
946  (relation == L_SELECT_IF_GT && y > yth) ||
947  (relation == L_SELECT_IF_LTE && y <= yth) ||
948  (relation == L_SELECT_IF_GTE && y >= yth))
949  ptaAddPt(ptad, x, y);
950  } else if (type == L_SELECT_IF_EITHER) {
951  if (((relation == L_SELECT_IF_LT) && (x < xth || y < yth)) ||
952  ((relation == L_SELECT_IF_GT) && (x > xth || y > yth)) ||
953  ((relation == L_SELECT_IF_LTE) && (x <= xth || y <= yth)) ||
954  ((relation == L_SELECT_IF_GTE) && (x >= xth || y >= yth)))
955  ptaAddPt(ptad, x, y);
956  } else { /* L_SELECT_IF_BOTH */
957  if (((relation == L_SELECT_IF_LT) && (x < xth && y < yth)) ||
958  ((relation == L_SELECT_IF_GT) && (x > xth && y > yth)) ||
959  ((relation == L_SELECT_IF_LTE) && (x <= xth && y <= yth)) ||
960  ((relation == L_SELECT_IF_GTE) && (x >= xth && y >= yth)))
961  ptaAddPt(ptad, x, y);
962  }
963  }
964 
965  return ptad;
966 }
967 
968 
976 PTA *
978  PIX *pixm)
979 {
980 l_int32 i, n, x, y;
981 l_uint32 val;
982 PTA *ptad;
983 
984  PROCNAME("ptaCropToMask");
985 
986  if (!ptas)
987  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
988  if (!pixm || pixGetDepth(pixm) != 1)
989  return (PTA *)ERROR_PTR("pixm undefined or not 1 bpp", procName, NULL);
990  if (ptaGetCount(ptas) == 0) {
991  L_INFO("ptas is empty\n", procName);
992  return ptaCopy(ptas);
993  }
994 
995  n = ptaGetCount(ptas);
996  ptad = ptaCreate(n);
997  for (i = 0; i < n; i++) {
998  ptaGetIPt(ptas, i, &x, &y);
999  pixGetPixel(pixm, x, y, &val);
1000  if (val == 1)
1001  ptaAddPt(ptad, x, y);
1002  }
1003  return ptad;
1004 }
1005 
1006 
1007 /*---------------------------------------------------------------------*
1008  * Least Squares Fit *
1009  *---------------------------------------------------------------------*/
1043 l_ok
1045  l_float32 *pa,
1046  l_float32 *pb,
1047  NUMA **pnafit)
1048 {
1049 l_int32 n, i;
1050 l_float32 a, b, factor, sx, sy, sxx, sxy, val;
1051 l_float32 *xa, *ya;
1052 
1053  PROCNAME("ptaGetLinearLSF");
1054 
1055  if (pa) *pa = 0.0;
1056  if (pb) *pb = 0.0;
1057  if (pnafit) *pnafit = NULL;
1058  if (!pa && !pb && !pnafit)
1059  return ERROR_INT("no output requested", procName, 1);
1060  if (!pta)
1061  return ERROR_INT("pta not defined", procName, 1);
1062  if ((n = ptaGetCount(pta)) < 2)
1063  return ERROR_INT("less than 2 pts found", procName, 1);
1064 
1065  xa = pta->x; /* not a copy */
1066  ya = pta->y; /* not a copy */
1067  sx = sy = sxx = sxy = 0.;
1068  if (pa && pb) { /* general line */
1069  for (i = 0; i < n; i++) {
1070  sx += xa[i];
1071  sy += ya[i];
1072  sxx += xa[i] * xa[i];
1073  sxy += xa[i] * ya[i];
1074  }
1075  factor = n * sxx - sx * sx;
1076  if (factor == 0.0)
1077  return ERROR_INT("no solution found", procName, 1);
1078  factor = 1. / factor;
1079 
1080  a = factor * ((l_float32)n * sxy - sx * sy);
1081  b = factor * (sxx * sy - sx * sxy);
1082  } else if (pa) { /* b = 0; line through origin */
1083  for (i = 0; i < n; i++) {
1084  sxx += xa[i] * xa[i];
1085  sxy += xa[i] * ya[i];
1086  }
1087  if (sxx == 0.0)
1088  return ERROR_INT("no solution found", procName, 1);
1089  a = sxy / sxx;
1090  b = 0.0;
1091  } else { /* a = 0; horizontal line */
1092  for (i = 0; i < n; i++)
1093  sy += ya[i];
1094  a = 0.0;
1095  b = sy / (l_float32)n;
1096  }
1097 
1098  if (pnafit) {
1099  *pnafit = numaCreate(n);
1100  for (i = 0; i < n; i++) {
1101  val = a * xa[i] + b;
1102  numaAddNumber(*pnafit, val);
1103  }
1104  }
1105 
1106  if (pa) *pa = a;
1107  if (pb) *pb = b;
1108  return 0;
1109 }
1110 
1111 
1144 l_ok
1146  l_float32 *pa,
1147  l_float32 *pb,
1148  l_float32 *pc,
1149  NUMA **pnafit)
1150 {
1151 l_int32 n, i, ret;
1152 l_float32 x, y, sx, sy, sx2, sx3, sx4, sxy, sx2y;
1153 l_float32 *xa, *ya;
1154 l_float32 *f[3];
1155 l_float32 g[3];
1156 
1157  PROCNAME("ptaGetQuadraticLSF");
1158 
1159  if (pa) *pa = 0.0;
1160  if (pb) *pb = 0.0;
1161  if (pc) *pc = 0.0;
1162  if (pnafit) *pnafit = NULL;
1163  if (!pa && !pb && !pc && !pnafit)
1164  return ERROR_INT("no output requested", procName, 1);
1165  if (!pta)
1166  return ERROR_INT("pta not defined", procName, 1);
1167  if ((n = ptaGetCount(pta)) < 3)
1168  return ERROR_INT("less than 3 pts found", procName, 1);
1169 
1170  xa = pta->x; /* not a copy */
1171  ya = pta->y; /* not a copy */
1172  sx = sy = sx2 = sx3 = sx4 = sxy = sx2y = 0.;
1173  for (i = 0; i < n; i++) {
1174  x = xa[i];
1175  y = ya[i];
1176  sx += x;
1177  sy += y;
1178  sx2 += x * x;
1179  sx3 += x * x * x;
1180  sx4 += x * x * x * x;
1181  sxy += x * y;
1182  sx2y += x * x * y;
1183  }
1184 
1185  for (i = 0; i < 3; i++)
1186  f[i] = (l_float32 *)LEPT_CALLOC(3, sizeof(l_float32));
1187  f[0][0] = sx4;
1188  f[0][1] = sx3;
1189  f[0][2] = sx2;
1190  f[1][0] = sx3;
1191  f[1][1] = sx2;
1192  f[1][2] = sx;
1193  f[2][0] = sx2;
1194  f[2][1] = sx;
1195  f[2][2] = n;
1196  g[0] = sx2y;
1197  g[1] = sxy;
1198  g[2] = sy;
1199 
1200  /* Solve for the unknowns, also putting f-inverse into f */
1201  ret = gaussjordan(f, g, 3);
1202  for (i = 0; i < 3; i++)
1203  LEPT_FREE(f[i]);
1204  if (ret)
1205  return ERROR_INT("quadratic solution failed", procName, 1);
1206 
1207  if (pa) *pa = g[0];
1208  if (pb) *pb = g[1];
1209  if (pc) *pc = g[2];
1210  if (pnafit) {
1211  *pnafit = numaCreate(n);
1212  for (i = 0; i < n; i++) {
1213  x = xa[i];
1214  y = g[0] * x * x + g[1] * x + g[2];
1215  numaAddNumber(*pnafit, y);
1216  }
1217  }
1218  return 0;
1219 }
1220 
1221 
1257 l_ok
1259  l_float32 *pa,
1260  l_float32 *pb,
1261  l_float32 *pc,
1262  l_float32 *pd,
1263  NUMA **pnafit)
1264 {
1265 l_int32 n, i, ret;
1266 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sxy, sx2y, sx3y;
1267 l_float32 *xa, *ya;
1268 l_float32 *f[4];
1269 l_float32 g[4];
1270 
1271  PROCNAME("ptaGetCubicLSF");
1272 
1273  if (pa) *pa = 0.0;
1274  if (pb) *pb = 0.0;
1275  if (pc) *pc = 0.0;
1276  if (pd) *pd = 0.0;
1277  if (pnafit) *pnafit = NULL;
1278  if (!pa && !pb && !pc && !pd && !pnafit)
1279  return ERROR_INT("no output requested", procName, 1);
1280  if (!pta)
1281  return ERROR_INT("pta not defined", procName, 1);
1282  if ((n = ptaGetCount(pta)) < 4)
1283  return ERROR_INT("less than 4 pts found", procName, 1);
1284 
1285  xa = pta->x; /* not a copy */
1286  ya = pta->y; /* not a copy */
1287  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sxy = sx2y = sx3y = 0.;
1288  for (i = 0; i < n; i++) {
1289  x = xa[i];
1290  y = ya[i];
1291  sx += x;
1292  sy += y;
1293  sx2 += x * x;
1294  sx3 += x * x * x;
1295  sx4 += x * x * x * x;
1296  sx5 += x * x * x * x * x;
1297  sx6 += x * x * x * x * x * x;
1298  sxy += x * y;
1299  sx2y += x * x * y;
1300  sx3y += x * x * x * y;
1301  }
1302 
1303  for (i = 0; i < 4; i++)
1304  f[i] = (l_float32 *)LEPT_CALLOC(4, sizeof(l_float32));
1305  f[0][0] = sx6;
1306  f[0][1] = sx5;
1307  f[0][2] = sx4;
1308  f[0][3] = sx3;
1309  f[1][0] = sx5;
1310  f[1][1] = sx4;
1311  f[1][2] = sx3;
1312  f[1][3] = sx2;
1313  f[2][0] = sx4;
1314  f[2][1] = sx3;
1315  f[2][2] = sx2;
1316  f[2][3] = sx;
1317  f[3][0] = sx3;
1318  f[3][1] = sx2;
1319  f[3][2] = sx;
1320  f[3][3] = n;
1321  g[0] = sx3y;
1322  g[1] = sx2y;
1323  g[2] = sxy;
1324  g[3] = sy;
1325 
1326  /* Solve for the unknowns, also putting f-inverse into f */
1327  ret = gaussjordan(f, g, 4);
1328  for (i = 0; i < 4; i++)
1329  LEPT_FREE(f[i]);
1330  if (ret)
1331  return ERROR_INT("cubic solution failed", procName, 1);
1332 
1333  if (pa) *pa = g[0];
1334  if (pb) *pb = g[1];
1335  if (pc) *pc = g[2];
1336  if (pd) *pd = g[3];
1337  if (pnafit) {
1338  *pnafit = numaCreate(n);
1339  for (i = 0; i < n; i++) {
1340  x = xa[i];
1341  y = g[0] * x * x * x + g[1] * x * x + g[2] * x + g[3];
1342  numaAddNumber(*pnafit, y);
1343  }
1344  }
1345  return 0;
1346 }
1347 
1348 
1387 l_ok
1389  l_float32 *pa,
1390  l_float32 *pb,
1391  l_float32 *pc,
1392  l_float32 *pd,
1393  l_float32 *pe,
1394  NUMA **pnafit)
1395 {
1396 l_int32 n, i, ret;
1397 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sx7, sx8;
1398 l_float32 sxy, sx2y, sx3y, sx4y;
1399 l_float32 *xa, *ya;
1400 l_float32 *f[5];
1401 l_float32 g[5];
1402 
1403  PROCNAME("ptaGetQuarticLSF");
1404 
1405  if (pa) *pa = 0.0;
1406  if (pb) *pb = 0.0;
1407  if (pc) *pc = 0.0;
1408  if (pd) *pd = 0.0;
1409  if (pe) *pe = 0.0;
1410  if (pnafit) *pnafit = NULL;
1411  if (!pa && !pb && !pc && !pd && !pe && !pnafit)
1412  return ERROR_INT("no output requested", procName, 1);
1413  if (!pta)
1414  return ERROR_INT("pta not defined", procName, 1);
1415  if ((n = ptaGetCount(pta)) < 5)
1416  return ERROR_INT("less than 5 pts found", procName, 1);
1417 
1418  xa = pta->x; /* not a copy */
1419  ya = pta->y; /* not a copy */
1420  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sx7 = sx8 = 0;
1421  sxy = sx2y = sx3y = sx4y = 0.;
1422  for (i = 0; i < n; i++) {
1423  x = xa[i];
1424  y = ya[i];
1425  sx += x;
1426  sy += y;
1427  sx2 += x * x;
1428  sx3 += x * x * x;
1429  sx4 += x * x * x * x;
1430  sx5 += x * x * x * x * x;
1431  sx6 += x * x * x * x * x * x;
1432  sx7 += x * x * x * x * x * x * x;
1433  sx8 += x * x * x * x * x * x * x * x;
1434  sxy += x * y;
1435  sx2y += x * x * y;
1436  sx3y += x * x * x * y;
1437  sx4y += x * x * x * x * y;
1438  }
1439 
1440  for (i = 0; i < 5; i++)
1441  f[i] = (l_float32 *)LEPT_CALLOC(5, sizeof(l_float32));
1442  f[0][0] = sx8;
1443  f[0][1] = sx7;
1444  f[0][2] = sx6;
1445  f[0][3] = sx5;
1446  f[0][4] = sx4;
1447  f[1][0] = sx7;
1448  f[1][1] = sx6;
1449  f[1][2] = sx5;
1450  f[1][3] = sx4;
1451  f[1][4] = sx3;
1452  f[2][0] = sx6;
1453  f[2][1] = sx5;
1454  f[2][2] = sx4;
1455  f[2][3] = sx3;
1456  f[2][4] = sx2;
1457  f[3][0] = sx5;
1458  f[3][1] = sx4;
1459  f[3][2] = sx3;
1460  f[3][3] = sx2;
1461  f[3][4] = sx;
1462  f[4][0] = sx4;
1463  f[4][1] = sx3;
1464  f[4][2] = sx2;
1465  f[4][3] = sx;
1466  f[4][4] = n;
1467  g[0] = sx4y;
1468  g[1] = sx3y;
1469  g[2] = sx2y;
1470  g[3] = sxy;
1471  g[4] = sy;
1472 
1473  /* Solve for the unknowns, also putting f-inverse into f */
1474  ret = gaussjordan(f, g, 5);
1475  for (i = 0; i < 5; i++)
1476  LEPT_FREE(f[i]);
1477  if (ret)
1478  return ERROR_INT("quartic solution failed", procName, 1);
1479 
1480  if (pa) *pa = g[0];
1481  if (pb) *pb = g[1];
1482  if (pc) *pc = g[2];
1483  if (pd) *pd = g[3];
1484  if (pe) *pe = g[4];
1485  if (pnafit) {
1486  *pnafit = numaCreate(n);
1487  for (i = 0; i < n; i++) {
1488  x = xa[i];
1489  y = g[0] * x * x * x * x + g[1] * x * x * x + g[2] * x * x
1490  + g[3] * x + g[4];
1491  numaAddNumber(*pnafit, y);
1492  }
1493  }
1494  return 0;
1495 }
1496 
1497 
1523 l_ok
1525  l_float32 factor,
1526  PTA **pptad,
1527  l_float32 *pa,
1528  l_float32 *pb,
1529  l_float32 *pmederr,
1530  NUMA **pnafit)
1531 {
1532 l_int32 n, i, ret;
1533 l_float32 x, y, yf, val, mederr;
1534 NUMA *nafit, *naerror;
1535 PTA *ptad;
1536 
1537  PROCNAME("ptaNoisyLinearLSF");
1538 
1539  if (pptad) *pptad = NULL;
1540  if (pa) *pa = 0.0;
1541  if (pb) *pb = 0.0;
1542  if (pmederr) *pmederr = 0.0;
1543  if (pnafit) *pnafit = NULL;
1544  if (!pptad && !pa && !pb && !pnafit)
1545  return ERROR_INT("no output requested", procName, 1);
1546  if (!pta)
1547  return ERROR_INT("pta not defined", procName, 1);
1548  if (factor <= 0.0)
1549  return ERROR_INT("factor must be > 0.0", procName, 1);
1550  if ((n = ptaGetCount(pta)) < 3)
1551  return ERROR_INT("less than 2 pts found", procName, 1);
1552 
1553  if (ptaGetLinearLSF(pta, pa, pb, &nafit) != 0)
1554  return ERROR_INT("error in linear LSF", procName, 1);
1555 
1556  /* Get the median error */
1557  naerror = numaCreate(n);
1558  for (i = 0; i < n; i++) {
1559  ptaGetPt(pta, i, &x, &y);
1560  numaGetFValue(nafit, i, &yf);
1561  numaAddNumber(naerror, L_ABS(y - yf));
1562  }
1563  numaGetMedian(naerror, &mederr);
1564  if (pmederr) *pmederr = mederr;
1565  numaDestroy(&nafit);
1566 
1567  /* Remove outliers */
1568  ptad = ptaCreate(n);
1569  for (i = 0; i < n; i++) {
1570  ptaGetPt(pta, i, &x, &y);
1571  numaGetFValue(naerror, i, &val);
1572  if (val <= factor * mederr) /* <= in case mederr = 0 */
1573  ptaAddPt(ptad, x, y);
1574  }
1575  numaDestroy(&naerror);
1576 
1577  /* Do LSF again */
1578  ret = ptaGetLinearLSF(ptad, pa, pb, pnafit);
1579  if (pptad)
1580  *pptad = ptad;
1581  else
1582  ptaDestroy(&ptad);
1583 
1584  return ret;
1585 }
1586 
1587 
1610 l_ok
1612  l_float32 factor,
1613  PTA **pptad,
1614  l_float32 *pa,
1615  l_float32 *pb,
1616  l_float32 *pc,
1617  l_float32 *pmederr,
1618  NUMA **pnafit)
1619 {
1620 l_int32 n, i, ret;
1621 l_float32 x, y, yf, val, mederr;
1622 NUMA *nafit, *naerror;
1623 PTA *ptad;
1624 
1625  PROCNAME("ptaNoisyQuadraticLSF");
1626 
1627  if (pptad) *pptad = NULL;
1628  if (pa) *pa = 0.0;
1629  if (pb) *pb = 0.0;
1630  if (pc) *pc = 0.0;
1631  if (pmederr) *pmederr = 0.0;
1632  if (pnafit) *pnafit = NULL;
1633  if (!pptad && !pa && !pb && !pc && !pnafit)
1634  return ERROR_INT("no output requested", procName, 1);
1635  if (factor <= 0.0)
1636  return ERROR_INT("factor must be > 0.0", procName, 1);
1637  if (!pta)
1638  return ERROR_INT("pta not defined", procName, 1);
1639  if ((n = ptaGetCount(pta)) < 3)
1640  return ERROR_INT("less than 3 pts found", procName, 1);
1641 
1642  if (ptaGetQuadraticLSF(pta, NULL, NULL, NULL, &nafit) != 0)
1643  return ERROR_INT("error in quadratic LSF", procName, 1);
1644 
1645  /* Get the median error */
1646  naerror = numaCreate(n);
1647  for (i = 0; i < n; i++) {
1648  ptaGetPt(pta, i, &x, &y);
1649  numaGetFValue(nafit, i, &yf);
1650  numaAddNumber(naerror, L_ABS(y - yf));
1651  }
1652  numaGetMedian(naerror, &mederr);
1653  if (pmederr) *pmederr = mederr;
1654  numaDestroy(&nafit);
1655 
1656  /* Remove outliers */
1657  ptad = ptaCreate(n);
1658  for (i = 0; i < n; i++) {
1659  ptaGetPt(pta, i, &x, &y);
1660  numaGetFValue(naerror, i, &val);
1661  if (val <= factor * mederr) /* <= in case mederr = 0 */
1662  ptaAddPt(ptad, x, y);
1663  }
1664  numaDestroy(&naerror);
1665  n = ptaGetCount(ptad);
1666  if ((n = ptaGetCount(ptad)) < 3) {
1667  ptaDestroy(&ptad);
1668  return ERROR_INT("less than 3 pts found", procName, 1);
1669  }
1670 
1671  /* Do LSF again */
1672  ret = ptaGetQuadraticLSF(ptad, pa, pb, pc, pnafit);
1673  if (pptad)
1674  *pptad = ptad;
1675  else
1676  ptaDestroy(&ptad);
1677 
1678  return ret;
1679 }
1680 
1681 
1690 l_ok
1691 applyLinearFit(l_float32 a,
1692  l_float32 b,
1693  l_float32 x,
1694  l_float32 *py)
1695 {
1696  PROCNAME("applyLinearFit");
1697 
1698  if (!py)
1699  return ERROR_INT("&y not defined", procName, 1);
1700 
1701  *py = a * x + b;
1702  return 0;
1703 }
1704 
1705 
1714 l_ok
1715 applyQuadraticFit(l_float32 a,
1716  l_float32 b,
1717  l_float32 c,
1718  l_float32 x,
1719  l_float32 *py)
1720 {
1721  PROCNAME("applyQuadraticFit");
1722 
1723  if (!py)
1724  return ERROR_INT("&y not defined", procName, 1);
1725 
1726  *py = a * x * x + b * x + c;
1727  return 0;
1728 }
1729 
1730 
1739 l_ok
1740 applyCubicFit(l_float32 a,
1741  l_float32 b,
1742  l_float32 c,
1743  l_float32 d,
1744  l_float32 x,
1745  l_float32 *py)
1746 {
1747  PROCNAME("applyCubicFit");
1748 
1749  if (!py)
1750  return ERROR_INT("&y not defined", procName, 1);
1751 
1752  *py = a * x * x * x + b * x * x + c * x + d;
1753  return 0;
1754 }
1755 
1756 
1765 l_ok
1766 applyQuarticFit(l_float32 a,
1767  l_float32 b,
1768  l_float32 c,
1769  l_float32 d,
1770  l_float32 e,
1771  l_float32 x,
1772  l_float32 *py)
1773 {
1774 l_float32 x2;
1775 
1776  PROCNAME("applyQuarticFit");
1777 
1778  if (!py)
1779  return ERROR_INT("&y not defined", procName, 1);
1780 
1781  x2 = x * x;
1782  *py = a * x2 * x2 + b * x2 * x + c * x2 + d * x + e;
1783  return 0;
1784 }
1785 
1786 
1787 /*---------------------------------------------------------------------*
1788  * Interconversions with Pix *
1789  *---------------------------------------------------------------------*/
1806 l_ok
1808  PTA *pta,
1809  l_int32 outformat,
1810  const char *title)
1811 {
1812 char buffer[128];
1813 char *rtitle, *gtitle, *btitle;
1814 static l_int32 count = 0; /* require separate temp files for each call */
1815 l_int32 i, x, y, d, w, h, npts, rval, gval, bval;
1816 l_uint32 val;
1817 NUMA *na, *nar, *nag, *nab;
1818 PIX *pixt;
1819 
1820  PROCNAME("pixPlotAlongPta");
1821 
1822  lept_mkdir("lept/plot");
1823 
1824  if (!pixs)
1825  return ERROR_INT("pixs not defined", procName, 1);
1826  if (!pta)
1827  return ERROR_INT("pta not defined", procName, 1);
1828  if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
1829  outformat != GPLOT_EPS && outformat != GPLOT_LATEX) {
1830  L_WARNING("outformat invalid; using GPLOT_PNG\n", procName);
1831  outformat = GPLOT_PNG;
1832  }
1833 
1835  d = pixGetDepth(pixt);
1836  w = pixGetWidth(pixt);
1837  h = pixGetHeight(pixt);
1838  npts = ptaGetCount(pta);
1839  if (d == 32) {
1840  nar = numaCreate(npts);
1841  nag = numaCreate(npts);
1842  nab = numaCreate(npts);
1843  for (i = 0; i < npts; i++) {
1844  ptaGetIPt(pta, i, &x, &y);
1845  if (x < 0 || x >= w)
1846  continue;
1847  if (y < 0 || y >= h)
1848  continue;
1849  pixGetPixel(pixt, x, y, &val);
1850  rval = GET_DATA_BYTE(&val, COLOR_RED);
1851  gval = GET_DATA_BYTE(&val, COLOR_GREEN);
1852  bval = GET_DATA_BYTE(&val, COLOR_BLUE);
1853  numaAddNumber(nar, rval);
1854  numaAddNumber(nag, gval);
1855  numaAddNumber(nab, bval);
1856  }
1857 
1858  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1859  rtitle = stringJoin("Red: ", title);
1860  gplotSimple1(nar, outformat, buffer, rtitle);
1861  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1862  gtitle = stringJoin("Green: ", title);
1863  gplotSimple1(nag, outformat, buffer, gtitle);
1864  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1865  btitle = stringJoin("Blue: ", title);
1866  gplotSimple1(nab, outformat, buffer, btitle);
1867  numaDestroy(&nar);
1868  numaDestroy(&nag);
1869  numaDestroy(&nab);
1870  LEPT_FREE(rtitle);
1871  LEPT_FREE(gtitle);
1872  LEPT_FREE(btitle);
1873  } else {
1874  na = numaCreate(npts);
1875  for (i = 0; i < npts; i++) {
1876  ptaGetIPt(pta, i, &x, &y);
1877  if (x < 0 || x >= w)
1878  continue;
1879  if (y < 0 || y >= h)
1880  continue;
1881  pixGetPixel(pixt, x, y, &val);
1882  numaAddNumber(na, (l_float32)val);
1883  }
1884 
1885  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1886  gplotSimple1(na, outformat, buffer, title);
1887  numaDestroy(&na);
1888  }
1889  pixDestroy(&pixt);
1890  return 0;
1891 }
1892 
1893 
1907 PTA *
1909  BOX *box)
1910 {
1911 l_int32 i, j, w, h, wpl, xstart, xend, ystart, yend, bw, bh;
1912 l_uint32 *data, *line;
1913 PTA *pta;
1914 
1915  PROCNAME("ptaGetPixelsFromPix");
1916 
1917  if (!pixs || (pixGetDepth(pixs) != 1))
1918  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
1919 
1920  pixGetDimensions(pixs, &w, &h, NULL);
1921  data = pixGetData(pixs);
1922  wpl = pixGetWpl(pixs);
1923  xstart = ystart = 0;
1924  xend = w - 1;
1925  yend = h - 1;
1926  if (box) {
1927  boxGetGeometry(box, &xstart, &ystart, &bw, &bh);
1928  xend = xstart + bw - 1;
1929  yend = ystart + bh - 1;
1930  }
1931 
1932  if ((pta = ptaCreate(0)) == NULL)
1933  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
1934  for (i = ystart; i <= yend; i++) {
1935  line = data + i * wpl;
1936  for (j = xstart; j <= xend; j++) {
1937  if (GET_DATA_BIT(line, j))
1938  ptaAddPt(pta, j, i);
1939  }
1940  }
1941 
1942  return pta;
1943 }
1944 
1945 
1960 PIX *
1962  l_int32 w,
1963  l_int32 h)
1964 {
1965 l_int32 n, i, x, y;
1966 PIX *pix;
1967 
1968  PROCNAME("pixGenerateFromPta");
1969 
1970  if (!pta)
1971  return (PIX *)ERROR_PTR("pta not defined", procName, NULL);
1972 
1973  if ((pix = pixCreate(w, h, 1)) == NULL)
1974  return (PIX *)ERROR_PTR("pix not made", procName, NULL);
1975  n = ptaGetCount(pta);
1976  for (i = 0; i < n; i++) {
1977  ptaGetIPt(pta, i, &x, &y);
1978  if (x < 0 || x >= w || y < 0 || y >= h)
1979  continue;
1980  pixSetPixel(pix, x, y, 1);
1981  }
1982 
1983  return pix;
1984 }
1985 
1986 
2001 PTA *
2003  l_int32 type)
2004 {
2005 PIX *pixt;
2006 PTA *pta;
2007 
2008  PROCNAME("ptaGetBoundaryPixels");
2009 
2010  if (!pixs || (pixGetDepth(pixs) != 1))
2011  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2012  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2013  return (PTA *)ERROR_PTR("invalid type", procName, NULL);
2014 
2015  if (type == L_BOUNDARY_FG)
2016  pixt = pixMorphSequence(pixs, "e3.3", 0);
2017  else
2018  pixt = pixMorphSequence(pixs, "d3.3", 0);
2019  pixXor(pixt, pixt, pixs);
2020  pta = ptaGetPixelsFromPix(pixt, NULL);
2021 
2022  pixDestroy(&pixt);
2023  return pta;
2024 }
2025 
2026 
2050 PTAA *
2052  l_int32 type,
2053  l_int32 connectivity,
2054  BOXA **pboxa,
2055  PIXA **ppixa)
2056 {
2057 l_int32 i, n, w, h, x, y, bw, bh, left, right, top, bot;
2058 BOXA *boxa;
2059 PIX *pixt1, *pixt2;
2060 PIXA *pixa;
2061 PTA *pta1, *pta2;
2062 PTAA *ptaa;
2063 
2064  PROCNAME("ptaaGetBoundaryPixels");
2065 
2066  if (pboxa) *pboxa = NULL;
2067  if (ppixa) *ppixa = NULL;
2068  if (!pixs || (pixGetDepth(pixs) != 1))
2069  return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2070  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2071  return (PTAA *)ERROR_PTR("invalid type", procName, NULL);
2072  if (connectivity != 4 && connectivity != 8)
2073  return (PTAA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
2074 
2075  pixGetDimensions(pixs, &w, &h, NULL);
2076  boxa = pixConnComp(pixs, &pixa, connectivity);
2077  n = boxaGetCount(boxa);
2078  ptaa = ptaaCreate(0);
2079  for (i = 0; i < n; i++) {
2080  pixt1 = pixaGetPix(pixa, i, L_CLONE);
2081  boxaGetBoxGeometry(boxa, i, &x, &y, &bw, &bh);
2082  left = right = top = bot = 0;
2083  if (type == L_BOUNDARY_BG) {
2084  if (x > 0) left = 1;
2085  if (y > 0) top = 1;
2086  if (x + bw < w) right = 1;
2087  if (y + bh < h) bot = 1;
2088  pixt2 = pixAddBorderGeneral(pixt1, left, right, top, bot, 0);
2089  } else {
2090  pixt2 = pixClone(pixt1);
2091  }
2092  pta1 = ptaGetBoundaryPixels(pixt2, type);
2093  pta2 = ptaTransform(pta1, x - left, y - top, 1.0, 1.0);
2094  ptaaAddPta(ptaa, pta2, L_INSERT);
2095  ptaDestroy(&pta1);
2096  pixDestroy(&pixt1);
2097  pixDestroy(&pixt2);
2098  }
2099 
2100  if (pboxa)
2101  *pboxa = boxa;
2102  else
2103  boxaDestroy(&boxa);
2104  if (ppixa)
2105  *ppixa = pixa;
2106  else
2107  pixaDestroy(&pixa);
2108  return ptaa;
2109 }
2110 
2111 
2133 PTAA *
2135  l_int32 *pncc)
2136 {
2137 l_int32 wpl, index, i, j, w, h;
2138 l_uint32 maxval;
2139 l_uint32 *data, *line;
2140 PTA *pta;
2141 PTAA *ptaa;
2142 
2143  PROCNAME("ptaaIndexLabeledPixels");
2144 
2145  if (pncc) *pncc = 0;
2146  if (!pixs || (pixGetDepth(pixs) != 32))
2147  return (PTAA *)ERROR_PTR("pixs undef or not 32 bpp", procName, NULL);
2148 
2149  /* The number of c.c. is the maximum pixel value. Use this to
2150  * initialize ptaa with sufficient pta arrays */
2151  pixGetMaxValueInRect(pixs, NULL, &maxval, NULL, NULL);
2152  if (pncc) *pncc = maxval;
2153  pta = ptaCreate(1);
2154  ptaa = ptaaCreate(maxval + 1);
2155  ptaaInitFull(ptaa, pta);
2156  ptaDestroy(&pta);
2157 
2158  /* Sweep over %pixs, saving the pixel coordinates of each pixel
2159  * with nonzero value in the appropriate pta, indexed by that value. */
2160  pixGetDimensions(pixs, &w, &h, NULL);
2161  data = pixGetData(pixs);
2162  wpl = pixGetWpl(pixs);
2163  for (i = 0; i < h; i++) {
2164  line = data + wpl * i;
2165  for (j = 0; j < w; j++) {
2166  index = line[j];
2167  if (index > 0)
2168  ptaaAddPt(ptaa, index, j, i);
2169  }
2170  }
2171 
2172  return ptaa;
2173 }
2174 
2175 
2190 PTA *
2192  l_int32 x,
2193  l_int32 y,
2194  l_int32 conn)
2195 {
2196 l_int32 w, h;
2197 PTA *pta;
2198 
2199  PROCNAME("ptaGetNeighborPixLocs");
2200 
2201  if (!pixs)
2202  return (PTA *)ERROR_PTR("pixs not defined", procName, NULL);
2203  pixGetDimensions(pixs, &w, &h, NULL);
2204  if (x < 0 || x >= w || y < 0 || y >= h)
2205  return (PTA *)ERROR_PTR("(x,y) not in pixs", procName, NULL);
2206  if (conn != 4 && conn != 8)
2207  return (PTA *)ERROR_PTR("conn not 4 or 8", procName, NULL);
2208 
2209  pta = ptaCreate(conn);
2210  if (x > 0)
2211  ptaAddPt(pta, x - 1, y);
2212  if (x < w - 1)
2213  ptaAddPt(pta, x + 1, y);
2214  if (y > 0)
2215  ptaAddPt(pta, x, y - 1);
2216  if (y < h - 1)
2217  ptaAddPt(pta, x, y + 1);
2218  if (conn == 8) {
2219  if (x > 0) {
2220  if (y > 0)
2221  ptaAddPt(pta, x - 1, y - 1);
2222  if (y < h - 1)
2223  ptaAddPt(pta, x - 1, y + 1);
2224  }
2225  if (x < w - 1) {
2226  if (y > 0)
2227  ptaAddPt(pta, x + 1, y - 1);
2228  if (y < h - 1)
2229  ptaAddPt(pta, x + 1, y + 1);
2230  }
2231  }
2232 
2233  return pta;
2234 }
2235 
2236 
2237 /*---------------------------------------------------------------------*
2238  * Interconversion with Numa *
2239  *---------------------------------------------------------------------*/
2246 PTA *
2248 {
2249 l_int32 i, n;
2250 l_float32 startx, delx, val;
2251 PTA *pta;
2252 
2253  PROCNAME("numaConvertToPta1");
2254 
2255  if (!na)
2256  return (PTA *)ERROR_PTR("na not defined", procName, NULL);
2257 
2258  n = numaGetCount(na);
2259  pta = ptaCreate(n);
2260  numaGetParameters(na, &startx, &delx);
2261  for (i = 0; i < n; i++) {
2262  numaGetFValue(na, i, &val);
2263  ptaAddPt(pta, startx + i * delx, val);
2264  }
2265  return pta;
2266 }
2267 
2268 
2276 PTA *
2278  NUMA *nay)
2279 {
2280 l_int32 i, n, nx, ny;
2281 l_float32 valx, valy;
2282 PTA *pta;
2283 
2284  PROCNAME("numaConvertToPta2");
2285 
2286  if (!nax || !nay)
2287  return (PTA *)ERROR_PTR("nax and nay not both defined", procName, NULL);
2288 
2289  nx = numaGetCount(nax);
2290  ny = numaGetCount(nay);
2291  n = L_MIN(nx, ny);
2292  if (nx != ny)
2293  L_WARNING("nx = %d does not equal ny = %d\n", procName, nx, ny);
2294  pta = ptaCreate(n);
2295  for (i = 0; i < n; i++) {
2296  numaGetFValue(nax, i, &valx);
2297  numaGetFValue(nay, i, &valy);
2298  ptaAddPt(pta, valx, valy);
2299  }
2300  return pta;
2301 }
2302 
2303 
2312 l_ok
2314  NUMA **pnax,
2315  NUMA **pnay)
2316 {
2317 l_int32 i, n;
2318 l_float32 valx, valy;
2319 
2320  PROCNAME("ptaConvertToNuma");
2321 
2322  if (pnax) *pnax = NULL;
2323  if (pnay) *pnay = NULL;
2324  if (!pnax || !pnay)
2325  return ERROR_INT("&nax and &nay not both defined", procName, 1);
2326  if (!pta)
2327  return ERROR_INT("pta not defined", procName, 1);
2328 
2329  n = ptaGetCount(pta);
2330  *pnax = numaCreate(n);
2331  *pnay = numaCreate(n);
2332  for (i = 0; i < n; i++) {
2333  ptaGetPt(pta, i, &valx, &valy);
2334  numaAddNumber(*pnax, valx);
2335  numaAddNumber(*pnay, valy);
2336  }
2337  return 0;
2338 }
2339 
2340 
2341 /*---------------------------------------------------------------------*
2342  * Display Pta and Ptaa *
2343  *---------------------------------------------------------------------*/
2363 PIX *
2365  PIX *pixs,
2366  PTA *pta)
2367 {
2368 l_int32 i, n, w, h, x, y;
2369 l_uint32 rpixel, gpixel, bpixel;
2370 
2371  PROCNAME("pixDisplayPta");
2372 
2373  if (!pixs)
2374  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2375  if (!pta)
2376  return (PIX *)ERROR_PTR("pta not defined", procName, pixd);
2377  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2378  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2379 
2380  if (!pixd)
2381  pixd = pixConvertTo32(pixs);
2382  pixGetDimensions(pixd, &w, &h, NULL);
2383  composeRGBPixel(255, 0, 0, &rpixel); /* start point */
2384  composeRGBPixel(0, 255, 0, &gpixel);
2385  composeRGBPixel(0, 0, 255, &bpixel); /* end point */
2386 
2387  n = ptaGetCount(pta);
2388  for (i = 0; i < n; i++) {
2389  ptaGetIPt(pta, i, &x, &y);
2390  if (x < 0 || x >= w || y < 0 || y >= h)
2391  continue;
2392  if (i == 0)
2393  pixSetPixel(pixd, x, y, rpixel);
2394  else if (i < n - 1)
2395  pixSetPixel(pixd, x, y, gpixel);
2396  else
2397  pixSetPixel(pixd, x, y, bpixel);
2398  }
2399 
2400  return pixd;
2401 }
2402 
2403 
2429 PIX *
2431  PIX *pixs,
2432  PTAA *ptaa,
2433  PIX *pixp,
2434  l_int32 cx,
2435  l_int32 cy)
2436 {
2437 l_int32 i, n;
2438 l_uint32 color;
2439 PIXCMAP *cmap;
2440 PTA *pta;
2441 
2442  PROCNAME("pixDisplayPtaaPattern");
2443 
2444  if (!pixs)
2445  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2446  if (!ptaa)
2447  return (PIX *)ERROR_PTR("ptaa not defined", procName, pixd);
2448  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2449  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2450  if (!pixp)
2451  return (PIX *)ERROR_PTR("pixp not defined", procName, pixd);
2452 
2453  if (!pixd)
2454  pixd = pixConvertTo32(pixs);
2455 
2456  /* Use 256 random colors */
2457  cmap = pixcmapCreateRandom(8, 0, 0);
2458  n = ptaaGetCount(ptaa);
2459  for (i = 0; i < n; i++) {
2460  pixcmapGetColor32(cmap, i % 256, &color);
2461  pta = ptaaGetPta(ptaa, i, L_CLONE);
2462  pixDisplayPtaPattern(pixd, pixd, pta, pixp, cx, cy, color);
2463  ptaDestroy(&pta);
2464  }
2465 
2466  pixcmapDestroy(&cmap);
2467  return pixd;
2468 }
2469 
2470 
2496 PIX *
2498  PIX *pixs,
2499  PTA *pta,
2500  PIX *pixp,
2501  l_int32 cx,
2502  l_int32 cy,
2503  l_uint32 color)
2504 {
2505 l_int32 i, n, w, h, x, y;
2506 PTA *ptat;
2507 
2508  PROCNAME("pixDisplayPtaPattern");
2509 
2510  if (!pixs)
2511  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2512  if (!pta)
2513  return (PIX *)ERROR_PTR("pta not defined", procName, pixd);
2514  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2515  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2516  if (!pixp)
2517  return (PIX *)ERROR_PTR("pixp not defined", procName, pixd);
2518 
2519  if (!pixd)
2520  pixd = pixConvertTo32(pixs);
2521  pixGetDimensions(pixs, &w, &h, NULL);
2522  ptat = ptaReplicatePattern(pta, pixp, NULL, cx, cy, w, h);
2523 
2524  n = ptaGetCount(ptat);
2525  for (i = 0; i < n; i++) {
2526  ptaGetIPt(ptat, i, &x, &y);
2527  if (x < 0 || x >= w || y < 0 || y >= h)
2528  continue;
2529  pixSetPixel(pixd, x, y, color);
2530  }
2531 
2532  ptaDestroy(&ptat);
2533  return pixd;
2534 }
2535 
2536 
2556 PTA *
2558  PIX *pixp,
2559  PTA *ptap,
2560  l_int32 cx,
2561  l_int32 cy,
2562  l_int32 w,
2563  l_int32 h)
2564 {
2565 l_int32 i, j, n, np, x, y, xp, yp, xf, yf;
2566 PTA *ptat, *ptad;
2567 
2568  PROCNAME("ptaReplicatePattern");
2569 
2570  if (!ptas)
2571  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
2572  if (!pixp && !ptap)
2573  return (PTA *)ERROR_PTR("no pattern is defined", procName, NULL);
2574  if (pixp && ptap)
2575  L_WARNING("pixp and ptap defined; using ptap\n", procName);
2576 
2577  n = ptaGetCount(ptas);
2578  ptad = ptaCreate(n);
2579  if (ptap)
2580  ptat = ptaClone(ptap);
2581  else
2582  ptat = ptaGetPixelsFromPix(pixp, NULL);
2583  np = ptaGetCount(ptat);
2584  for (i = 0; i < n; i++) {
2585  ptaGetIPt(ptas, i, &x, &y);
2586  for (j = 0; j < np; j++) {
2587  ptaGetIPt(ptat, j, &xp, &yp);
2588  xf = x - cx + xp;
2589  yf = y - cy + yp;
2590  if (xf >= 0 && xf < w && yf >= 0 && yf < h)
2591  ptaAddPt(ptad, xf, yf);
2592  }
2593  }
2594 
2595  ptaDestroy(&ptat);
2596  return ptad;
2597 }
2598 
2599 
2608 PIX *
2610  PTAA *ptaa)
2611 {
2612 l_int32 i, j, w, h, npta, npt, x, y, rv, gv, bv;
2613 l_uint32 *pixela;
2614 NUMA *na1, *na2, *na3;
2615 PIX *pixd;
2616 PTA *pta;
2617 
2618  PROCNAME("pixDisplayPtaa");
2619 
2620  if (!pixs)
2621  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2622  if (!ptaa)
2623  return (PIX *)ERROR_PTR("ptaa not defined", procName, NULL);
2624  npta = ptaaGetCount(ptaa);
2625  if (npta == 0)
2626  return (PIX *)ERROR_PTR("no pta", procName, NULL);
2627 
2628  if ((pixd = pixConvertTo32(pixs)) == NULL)
2629  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2630  pixGetDimensions(pixd, &w, &h, NULL);
2631 
2632  /* Make a colormap for the paths */
2633  if ((pixela = (l_uint32 *)LEPT_CALLOC(npta, sizeof(l_uint32))) == NULL) {
2634  pixDestroy(&pixd);
2635  return (PIX *)ERROR_PTR("calloc fail for pixela", procName, NULL);
2636  }
2637  na1 = numaPseudorandomSequence(256, 14657);
2638  na2 = numaPseudorandomSequence(256, 34631);
2639  na3 = numaPseudorandomSequence(256, 54617);
2640  for (i = 0; i < npta; i++) {
2641  numaGetIValue(na1, i % 256, &rv);
2642  numaGetIValue(na2, i % 256, &gv);
2643  numaGetIValue(na3, i % 256, &bv);
2644  composeRGBPixel(rv, gv, bv, &pixela[i]);
2645  }
2646  numaDestroy(&na1);
2647  numaDestroy(&na2);
2648  numaDestroy(&na3);
2649 
2650  for (i = 0; i < npta; i++) {
2651  pta = ptaaGetPta(ptaa, i, L_CLONE);
2652  npt = ptaGetCount(pta);
2653  for (j = 0; j < npt; j++) {
2654  ptaGetIPt(pta, j, &x, &y);
2655  if (x < 0 || x >= w || y < 0 || y >= h)
2656  continue;
2657  pixSetPixel(pixd, x, y, pixela[i]);
2658  }
2659  ptaDestroy(&pta);
2660  }
2661 
2662  LEPT_FREE(pixela);
2663  return pixd;
2664 }
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:1766
l_int32 gaussjordan(l_float32 **a, l_float32 *b, l_int32 n)
gaussjordan()
Definition: affine.c:1345
l_ok ptaGetQuadraticLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, NUMA **pnafit)
ptaGetQuadraticLSF()
Definition: ptafunc1.c:1145
l_ok ptaConvertToNuma(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaConvertToNuma()
Definition: ptafunc1.c:2313
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:692
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:322
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:1944
Definition: pix.h:717
l_ok pixPlotAlongPta(PIX *pixs, PTA *pta, l_int32 outformat, const char *title)
pixPlotAlongPta()
Definition: ptafunc1.c:1807
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
PIX * pixGenerateFromPta(PTA *pta, l_int32 w, l_int32 h)
pixGenerateFromPta()
Definition: ptafunc1.c:1961
l_ok ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1235
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:342
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:473
l_ok boxContainsPt(BOX *box, l_float32 x, l_float32 y, l_int32 *pcontains)
boxContainsPt()
Definition: boxfunc1.c:1080
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:1388
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:116
l_ok numaGetMedian(NUMA *na, l_float32 *pval)
numaGetMedian()
Definition: numafunc1.c:3135
PIX * pixDisplayPtaaPattern(PIX *pixd, PIX *pixs, PTAA *ptaa, PIX *pixp, l_int32 cx, l_int32 cy)
pixDisplayPtaaPattern()
Definition: ptafunc1.c:2430
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:265
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:187
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:504
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:580
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PTA * ptaGetBoundaryPixels(PIX *pixs, l_int32 type)
ptaGetBoundaryPixels()
Definition: ptafunc1.c:2002
#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:1044
Definition: pix.h:492
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:977
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:1740
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:164
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:1524
l_ok applyQuadraticFit(l_float32 a, l_float32 b, l_float32 c, l_float32 x, l_float32 *py)
applyQuadraticFit()
Definition: ptafunc1.c:1715
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:147
PTA * ptaSubsample(PTA *ptas, l_int32 subfactor)
ptaSubsample()
Definition: ptafunc1.c:121
NUMA * numaPseudorandomSequence(l_int32 size, l_int32 seed)
numaPseudorandomSequence()
Definition: numafunc1.c:2985
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:775
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1094
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:727
PTA * numaConvertToPta1(NUMA *na)
numaConvertToPta1()
Definition: ptafunc1.c:2247
Definition: array.h:59
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1574
PIX * pixDisplayPtaa(PIX *pixs, PTAA *ptaa)
pixDisplayPtaa()
Definition: ptafunc1.c:2609
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:631
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:296
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:863
Definition: pix.h:532
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:253
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
Definition: morphseq.c:133
l_ok ptaGetCubicLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pd, NUMA **pnafit)
ptaGetCubicLSF()
Definition: ptafunc1.c:1258
PTA * ptaCyclicPerm(PTA *ptas, l_int32 xs, l_int32 ys)
ptaCyclicPerm()
Definition: ptafunc1.c:328
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:525
PTA * ptaGetNeighborPixLocs(PIX *pixs, l_int32 x, l_int32 y, l_int32 conn)
ptaGetNeighborPixLocs()
Definition: ptafunc1.c:2191
PTA * ptaSelectByValue(PTA *ptas, l_float32 xth, l_float32 yth, l_int32 type, l_int32 relation)
ptaSelectByValue()
Definition: ptafunc1.c:909
l_int32 ptaContainsPt(PTA *pta, l_int32 x, l_int32 y)
ptaContainsPt()
Definition: ptafunc1.c:665
#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:2051
PTA * ptaGetInsideBox(PTA *ptas, BOX *box)
ptaGetInsideBox()
Definition: ptafunc1.c:533
l_float32 l_angleBetweenVectors(l_float32 x1, l_float32 y1, l_float32 x2, l_float32 y2)
l_angleBetweenVectors()
Definition: ptafunc1.c:827
l_ok ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1165
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:936
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
BOX * ptaGetBoundingRegion(PTA *pta)
ptaGetBoundingRegion()
Definition: ptafunc1.c:439
l_ok ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:483
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:225
Definition: pix.h:454
l_float32 * y
Definition: pix.h:522
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:360
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:180
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
PTA * pixFindCornerPixels(PIX *pixs)
pixFindCornerPixels()
Definition: ptafunc1.c:573
l_ok applyLinearFit(l_float32 a, l_float32 b, l_float32 x, l_float32 *py)
applyLinearFit()
Definition: ptafunc1.c:1691
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1074
l_ok pixcmapGetColor32(PIXCMAP *cmap, l_int32 index, l_uint32 *pval32)
pixcmapGetColor32()
Definition: colormap.c:791
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2557
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:672
l_int32 ptaTestIntersection(PTA *pta1, PTA *pta2)
ptaTestIntersection()
Definition: ptafunc1.c:694
PTA * numaConvertToPta2(NUMA *nax, NUMA *nay)
numaConvertToPta2()
Definition: ptafunc1.c:2277
PIX * pixDisplayPta(PIX *pixd, PIX *pixs, PTA *pta)
pixDisplayPta()
Definition: ptafunc1.c:2364
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:509
Definition: pix.h:134
Definition: pix.h:719
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:192
l_ok pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2278
l_ok ptaaJoin(PTAA *ptaad, PTAA *ptaas, l_int32 istart, l_int32 iend)
ptaaJoin()
Definition: ptafunc1.c:212
PTA * ptaSelectRange(PTA *ptas, l_int32 first, l_int32 last)
ptaSelectRange()
Definition: ptafunc1.c:384
Definition: pix.h:201
PTAA * ptaaIndexLabeledPixels(PIX *pixs, l_int32 *pncc)
ptaaIndexLabeledPixels()
Definition: ptafunc1.c:2134
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:718
l_ok ptaGetMinMax(PTA *pta, l_float32 *pxmin, l_float32 *pymin, l_float32 *pxmax, l_float32 *pymax)
ptaGetMinMax()
Definition: ptafunc1.c:856
PTA * ptaTransform(PTA *ptas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
ptaTransform()
Definition: ptafunc1.c:735
PIX * pixDisplayPtaPattern(PIX *pixd, PIX *pixs, PTA *pta, PIX *pixp, l_int32 cx, l_int32 cy, l_uint32 color)
pixDisplayPtaPattern()
Definition: ptafunc1.c:2497
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:1611
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:555
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:1004
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2671
PTA * ptaReverse(PTA *ptas, l_int32 type)
ptaReverse()
Definition: ptafunc1.c:252
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1908
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:310
Definition: pix.h:480
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:408
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:165
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:939
l_ok gplotSimple1(NUMA *na, l_int32 outformat, const char *outroot, const char *title)
gplotSimple1()
Definition: gplot.c:575
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1842
PTA * ptaTranspose(PTA *ptas)
ptaTranspose()
Definition: ptafunc1.c:288
Definition: pix.h:517
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:158