Leptonica  1.73
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 
92 #include <math.h>
93 #include "allheaders.h"
94 
95 #ifndef M_PI
96 #define M_PI 3.14159265358979323846
97 #endif /* M_PI */
98 
99 
100 /*---------------------------------------------------------------------*
101  * Simple rearrangements *
102  *---------------------------------------------------------------------*/
110 PTA *
112  l_int32 subfactor)
113 {
114 l_int32 n, i;
115 l_float32 x, y;
116 PTA *ptad;
117 
118  PROCNAME("pixSubsample");
119 
120  if (!ptas)
121  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
122  if (subfactor < 1)
123  return (PTA *)ERROR_PTR("subfactor < 1", procName, NULL);
124 
125  ptad = ptaCreate(0);
126  n = ptaGetCount(ptas);
127  for (i = 0; i < n; i++) {
128  if (i % subfactor != 0) continue;
129  ptaGetPt(ptas, i, &x, &y);
130  ptaAddPt(ptad, x, y);
131  }
132 
133  return ptad;
134 }
135 
136 
153 l_int32
154 ptaJoin(PTA *ptad,
155  PTA *ptas,
156  l_int32 istart,
157  l_int32 iend)
158 {
159 l_int32 n, i, x, y;
160 
161  PROCNAME("ptaJoin");
162 
163  if (!ptad)
164  return ERROR_INT("ptad not defined", procName, 1);
165  if (!ptas)
166  return 0;
167 
168  if (istart < 0)
169  istart = 0;
170  n = ptaGetCount(ptas);
171  if (iend < 0 || iend >= n)
172  iend = n - 1;
173  if (istart > iend)
174  return ERROR_INT("istart > iend; no pts", procName, 1);
175 
176  for (i = istart; i <= iend; i++) {
177  ptaGetIPt(ptas, i, &x, &y);
178  ptaAddPt(ptad, x, y);
179  }
180 
181  return 0;
182 }
183 
184 
201 l_int32
202 ptaaJoin(PTAA *ptaad,
203  PTAA *ptaas,
204  l_int32 istart,
205  l_int32 iend)
206 {
207 l_int32 n, i;
208 PTA *pta;
209 
210  PROCNAME("ptaaJoin");
211 
212  if (!ptaad)
213  return ERROR_INT("ptaad not defined", procName, 1);
214  if (!ptaas)
215  return 0;
216 
217  if (istart < 0)
218  istart = 0;
219  n = ptaaGetCount(ptaas);
220  if (iend < 0 || iend >= n)
221  iend = n - 1;
222  if (istart > iend)
223  return ERROR_INT("istart > iend; no pts", procName, 1);
224 
225  for (i = istart; i <= iend; i++) {
226  pta = ptaaGetPta(ptaas, i, L_CLONE);
227  ptaaAddPta(ptaad, pta, L_INSERT);
228  }
229 
230  return 0;
231 }
232 
233 
241 PTA *
243  l_int32 type)
244 {
245 l_int32 n, i, ix, iy;
246 l_float32 x, y;
247 PTA *ptad;
248 
249  PROCNAME("ptaReverse");
250 
251  if (!ptas)
252  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
253 
254  n = ptaGetCount(ptas);
255  if ((ptad = ptaCreate(n)) == NULL)
256  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
257  for (i = n - 1; i >= 0; i--) {
258  if (type == 0) {
259  ptaGetPt(ptas, i, &x, &y);
260  ptaAddPt(ptad, x, y);
261  } else { /* type == 1 */
262  ptaGetIPt(ptas, i, &ix, &iy);
263  ptaAddPt(ptad, ix, iy);
264  }
265  }
266 
267  return ptad;
268 }
269 
270 
277 PTA *
279 {
280 l_int32 n, i;
281 l_float32 x, y;
282 PTA *ptad;
283 
284  PROCNAME("ptaTranspose");
285 
286  if (!ptas)
287  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
288 
289  n = ptaGetCount(ptas);
290  if ((ptad = ptaCreate(n)) == NULL)
291  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
292  for (i = 0; i < n; i++) {
293  ptaGetPt(ptas, i, &x, &y);
294  ptaAddPt(ptad, y, x);
295  }
296 
297  return ptad;
298 }
299 
300 
317 PTA *
319  l_int32 xs,
320  l_int32 ys)
321 {
322 l_int32 n, i, x, y, j, index, state;
323 l_int32 x1, y1, x2, y2;
324 PTA *ptad;
325 
326  PROCNAME("ptaCyclicPerm");
327 
328  if (!ptas)
329  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
330 
331  n = ptaGetCount(ptas);
332 
333  /* Verify input data */
334  ptaGetIPt(ptas, 0, &x1, &y1);
335  ptaGetIPt(ptas, n - 1, &x2, &y2);
336  if (x1 != x2 || y1 != y2)
337  return (PTA *)ERROR_PTR("start and end pts not same", procName, NULL);
338  state = L_NOT_FOUND;
339  for (i = 0; i < n; i++) {
340  ptaGetIPt(ptas, i, &x, &y);
341  if (x == xs && y == ys) {
342  state = L_FOUND;
343  break;
344  }
345  }
346  if (state == L_NOT_FOUND)
347  return (PTA *)ERROR_PTR("start pt not in ptas", procName, NULL);
348 
349  if ((ptad = ptaCreate(n)) == NULL)
350  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
351  for (j = 0; j < n - 1; j++) {
352  if (i + j < n - 1)
353  index = i + j;
354  else
355  index = (i + j + 1) % n;
356  ptaGetIPt(ptas, index, &x, &y);
357  ptaAddPt(ptad, x, y);
358  }
359  ptaAddPt(ptad, xs, ys);
360 
361  return ptad;
362 }
363 
364 
373 PTA *
375  l_int32 first,
376  l_int32 last)
377 {
378 l_int32 n, npt, i;
379 l_float32 x, y;
380 PTA *ptad;
381 
382  PROCNAME("ptaSelectRange");
383 
384  if (!ptas)
385  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
386  if ((n = ptaGetCount(ptas)) == 0) {
387  L_WARNING("ptas is empty\n", procName);
388  return ptaCopy(ptas);
389  }
390  first = L_MAX(0, first);
391  if (last <= 0) last = n - 1;
392  if (first >= n)
393  return (PTA *)ERROR_PTR("invalid first", procName, NULL);
394  if (first > last)
395  return (PTA *)ERROR_PTR("first > last", procName, NULL);
396 
397  npt = last - first + 1;
398  ptad = ptaCreate(npt);
399  for (i = first; i <= last; i++) {
400  ptaGetPt(ptas, i, &x, &y);
401  ptaAddPt(ptad, x, y);
402  }
403  return ptad;
404 }
405 
406 
407 /*---------------------------------------------------------------------*
408  * Geometric *
409  *---------------------------------------------------------------------*/
423 BOX *
425 {
426 l_int32 n, i, x, y, minx, maxx, miny, maxy;
427 
428  PROCNAME("ptaGetBoundingRegion");
429 
430  if (!pta)
431  return (BOX *)ERROR_PTR("pta not defined", procName, NULL);
432 
433  minx = 10000000;
434  miny = 10000000;
435  maxx = -10000000;
436  maxy = -10000000;
437  n = ptaGetCount(pta);
438  for (i = 0; i < n; i++) {
439  ptaGetIPt(pta, i, &x, &y);
440  if (x < minx) minx = x;
441  if (x > maxx) maxx = x;
442  if (y < miny) miny = y;
443  if (y > maxy) maxy = y;
444  }
445 
446  return boxCreate(minx, miny, maxx - minx + 1, maxy - miny + 1);
447 }
448 
449 
467 l_int32
469  l_float32 *pminx,
470  l_float32 *pmaxx,
471  l_float32 *pminy,
472  l_float32 *pmaxy)
473 {
474 l_int32 n, i;
475 l_float32 x, y, minx, maxx, miny, maxy;
476 
477  PROCNAME("ptaGetRange");
478 
479  if (!pminx && !pmaxx && !pminy && !pmaxy)
480  return ERROR_INT("no output requested", procName, 1);
481  if (pminx) *pminx = 0;
482  if (pmaxx) *pmaxx = 0;
483  if (pminy) *pminy = 0;
484  if (pmaxy) *pmaxy = 0;
485  if (!pta)
486  return ERROR_INT("pta not defined", procName, 1);
487  if ((n = ptaGetCount(pta)) == 0)
488  return ERROR_INT("no points in pta", procName, 1);
489 
490  ptaGetPt(pta, 0, &x, &y);
491  minx = x;
492  maxx = x;
493  miny = y;
494  maxy = y;
495  for (i = 1; i < n; i++) {
496  ptaGetPt(pta, i, &x, &y);
497  if (x < minx) minx = x;
498  if (x > maxx) maxx = x;
499  if (y < miny) miny = y;
500  if (y > maxy) maxy = y;
501  }
502  if (pminx) *pminx = minx;
503  if (pmaxx) *pmaxx = maxx;
504  if (pminy) *pminy = miny;
505  if (pmaxy) *pmaxy = maxy;
506  return 0;
507 }
508 
509 
517 PTA *
519  BOX *box)
520 {
521 PTA *ptad;
522 l_int32 n, i, contains;
523 l_float32 x, y;
524 
525  PROCNAME("ptaGetInsideBox");
526 
527  if (!ptas)
528  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
529  if (!box)
530  return (PTA *)ERROR_PTR("box not defined", procName, NULL);
531 
532  n = ptaGetCount(ptas);
533  ptad = ptaCreate(0);
534  for (i = 0; i < n; i++) {
535  ptaGetPt(ptas, i, &x, &y);
536  boxContainsPt(box, x, y, &contains);
537  if (contains)
538  ptaAddPt(ptad, x, y);
539  }
540 
541  return ptad;
542 }
543 
544 
557 PTA *
559 {
560 l_int32 i, j, x, y, w, h, wpl, mindim, found;
561 l_uint32 *data, *line;
562 PTA *pta;
563 
564  PROCNAME("pixFindCornerPixels");
565 
566  if (!pixs)
567  return (PTA *)ERROR_PTR("pixs not defined", procName, NULL);
568  if (pixGetDepth(pixs) != 1)
569  return (PTA *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
570 
571  w = pixGetWidth(pixs);
572  h = pixGetHeight(pixs);
573  mindim = L_MIN(w, h);
574  data = pixGetData(pixs);
575  wpl = pixGetWpl(pixs);
576 
577  if ((pta = ptaCreate(4)) == NULL)
578  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
579 
580  for (found = FALSE, i = 0; i < mindim; i++) {
581  for (j = 0; j <= i; j++) {
582  y = i - j;
583  line = data + y * wpl;
584  if (GET_DATA_BIT(line, j)) {
585  ptaAddPt(pta, j, y);
586  found = TRUE;
587  break;
588  }
589  }
590  if (found == TRUE)
591  break;
592  }
593 
594  for (found = FALSE, i = 0; i < mindim; i++) {
595  for (j = 0; j <= i; j++) {
596  y = i - j;
597  line = data + y * wpl;
598  x = w - 1 - j;
599  if (GET_DATA_BIT(line, x)) {
600  ptaAddPt(pta, x, 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 = h - 1 - i + j;
612  line = data + y * wpl;
613  if (GET_DATA_BIT(line, j)) {
614  ptaAddPt(pta, j, y);
615  found = TRUE;
616  break;
617  }
618  }
619  if (found == TRUE)
620  break;
621  }
622 
623  for (found = FALSE, i = 0; i < mindim; i++) {
624  for (j = 0; j <= i; j++) {
625  y = h - 1 - i + j;
626  line = data + y * wpl;
627  x = w - 1 - j;
628  if (GET_DATA_BIT(line, x)) {
629  ptaAddPt(pta, x, y);
630  found = TRUE;
631  break;
632  }
633  }
634  if (found == TRUE)
635  break;
636  }
637 
638  return pta;
639 }
640 
641 
649 l_int32
651  l_int32 x,
652  l_int32 y)
653 {
654 l_int32 i, n, ix, iy;
655 
656  PROCNAME("ptaContainsPt");
657 
658  if (!pta)
659  return ERROR_INT("pta not defined", procName, 0);
660 
661  n = ptaGetCount(pta);
662  for (i = 0; i < n; i++) {
663  ptaGetIPt(pta, i, &ix, &iy);
664  if (x == ix && y == iy)
665  return 1;
666  }
667  return 0;
668 }
669 
670 
678 l_int32
680  PTA *pta2)
681 {
682 l_int32 i, j, n1, n2, x1, y1, x2, y2;
683 
684  PROCNAME("ptaTestIntersection");
685 
686  if (!pta1)
687  return ERROR_INT("pta1 not defined", procName, 0);
688  if (!pta2)
689  return ERROR_INT("pta2 not defined", procName, 0);
690 
691  n1 = ptaGetCount(pta1);
692  n2 = ptaGetCount(pta2);
693  for (i = 0; i < n1; i++) {
694  ptaGetIPt(pta1, i, &x1, &y1);
695  for (j = 0; j < n2; j++) {
696  ptaGetIPt(pta2, i, &x2, &y2);
697  if (x1 == x2 && y1 == y2)
698  return 1;
699  }
700  }
701 
702  return 0;
703 }
704 
705 
719 PTA *
721  l_int32 shiftx,
722  l_int32 shifty,
723  l_float32 scalex,
724  l_float32 scaley)
725 {
726 l_int32 n, i, x, y;
727 PTA *ptad;
728 
729  PROCNAME("ptaTransform");
730 
731  if (!ptas)
732  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
733  n = ptaGetCount(ptas);
734  ptad = ptaCreate(n);
735  for (i = 0; i < n; i++) {
736  ptaGetIPt(ptas, i, &x, &y);
737  x = (l_int32)(scalex * (x + shiftx) + 0.5);
738  y = (l_int32)(scaley * (y + shifty) + 0.5);
739  ptaAddPt(ptad, x, y);
740  }
741 
742  return ptad;
743 }
744 
745 
759 l_int32
761  l_float32 x,
762  l_float32 y,
763  l_int32 *pinside)
764 {
765 l_int32 i, n;
766 l_float32 sum, x1, y1, x2, y2, xp1, yp1, xp2, yp2;
767 
768  PROCNAME("ptaPtInsidePolygon");
769 
770  if (!pinside)
771  return ERROR_INT("&inside not defined", procName, 1);
772  *pinside = 0;
773  if (!pta)
774  return ERROR_INT("pta not defined", procName, 1);
775 
776  /* Think of (x1,y1) as the end point of a vector that starts
777  * from the origin (0,0), and ditto for (x2,y2). */
778  n = ptaGetCount(pta);
779  sum = 0.0;
780  for (i = 0; i < n; i++) {
781  ptaGetPt(pta, i, &xp1, &yp1);
782  ptaGetPt(pta, (i + 1) % n, &xp2, &yp2);
783  x1 = xp1 - x;
784  y1 = yp1 - y;
785  x2 = xp2 - x;
786  y2 = yp2 - y;
787  sum += l_angleBetweenVectors(x1, y1, x2, y2);
788  }
789 
790  if (L_ABS(sum) > M_PI)
791  *pinside = 1;
792  return 0;
793 }
794 
795 
811 l_float32
813  l_float32 y1,
814  l_float32 x2,
815  l_float32 y2)
816 {
817 l_float64 ang;
818 
819  ang = atan2(y2, x2) - atan2(y1, x1);
820  if (ang > M_PI) ang -= 2.0 * M_PI;
821  if (ang < -M_PI) ang += 2.0 * M_PI;
822  return ang;
823 }
824 
825 
826 /*---------------------------------------------------------------------*
827  * Min/max and filtering *
828  *---------------------------------------------------------------------*/
840 l_int32
842  l_float32 *pxmin,
843  l_float32 *pymin,
844  l_float32 *pxmax,
845  l_float32 *pymax)
846 {
847 l_int32 i, n;
848 l_float32 x, y, xmin, ymin, xmax, ymax;
849 
850  PROCNAME("ptaGetMinMax");
851 
852  if (pxmin) *pxmin = -1.0;
853  if (pymin) *pymin = -1.0;
854  if (pxmax) *pxmax = -1.0;
855  if (pymax) *pymax = -1.0;
856  if (!pta)
857  return ERROR_INT("pta not defined", procName, 1);
858  if (!pxmin && !pxmax && !pymin && !pymax)
859  return ERROR_INT("no output requested", procName, 1);
860  if ((n = ptaGetCount(pta)) == 0) {
861  L_WARNING("pta is empty\n", procName);
862  return 0;
863  }
864 
865  xmin = ymin = 1.0e20;
866  xmax = ymax = -1.0e20;
867  for (i = 0; i < n; i++) {
868  ptaGetPt(pta, i, &x, &y);
869  if (x < xmin) xmin = x;
870  if (y < ymin) ymin = y;
871  if (x > xmax) xmax = x;
872  if (y > ymax) ymax = y;
873  }
874  if (pxmin) *pxmin = xmin;
875  if (pymin) *pymin = ymin;
876  if (pxmax) *pxmax = xmax;
877  if (pymax) *pymax = ymax;
878  return 0;
879 }
880 
881 
893 PTA *
895  l_float32 xth,
896  l_float32 yth,
897  l_int32 type,
898  l_int32 relation)
899 {
900 l_int32 i, n;
901 l_float32 x, y;
902 PTA *ptad;
903 
904  PROCNAME("ptaSelectByValue");
905 
906  if (!ptas)
907  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
908  if (ptaGetCount(ptas) == 0) {
909  L_WARNING("ptas is empty\n", procName);
910  return ptaCopy(ptas);
911  }
912  if (type != L_SELECT_XVAL && type != L_SELECT_YVAL &&
913  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
914  return (PTA *)ERROR_PTR("invalid type", procName, NULL);
915  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
916  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
917  return (PTA *)ERROR_PTR("invalid relation", procName, NULL);
918 
919  n = ptaGetCount(ptas);
920  ptad = ptaCreate(n);
921  for (i = 0; i < n; i++) {
922  ptaGetPt(ptas, i, &x, &y);
923  if (type == L_SELECT_XVAL) {
924  if ((relation == L_SELECT_IF_LT && x < xth) ||
925  (relation == L_SELECT_IF_GT && x > xth) ||
926  (relation == L_SELECT_IF_LTE && x <= xth) ||
927  (relation == L_SELECT_IF_GTE && x >= xth))
928  ptaAddPt(ptad, x, y);
929  } else if (type == L_SELECT_YVAL) {
930  if ((relation == L_SELECT_IF_LT && y < yth) ||
931  (relation == L_SELECT_IF_GT && y > yth) ||
932  (relation == L_SELECT_IF_LTE && y <= yth) ||
933  (relation == L_SELECT_IF_GTE && y >= yth))
934  ptaAddPt(ptad, x, y);
935  } else if (type == L_SELECT_IF_EITHER) {
936  if (((relation == L_SELECT_IF_LT) && (x < xth || y < yth)) ||
937  ((relation == L_SELECT_IF_GT) && (x > xth || y > yth)) ||
938  ((relation == L_SELECT_IF_LTE) && (x <= xth || y <= yth)) ||
939  ((relation == L_SELECT_IF_GTE) && (x >= xth || y >= yth)))
940  ptaAddPt(ptad, x, y);
941  } else { /* L_SELECT_IF_BOTH */
942  if (((relation == L_SELECT_IF_LT) && (x < xth && y < yth)) ||
943  ((relation == L_SELECT_IF_GT) && (x > xth && y > yth)) ||
944  ((relation == L_SELECT_IF_LTE) && (x <= xth && y <= yth)) ||
945  ((relation == L_SELECT_IF_GTE) && (x >= xth && y >= yth)))
946  ptaAddPt(ptad, x, y);
947  }
948  }
949 
950  return ptad;
951 }
952 
953 
961 PTA *
963  PIX *pixm)
964 {
965 l_int32 i, n, x, y;
966 l_uint32 val;
967 PTA *ptad;
968 
969  PROCNAME("ptaCropToMask");
970 
971  if (!ptas)
972  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
973  if (!pixm || pixGetDepth(pixm) != 1)
974  return (PTA *)ERROR_PTR("pixm undefined or not 1 bpp", procName, NULL);
975  if (ptaGetCount(ptas) == 0) {
976  L_INFO("ptas is empty\n", procName);
977  return ptaCopy(ptas);
978  }
979 
980  n = ptaGetCount(ptas);
981  ptad = ptaCreate(n);
982  for (i = 0; i < n; i++) {
983  ptaGetIPt(ptas, i, &x, &y);
984  pixGetPixel(pixm, x, y, &val);
985  if (val == 1)
986  ptaAddPt(ptad, x, y);
987  }
988  return ptad;
989 }
990 
991 
992 /*---------------------------------------------------------------------*
993  * Least Squares Fit *
994  *---------------------------------------------------------------------*/
1028 l_int32
1030  l_float32 *pa,
1031  l_float32 *pb,
1032  NUMA **pnafit)
1033 {
1034 l_int32 n, i;
1035 l_float32 a, b, factor, sx, sy, sxx, sxy, val;
1036 l_float32 *xa, *ya;
1037 
1038  PROCNAME("ptaGetLinearLSF");
1039 
1040  if (pa) *pa = 0.0;
1041  if (pb) *pb = 0.0;
1042  if (pnafit) *pnafit = NULL;
1043  if (!pa && !pb && !pnafit)
1044  return ERROR_INT("no output requested", procName, 1);
1045  if (!pta)
1046  return ERROR_INT("pta not defined", procName, 1);
1047  if ((n = ptaGetCount(pta)) < 2)
1048  return ERROR_INT("less than 2 pts found", procName, 1);
1049 
1050  xa = pta->x; /* not a copy */
1051  ya = pta->y; /* not a copy */
1052  sx = sy = sxx = sxy = 0.;
1053  if (pa && pb) { /* general line */
1054  for (i = 0; i < n; i++) {
1055  sx += xa[i];
1056  sy += ya[i];
1057  sxx += xa[i] * xa[i];
1058  sxy += xa[i] * ya[i];
1059  }
1060  factor = n * sxx - sx * sx;
1061  if (factor == 0.0)
1062  return ERROR_INT("no solution found", procName, 1);
1063  factor = 1. / factor;
1064 
1065  a = factor * ((l_float32)n * sxy - sx * sy);
1066  b = factor * (sxx * sy - sx * sxy);
1067  } else if (pa) { /* b = 0; line through origin */
1068  for (i = 0; i < n; i++) {
1069  sxx += xa[i] * xa[i];
1070  sxy += xa[i] * ya[i];
1071  }
1072  if (sxx == 0.0)
1073  return ERROR_INT("no solution found", procName, 1);
1074  a = sxy / sxx;
1075  b = 0.0;
1076  } else { /* a = 0; horizontal line */
1077  for (i = 0; i < n; i++)
1078  sy += ya[i];
1079  a = 0.0;
1080  b = sy / (l_float32)n;
1081  }
1082 
1083  if (pnafit) {
1084  *pnafit = numaCreate(n);
1085  for (i = 0; i < n; i++) {
1086  val = a * xa[i] + b;
1087  numaAddNumber(*pnafit, val);
1088  }
1089  }
1090 
1091  if (pa) *pa = a;
1092  if (pb) *pb = b;
1093  return 0;
1094 }
1095 
1096 
1129 l_int32
1131  l_float32 *pa,
1132  l_float32 *pb,
1133  l_float32 *pc,
1134  NUMA **pnafit)
1135 {
1136 l_int32 n, i, ret;
1137 l_float32 x, y, sx, sy, sx2, sx3, sx4, sxy, sx2y;
1138 l_float32 *xa, *ya;
1139 l_float32 *f[3];
1140 l_float32 g[3];
1141 
1142  PROCNAME("ptaGetQuadraticLSF");
1143 
1144  if (pa) *pa = 0.0;
1145  if (pb) *pb = 0.0;
1146  if (pc) *pc = 0.0;
1147  if (pnafit) *pnafit = NULL;
1148  if (!pa && !pb && !pc && !pnafit)
1149  return ERROR_INT("no output requested", procName, 1);
1150  if (!pta)
1151  return ERROR_INT("pta not defined", procName, 1);
1152  if ((n = ptaGetCount(pta)) < 3)
1153  return ERROR_INT("less than 3 pts found", procName, 1);
1154 
1155  xa = pta->x; /* not a copy */
1156  ya = pta->y; /* not a copy */
1157  sx = sy = sx2 = sx3 = sx4 = sxy = sx2y = 0.;
1158  for (i = 0; i < n; i++) {
1159  x = xa[i];
1160  y = ya[i];
1161  sx += x;
1162  sy += y;
1163  sx2 += x * x;
1164  sx3 += x * x * x;
1165  sx4 += x * x * x * x;
1166  sxy += x * y;
1167  sx2y += x * x * y;
1168  }
1169 
1170  for (i = 0; i < 3; i++)
1171  f[i] = (l_float32 *)LEPT_CALLOC(3, sizeof(l_float32));
1172  f[0][0] = sx4;
1173  f[0][1] = sx3;
1174  f[0][2] = sx2;
1175  f[1][0] = sx3;
1176  f[1][1] = sx2;
1177  f[1][2] = sx;
1178  f[2][0] = sx2;
1179  f[2][1] = sx;
1180  f[2][2] = n;
1181  g[0] = sx2y;
1182  g[1] = sxy;
1183  g[2] = sy;
1184 
1185  /* Solve for the unknowns, also putting f-inverse into f */
1186  ret = gaussjordan(f, g, 3);
1187  for (i = 0; i < 3; i++)
1188  LEPT_FREE(f[i]);
1189  if (ret)
1190  return ERROR_INT("quadratic solution failed", procName, 1);
1191 
1192  if (pa) *pa = g[0];
1193  if (pb) *pb = g[1];
1194  if (pc) *pc = g[2];
1195  if (pnafit) {
1196  *pnafit = numaCreate(n);
1197  for (i = 0; i < n; i++) {
1198  x = xa[i];
1199  y = g[0] * x * x + g[1] * x + g[2];
1200  numaAddNumber(*pnafit, y);
1201  }
1202  }
1203  return 0;
1204 }
1205 
1206 
1242 l_int32
1244  l_float32 *pa,
1245  l_float32 *pb,
1246  l_float32 *pc,
1247  l_float32 *pd,
1248  NUMA **pnafit)
1249 {
1250 l_int32 n, i, ret;
1251 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sxy, sx2y, sx3y;
1252 l_float32 *xa, *ya;
1253 l_float32 *f[4];
1254 l_float32 g[4];
1255 
1256  PROCNAME("ptaGetCubicLSF");
1257 
1258  if (pa) *pa = 0.0;
1259  if (pb) *pb = 0.0;
1260  if (pc) *pc = 0.0;
1261  if (pd) *pd = 0.0;
1262  if (pnafit) *pnafit = NULL;
1263  if (!pa && !pb && !pc && !pd && !pnafit)
1264  return ERROR_INT("no output requested", procName, 1);
1265  if (!pta)
1266  return ERROR_INT("pta not defined", procName, 1);
1267  if ((n = ptaGetCount(pta)) < 4)
1268  return ERROR_INT("less than 4 pts found", procName, 1);
1269 
1270  xa = pta->x; /* not a copy */
1271  ya = pta->y; /* not a copy */
1272  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sxy = sx2y = sx3y = 0.;
1273  for (i = 0; i < n; i++) {
1274  x = xa[i];
1275  y = ya[i];
1276  sx += x;
1277  sy += y;
1278  sx2 += x * x;
1279  sx3 += x * x * x;
1280  sx4 += x * x * x * x;
1281  sx5 += x * x * x * x * x;
1282  sx6 += x * x * x * x * x * x;
1283  sxy += x * y;
1284  sx2y += x * x * y;
1285  sx3y += x * x * x * y;
1286  }
1287 
1288  for (i = 0; i < 4; i++)
1289  f[i] = (l_float32 *)LEPT_CALLOC(4, sizeof(l_float32));
1290  f[0][0] = sx6;
1291  f[0][1] = sx5;
1292  f[0][2] = sx4;
1293  f[0][3] = sx3;
1294  f[1][0] = sx5;
1295  f[1][1] = sx4;
1296  f[1][2] = sx3;
1297  f[1][3] = sx2;
1298  f[2][0] = sx4;
1299  f[2][1] = sx3;
1300  f[2][2] = sx2;
1301  f[2][3] = sx;
1302  f[3][0] = sx3;
1303  f[3][1] = sx2;
1304  f[3][2] = sx;
1305  f[3][3] = n;
1306  g[0] = sx3y;
1307  g[1] = sx2y;
1308  g[2] = sxy;
1309  g[3] = sy;
1310 
1311  /* Solve for the unknowns, also putting f-inverse into f */
1312  ret = gaussjordan(f, g, 4);
1313  for (i = 0; i < 4; i++)
1314  LEPT_FREE(f[i]);
1315  if (ret)
1316  return ERROR_INT("cubic solution failed", procName, 1);
1317 
1318  if (pa) *pa = g[0];
1319  if (pb) *pb = g[1];
1320  if (pc) *pc = g[2];
1321  if (pd) *pd = g[3];
1322  if (pnafit) {
1323  *pnafit = numaCreate(n);
1324  for (i = 0; i < n; i++) {
1325  x = xa[i];
1326  y = g[0] * x * x * x + g[1] * x * x + g[2] * x + g[3];
1327  numaAddNumber(*pnafit, y);
1328  }
1329  }
1330  return 0;
1331 }
1332 
1333 
1372 l_int32
1374  l_float32 *pa,
1375  l_float32 *pb,
1376  l_float32 *pc,
1377  l_float32 *pd,
1378  l_float32 *pe,
1379  NUMA **pnafit)
1380 {
1381 l_int32 n, i, ret;
1382 l_float32 x, y, sx, sy, sx2, sx3, sx4, sx5, sx6, sx7, sx8;
1383 l_float32 sxy, sx2y, sx3y, sx4y;
1384 l_float32 *xa, *ya;
1385 l_float32 *f[5];
1386 l_float32 g[5];
1387 
1388  PROCNAME("ptaGetQuarticLSF");
1389 
1390  if (pa) *pa = 0.0;
1391  if (pb) *pb = 0.0;
1392  if (pc) *pc = 0.0;
1393  if (pd) *pd = 0.0;
1394  if (pe) *pe = 0.0;
1395  if (pnafit) *pnafit = NULL;
1396  if (!pa && !pb && !pc && !pd && !pe && !pnafit)
1397  return ERROR_INT("no output requested", procName, 1);
1398  if (!pta)
1399  return ERROR_INT("pta not defined", procName, 1);
1400  if ((n = ptaGetCount(pta)) < 5)
1401  return ERROR_INT("less than 5 pts found", procName, 1);
1402 
1403  xa = pta->x; /* not a copy */
1404  ya = pta->y; /* not a copy */
1405  sx = sy = sx2 = sx3 = sx4 = sx5 = sx6 = sx7 = sx8 = 0;
1406  sxy = sx2y = sx3y = sx4y = 0.;
1407  for (i = 0; i < n; i++) {
1408  x = xa[i];
1409  y = ya[i];
1410  sx += x;
1411  sy += y;
1412  sx2 += x * x;
1413  sx3 += x * x * x;
1414  sx4 += x * x * x * x;
1415  sx5 += x * x * x * x * x;
1416  sx6 += x * x * x * x * x * x;
1417  sx7 += x * x * x * x * x * x * x;
1418  sx8 += x * x * x * x * x * x * x * x;
1419  sxy += x * y;
1420  sx2y += x * x * y;
1421  sx3y += x * x * x * y;
1422  sx4y += x * x * x * x * y;
1423  }
1424 
1425  for (i = 0; i < 5; i++)
1426  f[i] = (l_float32 *)LEPT_CALLOC(5, sizeof(l_float32));
1427  f[0][0] = sx8;
1428  f[0][1] = sx7;
1429  f[0][2] = sx6;
1430  f[0][3] = sx5;
1431  f[0][4] = sx4;
1432  f[1][0] = sx7;
1433  f[1][1] = sx6;
1434  f[1][2] = sx5;
1435  f[1][3] = sx4;
1436  f[1][4] = sx3;
1437  f[2][0] = sx6;
1438  f[2][1] = sx5;
1439  f[2][2] = sx4;
1440  f[2][3] = sx3;
1441  f[2][4] = sx2;
1442  f[3][0] = sx5;
1443  f[3][1] = sx4;
1444  f[3][2] = sx3;
1445  f[3][3] = sx2;
1446  f[3][4] = sx;
1447  f[4][0] = sx4;
1448  f[4][1] = sx3;
1449  f[4][2] = sx2;
1450  f[4][3] = sx;
1451  f[4][4] = n;
1452  g[0] = sx4y;
1453  g[1] = sx3y;
1454  g[2] = sx2y;
1455  g[3] = sxy;
1456  g[4] = sy;
1457 
1458  /* Solve for the unknowns, also putting f-inverse into f */
1459  ret = gaussjordan(f, g, 5);
1460  for (i = 0; i < 5; i++)
1461  LEPT_FREE(f[i]);
1462  if (ret)
1463  return ERROR_INT("quartic solution failed", procName, 1);
1464 
1465  if (pa) *pa = g[0];
1466  if (pb) *pb = g[1];
1467  if (pc) *pc = g[2];
1468  if (pd) *pd = g[3];
1469  if (pe) *pe = g[4];
1470  if (pnafit) {
1471  *pnafit = numaCreate(n);
1472  for (i = 0; i < n; i++) {
1473  x = xa[i];
1474  y = g[0] * x * x * x * x + g[1] * x * x * x + g[2] * x * x
1475  + g[3] * x + g[4];
1476  numaAddNumber(*pnafit, y);
1477  }
1478  }
1479  return 0;
1480 }
1481 
1482 
1508 l_int32
1510  l_float32 factor,
1511  PTA **pptad,
1512  l_float32 *pa,
1513  l_float32 *pb,
1514  l_float32 *pmederr,
1515  NUMA **pnafit)
1516 {
1517 l_int32 n, i, ret;
1518 l_float32 x, y, yf, val, mederr;
1519 NUMA *nafit, *naerror;
1520 PTA *ptad;
1521 
1522  PROCNAME("ptaNoisyLinearLSF");
1523 
1524  if (pptad) *pptad = NULL;
1525  if (pa) *pa = 0.0;
1526  if (pb) *pb = 0.0;
1527  if (pmederr) *pmederr = 0.0;
1528  if (pnafit) *pnafit = NULL;
1529  if (!pptad && !pa && !pb && !pnafit)
1530  return ERROR_INT("no output requested", procName, 1);
1531  if (!pta)
1532  return ERROR_INT("pta not defined", procName, 1);
1533  if (factor <= 0.0)
1534  return ERROR_INT("factor must be > 0.0", procName, 1);
1535  if ((n = ptaGetCount(pta)) < 3)
1536  return ERROR_INT("less than 2 pts found", procName, 1);
1537 
1538  if (ptaGetLinearLSF(pta, pa, pb, &nafit) != 0)
1539  return ERROR_INT("error in linear LSF", procName, 1);
1540 
1541  /* Get the median error */
1542  naerror = numaCreate(n);
1543  for (i = 0; i < n; i++) {
1544  ptaGetPt(pta, i, &x, &y);
1545  numaGetFValue(nafit, i, &yf);
1546  numaAddNumber(naerror, L_ABS(y - yf));
1547  }
1548  numaGetMedian(naerror, &mederr);
1549  if (pmederr) *pmederr = mederr;
1550  numaDestroy(&nafit);
1551 
1552  /* Remove outliers */
1553  ptad = ptaCreate(n);
1554  for (i = 0; i < n; i++) {
1555  ptaGetPt(pta, i, &x, &y);
1556  numaGetFValue(naerror, i, &val);
1557  if (val <= factor * mederr) /* <= in case mederr = 0 */
1558  ptaAddPt(ptad, x, y);
1559  }
1560  numaDestroy(&naerror);
1561 
1562  /* Do LSF again */
1563  ret = ptaGetLinearLSF(ptad, pa, pb, pnafit);
1564  if (pptad)
1565  *pptad = ptad;
1566  else
1567  ptaDestroy(&ptad);
1568 
1569  return ret;
1570 }
1571 
1572 
1595 l_int32
1597  l_float32 factor,
1598  PTA **pptad,
1599  l_float32 *pa,
1600  l_float32 *pb,
1601  l_float32 *pc,
1602  l_float32 *pmederr,
1603  NUMA **pnafit)
1604 {
1605 l_int32 n, i, ret;
1606 l_float32 x, y, yf, val, mederr;
1607 NUMA *nafit, *naerror;
1608 PTA *ptad;
1609 
1610  PROCNAME("ptaNoisyQuadraticLSF");
1611 
1612  if (pptad) *pptad = NULL;
1613  if (pa) *pa = 0.0;
1614  if (pb) *pb = 0.0;
1615  if (pc) *pc = 0.0;
1616  if (pmederr) *pmederr = 0.0;
1617  if (pnafit) *pnafit = NULL;
1618  if (!pptad && !pa && !pb && !pc && !pnafit)
1619  return ERROR_INT("no output requested", procName, 1);
1620  if (factor <= 0.0)
1621  return ERROR_INT("factor must be > 0.0", procName, 1);
1622  if (!pta)
1623  return ERROR_INT("pta not defined", procName, 1);
1624  if ((n = ptaGetCount(pta)) < 3)
1625  return ERROR_INT("less than 3 pts found", procName, 1);
1626 
1627  if (ptaGetQuadraticLSF(pta, NULL, NULL, NULL, &nafit) != 0)
1628  return ERROR_INT("error in quadratic LSF", procName, 1);
1629 
1630  /* Get the median error */
1631  naerror = numaCreate(n);
1632  for (i = 0; i < n; i++) {
1633  ptaGetPt(pta, i, &x, &y);
1634  numaGetFValue(nafit, i, &yf);
1635  numaAddNumber(naerror, L_ABS(y - yf));
1636  }
1637  numaGetMedian(naerror, &mederr);
1638  if (pmederr) *pmederr = mederr;
1639  numaDestroy(&nafit);
1640 
1641  /* Remove outliers */
1642  ptad = ptaCreate(n);
1643  for (i = 0; i < n; i++) {
1644  ptaGetPt(pta, i, &x, &y);
1645  numaGetFValue(naerror, i, &val);
1646  if (val <= factor * mederr) /* <= in case mederr = 0 */
1647  ptaAddPt(ptad, x, y);
1648  }
1649  numaDestroy(&naerror);
1650  n = ptaGetCount(ptad);
1651  if ((n = ptaGetCount(ptad)) < 3) {
1652  ptaDestroy(&ptad);
1653  return ERROR_INT("less than 3 pts found", procName, 1);
1654  }
1655 
1656  /* Do LSF again */
1657  ret = ptaGetQuadraticLSF(ptad, pa, pb, pc, pnafit);
1658  if (pptad)
1659  *pptad = ptad;
1660  else
1661  ptaDestroy(&ptad);
1662 
1663  return ret;
1664 }
1665 
1666 
1675 l_int32
1676 applyLinearFit(l_float32 a,
1677  l_float32 b,
1678  l_float32 x,
1679  l_float32 *py)
1680 {
1681  PROCNAME("applyLinearFit");
1682 
1683  if (!py)
1684  return ERROR_INT("&y not defined", procName, 1);
1685 
1686  *py = a * x + b;
1687  return 0;
1688 }
1689 
1690 
1699 l_int32
1700 applyQuadraticFit(l_float32 a,
1701  l_float32 b,
1702  l_float32 c,
1703  l_float32 x,
1704  l_float32 *py)
1705 {
1706  PROCNAME("applyQuadraticFit");
1707 
1708  if (!py)
1709  return ERROR_INT("&y not defined", procName, 1);
1710 
1711  *py = a * x * x + b * x + c;
1712  return 0;
1713 }
1714 
1715 
1724 l_int32
1725 applyCubicFit(l_float32 a,
1726  l_float32 b,
1727  l_float32 c,
1728  l_float32 d,
1729  l_float32 x,
1730  l_float32 *py)
1731 {
1732  PROCNAME("applyCubicFit");
1733 
1734  if (!py)
1735  return ERROR_INT("&y not defined", procName, 1);
1736 
1737  *py = a * x * x * x + b * x * x + c * x + d;
1738  return 0;
1739 }
1740 
1741 
1750 l_int32
1751 applyQuarticFit(l_float32 a,
1752  l_float32 b,
1753  l_float32 c,
1754  l_float32 d,
1755  l_float32 e,
1756  l_float32 x,
1757  l_float32 *py)
1758 {
1759 l_float32 x2;
1760 
1761  PROCNAME("applyQuarticFit");
1762 
1763  if (!py)
1764  return ERROR_INT("&y not defined", procName, 1);
1765 
1766  x2 = x * x;
1767  *py = a * x2 * x2 + b * x2 * x + c * x2 + d * x + e;
1768  return 0;
1769 }
1770 
1771 
1772 /*---------------------------------------------------------------------*
1773  * Interconversions with Pix *
1774  *---------------------------------------------------------------------*/
1791 l_int32
1793  PTA *pta,
1794  l_int32 outformat,
1795  const char *title)
1796 {
1797 char buffer[128];
1798 char *rtitle, *gtitle, *btitle;
1799 static l_int32 count = 0; /* require separate temp files for each call */
1800 l_int32 i, x, y, d, w, h, npts, rval, gval, bval;
1801 l_uint32 val;
1802 NUMA *na, *nar, *nag, *nab;
1803 PIX *pixt;
1804 
1805  PROCNAME("pixPlotAlongPta");
1806 
1807  lept_mkdir("lept/plot");
1808 
1809  if (!pixs)
1810  return ERROR_INT("pixs not defined", procName, 1);
1811  if (!pta)
1812  return ERROR_INT("pta not defined", procName, 1);
1813  if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
1814  outformat != GPLOT_EPS && outformat != GPLOT_LATEX) {
1815  L_WARNING("outformat invalid; using GPLOT_PNG\n", procName);
1816  outformat = GPLOT_PNG;
1817  }
1818 
1820  d = pixGetDepth(pixt);
1821  w = pixGetWidth(pixt);
1822  h = pixGetHeight(pixt);
1823  npts = ptaGetCount(pta);
1824  if (d == 32) {
1825  nar = numaCreate(npts);
1826  nag = numaCreate(npts);
1827  nab = numaCreate(npts);
1828  for (i = 0; i < npts; i++) {
1829  ptaGetIPt(pta, i, &x, &y);
1830  if (x < 0 || x >= w)
1831  continue;
1832  if (y < 0 || y >= h)
1833  continue;
1834  pixGetPixel(pixt, x, y, &val);
1835  rval = GET_DATA_BYTE(&val, COLOR_RED);
1836  gval = GET_DATA_BYTE(&val, COLOR_GREEN);
1837  bval = GET_DATA_BYTE(&val, COLOR_BLUE);
1838  numaAddNumber(nar, rval);
1839  numaAddNumber(nag, gval);
1840  numaAddNumber(nab, bval);
1841  }
1842 
1843  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1844  rtitle = stringJoin("Red: ", title);
1845  gplotSimple1(nar, outformat, buffer, rtitle);
1846  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1847  gtitle = stringJoin("Green: ", title);
1848  gplotSimple1(nag, outformat, buffer, gtitle);
1849  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1850  btitle = stringJoin("Blue: ", title);
1851  gplotSimple1(nab, outformat, buffer, btitle);
1852  numaDestroy(&nar);
1853  numaDestroy(&nag);
1854  numaDestroy(&nab);
1855  LEPT_FREE(rtitle);
1856  LEPT_FREE(gtitle);
1857  LEPT_FREE(btitle);
1858  } else {
1859  na = numaCreate(npts);
1860  for (i = 0; i < npts; i++) {
1861  ptaGetIPt(pta, i, &x, &y);
1862  if (x < 0 || x >= w)
1863  continue;
1864  if (y < 0 || y >= h)
1865  continue;
1866  pixGetPixel(pixt, x, y, &val);
1867  numaAddNumber(na, (l_float32)val);
1868  }
1869 
1870  snprintf(buffer, sizeof(buffer), "/tmp/lept/plot/%03d", count++);
1871  gplotSimple1(na, outformat, buffer, title);
1872  numaDestroy(&na);
1873  }
1874  pixDestroy(&pixt);
1875  return 0;
1876 }
1877 
1878 
1892 PTA *
1894  BOX *box)
1895 {
1896 l_int32 i, j, w, h, wpl, xstart, xend, ystart, yend, bw, bh;
1897 l_uint32 *data, *line;
1898 PTA *pta;
1899 
1900  PROCNAME("ptaGetPixelsFromPix");
1901 
1902  if (!pixs || (pixGetDepth(pixs) != 1))
1903  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
1904 
1905  pixGetDimensions(pixs, &w, &h, NULL);
1906  data = pixGetData(pixs);
1907  wpl = pixGetWpl(pixs);
1908  xstart = ystart = 0;
1909  xend = w - 1;
1910  yend = h - 1;
1911  if (box) {
1912  boxGetGeometry(box, &xstart, &ystart, &bw, &bh);
1913  xend = xstart + bw - 1;
1914  yend = ystart + bh - 1;
1915  }
1916 
1917  if ((pta = ptaCreate(0)) == NULL)
1918  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
1919  for (i = ystart; i <= yend; i++) {
1920  line = data + i * wpl;
1921  for (j = xstart; j <= xend; j++) {
1922  if (GET_DATA_BIT(line, j))
1923  ptaAddPt(pta, j, i);
1924  }
1925  }
1926 
1927  return pta;
1928 }
1929 
1930 
1945 PIX *
1947  l_int32 w,
1948  l_int32 h)
1949 {
1950 l_int32 n, i, x, y;
1951 PIX *pix;
1952 
1953  PROCNAME("pixGenerateFromPta");
1954 
1955  if (!pta)
1956  return (PIX *)ERROR_PTR("pta not defined", procName, NULL);
1957 
1958  if ((pix = pixCreate(w, h, 1)) == NULL)
1959  return (PIX *)ERROR_PTR("pix not made", procName, NULL);
1960  n = ptaGetCount(pta);
1961  for (i = 0; i < n; i++) {
1962  ptaGetIPt(pta, i, &x, &y);
1963  if (x < 0 || x >= w || y < 0 || y >= h)
1964  continue;
1965  pixSetPixel(pix, x, y, 1);
1966  }
1967 
1968  return pix;
1969 }
1970 
1971 
1986 PTA *
1988  l_int32 type)
1989 {
1990 PIX *pixt;
1991 PTA *pta;
1992 
1993  PROCNAME("ptaGetBoundaryPixels");
1994 
1995  if (!pixs || (pixGetDepth(pixs) != 1))
1996  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
1997  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
1998  return (PTA *)ERROR_PTR("invalid type", procName, NULL);
1999 
2000  if (type == L_BOUNDARY_FG)
2001  pixt = pixMorphSequence(pixs, "e3.3", 0);
2002  else
2003  pixt = pixMorphSequence(pixs, "d3.3", 0);
2004  pixXor(pixt, pixt, pixs);
2005  pta = ptaGetPixelsFromPix(pixt, NULL);
2006 
2007  pixDestroy(&pixt);
2008  return pta;
2009 }
2010 
2011 
2035 PTAA *
2037  l_int32 type,
2038  l_int32 connectivity,
2039  BOXA **pboxa,
2040  PIXA **ppixa)
2041 {
2042 l_int32 i, n, w, h, x, y, bw, bh, left, right, top, bot;
2043 BOXA *boxa;
2044 PIX *pixt1, *pixt2;
2045 PIXA *pixa;
2046 PTA *pta1, *pta2;
2047 PTAA *ptaa;
2048 
2049  PROCNAME("ptaaGetBoundaryPixels");
2050 
2051  if (pboxa) *pboxa = NULL;
2052  if (ppixa) *ppixa = NULL;
2053  if (!pixs || (pixGetDepth(pixs) != 1))
2054  return (PTAA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2055  if (type != L_BOUNDARY_FG && type != L_BOUNDARY_BG)
2056  return (PTAA *)ERROR_PTR("invalid type", procName, NULL);
2057  if (connectivity != 4 && connectivity != 8)
2058  return (PTAA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
2059 
2060  pixGetDimensions(pixs, &w, &h, NULL);
2061  boxa = pixConnComp(pixs, &pixa, connectivity);
2062  n = boxaGetCount(boxa);
2063  ptaa = ptaaCreate(0);
2064  for (i = 0; i < n; i++) {
2065  pixt1 = pixaGetPix(pixa, i, L_CLONE);
2066  boxaGetBoxGeometry(boxa, i, &x, &y, &bw, &bh);
2067  left = right = top = bot = 0;
2068  if (type == L_BOUNDARY_BG) {
2069  if (x > 0) left = 1;
2070  if (y > 0) top = 1;
2071  if (x + bw < w) right = 1;
2072  if (y + bh < h) bot = 1;
2073  pixt2 = pixAddBorderGeneral(pixt1, left, right, top, bot, 0);
2074  } else {
2075  pixt2 = pixClone(pixt1);
2076  }
2077  pta1 = ptaGetBoundaryPixels(pixt2, type);
2078  pta2 = ptaTransform(pta1, x - left, y - top, 1.0, 1.0);
2079  ptaaAddPta(ptaa, pta2, L_INSERT);
2080  ptaDestroy(&pta1);
2081  pixDestroy(&pixt1);
2082  pixDestroy(&pixt2);
2083  }
2084 
2085  if (pboxa)
2086  *pboxa = boxa;
2087  else
2088  boxaDestroy(&boxa);
2089  if (ppixa)
2090  *ppixa = pixa;
2091  else
2092  pixaDestroy(&pixa);
2093  return ptaa;
2094 }
2095 
2096 
2118 PTAA *
2120  l_int32 *pncc)
2121 {
2122 l_int32 wpl, index, i, j, w, h;
2123 l_uint32 maxval;
2124 l_uint32 *data, *line;
2125 PTA *pta;
2126 PTAA *ptaa;
2127 
2128  PROCNAME("ptaaIndexLabeledPixels");
2129 
2130  if (pncc) *pncc = 0;
2131  if (!pixs || (pixGetDepth(pixs) != 32))
2132  return (PTAA *)ERROR_PTR("pixs undef or not 32 bpp", procName, NULL);
2133 
2134  /* The number of c.c. is the maximum pixel value. Use this to
2135  * initialize ptaa with sufficient pta arrays */
2136  pixGetMaxValueInRect(pixs, NULL, &maxval, NULL, NULL);
2137  if (pncc) *pncc = maxval;
2138  pta = ptaCreate(1);
2139  ptaa = ptaaCreate(maxval + 1);
2140  ptaaInitFull(ptaa, pta);
2141  ptaDestroy(&pta);
2142 
2143  /* Sweep over %pixs, saving the pixel coordinates of each pixel
2144  * with nonzero value in the appropriate pta, indexed by that value. */
2145  pixGetDimensions(pixs, &w, &h, NULL);
2146  data = pixGetData(pixs);
2147  wpl = pixGetWpl(pixs);
2148  for (i = 0; i < h; i++) {
2149  line = data + wpl * i;
2150  for (j = 0; j < w; j++) {
2151  index = line[j];
2152  if (index > 0)
2153  ptaaAddPt(ptaa, index, j, i);
2154  }
2155  }
2156 
2157  return ptaa;
2158 }
2159 
2160 
2175 PTA *
2177  l_int32 x,
2178  l_int32 y,
2179  l_int32 conn)
2180 {
2181 l_int32 w, h;
2182 PTA *pta;
2183 
2184  PROCNAME("ptaGetNeighborPixLocs");
2185 
2186  if (!pixs)
2187  return (PTA *)ERROR_PTR("pixs not defined", procName, NULL);
2188  pixGetDimensions(pixs, &w, &h, NULL);
2189  if (x < 0 || x >= w || y < 0 || y >= h)
2190  return (PTA *)ERROR_PTR("(x,y) not in pixs", procName, NULL);
2191  if (conn != 4 && conn != 8)
2192  return (PTA *)ERROR_PTR("conn not 4 or 8", procName, NULL);
2193 
2194  pta = ptaCreate(conn);
2195  if (x > 0)
2196  ptaAddPt(pta, x - 1, y);
2197  if (x < w - 1)
2198  ptaAddPt(pta, x + 1, y);
2199  if (y > 0)
2200  ptaAddPt(pta, x, y - 1);
2201  if (y < h - 1)
2202  ptaAddPt(pta, x, y + 1);
2203  if (conn == 8) {
2204  if (x > 0) {
2205  if (y > 0)
2206  ptaAddPt(pta, x - 1, y - 1);
2207  if (y < h - 1)
2208  ptaAddPt(pta, x - 1, y + 1);
2209  }
2210  if (x < w - 1) {
2211  if (y > 0)
2212  ptaAddPt(pta, x + 1, y - 1);
2213  if (y < h - 1)
2214  ptaAddPt(pta, x + 1, y + 1);
2215  }
2216  }
2217 
2218  return pta;
2219 }
2220 
2221 
2222 /*---------------------------------------------------------------------*
2223  * Interconversion with Numa *
2224  *---------------------------------------------------------------------*/
2231 PTA *
2233 {
2234 l_int32 i, n;
2235 l_float32 startx, delx, val;
2236 PTA *pta;
2237 
2238  PROCNAME("numaConvertToPta1");
2239 
2240  if (!na)
2241  return (PTA *)ERROR_PTR("na not defined", procName, NULL);
2242 
2243  n = numaGetCount(na);
2244  pta = ptaCreate(n);
2245  numaGetParameters(na, &startx, &delx);
2246  for (i = 0; i < n; i++) {
2247  numaGetFValue(na, i, &val);
2248  ptaAddPt(pta, startx + i * delx, val);
2249  }
2250  return pta;
2251 }
2252 
2253 
2261 PTA *
2263  NUMA *nay)
2264 {
2265 l_int32 i, n, nx, ny;
2266 l_float32 valx, valy;
2267 PTA *pta;
2268 
2269  PROCNAME("numaConvertToPta2");
2270 
2271  if (!nax || !nay)
2272  return (PTA *)ERROR_PTR("nax and nay not both defined", procName, NULL);
2273 
2274  nx = numaGetCount(nax);
2275  ny = numaGetCount(nay);
2276  n = L_MIN(nx, ny);
2277  if (nx != ny)
2278  L_WARNING("nx = %d does not equal ny = %d\n", procName, nx, ny);
2279  pta = ptaCreate(n);
2280  for (i = 0; i < n; i++) {
2281  numaGetFValue(nax, i, &valx);
2282  numaGetFValue(nay, i, &valy);
2283  ptaAddPt(pta, valx, valy);
2284  }
2285  return pta;
2286 }
2287 
2288 
2297 l_int32
2299  NUMA **pnax,
2300  NUMA **pnay)
2301 {
2302 l_int32 i, n;
2303 l_float32 valx, valy;
2304 
2305  PROCNAME("ptaConvertToNuma");
2306 
2307  if (pnax) *pnax = NULL;
2308  if (pnay) *pnay = NULL;
2309  if (!pnax || !pnay)
2310  return ERROR_INT("&nax and &nay not both defined", procName, 1);
2311  if (!pta)
2312  return ERROR_INT("pta not defined", procName, 1);
2313 
2314  n = ptaGetCount(pta);
2315  *pnax = numaCreate(n);
2316  *pnay = numaCreate(n);
2317  for (i = 0; i < n; i++) {
2318  ptaGetPt(pta, i, &valx, &valy);
2319  numaAddNumber(*pnax, valx);
2320  numaAddNumber(*pnay, valy);
2321  }
2322  return 0;
2323 }
2324 
2325 
2326 /*---------------------------------------------------------------------*
2327  * Display Pta and Ptaa *
2328  *---------------------------------------------------------------------*/
2348 PIX *
2350  PIX *pixs,
2351  PTA *pta)
2352 {
2353 l_int32 i, n, w, h, x, y;
2354 l_uint32 rpixel, gpixel, bpixel;
2355 
2356  PROCNAME("pixDisplayPta");
2357 
2358  if (!pixs)
2359  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2360  if (!pta)
2361  return (PIX *)ERROR_PTR("pta not defined", procName, pixd);
2362  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2363  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2364 
2365  if (!pixd)
2366  pixd = pixConvertTo32(pixs);
2367  pixGetDimensions(pixd, &w, &h, NULL);
2368  composeRGBPixel(255, 0, 0, &rpixel); /* start point */
2369  composeRGBPixel(0, 255, 0, &gpixel);
2370  composeRGBPixel(0, 0, 255, &bpixel); /* end point */
2371 
2372  n = ptaGetCount(pta);
2373  for (i = 0; i < n; i++) {
2374  ptaGetIPt(pta, i, &x, &y);
2375  if (x < 0 || x >= w || y < 0 || y >= h)
2376  continue;
2377  if (i == 0)
2378  pixSetPixel(pixd, x, y, rpixel);
2379  else if (i < n - 1)
2380  pixSetPixel(pixd, x, y, gpixel);
2381  else
2382  pixSetPixel(pixd, x, y, bpixel);
2383  }
2384 
2385  return pixd;
2386 }
2387 
2388 
2414 PIX *
2416  PIX *pixs,
2417  PTAA *ptaa,
2418  PIX *pixp,
2419  l_int32 cx,
2420  l_int32 cy)
2421 {
2422 l_int32 i, n;
2423 l_uint32 color;
2424 PIXCMAP *cmap;
2425 PTA *pta;
2426 
2427  PROCNAME("pixDisplayPtaaPattern");
2428 
2429  if (!pixs)
2430  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2431  if (!ptaa)
2432  return (PIX *)ERROR_PTR("ptaa not defined", procName, pixd);
2433  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2434  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2435  if (!pixp)
2436  return (PIX *)ERROR_PTR("pixp not defined", procName, pixd);
2437 
2438  if (!pixd)
2439  pixd = pixConvertTo32(pixs);
2440 
2441  /* Use 256 random colors */
2442  cmap = pixcmapCreateRandom(8, 0, 0);
2443  n = ptaaGetCount(ptaa);
2444  for (i = 0; i < n; i++) {
2445  pixcmapGetColor32(cmap, i % 256, &color);
2446  pta = ptaaGetPta(ptaa, i, L_CLONE);
2447  pixDisplayPtaPattern(pixd, pixd, pta, pixp, cx, cy, color);
2448  ptaDestroy(&pta);
2449  }
2450 
2451  pixcmapDestroy(&cmap);
2452  return pixd;
2453 }
2454 
2455 
2481 PIX *
2483  PIX *pixs,
2484  PTA *pta,
2485  PIX *pixp,
2486  l_int32 cx,
2487  l_int32 cy,
2488  l_uint32 color)
2489 {
2490 l_int32 i, n, w, h, x, y;
2491 PTA *ptat;
2492 
2493  PROCNAME("pixDisplayPtaPattern");
2494 
2495  if (!pixs)
2496  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
2497  if (!pta)
2498  return (PIX *)ERROR_PTR("pta not defined", procName, pixd);
2499  if (pixd && (pixd != pixs || pixGetDepth(pixd) != 32))
2500  return (PIX *)ERROR_PTR("invalid pixd", procName, pixd);
2501  if (!pixp)
2502  return (PIX *)ERROR_PTR("pixp not defined", procName, pixd);
2503 
2504  if (!pixd)
2505  pixd = pixConvertTo32(pixs);
2506  pixGetDimensions(pixs, &w, &h, NULL);
2507  ptat = ptaReplicatePattern(pta, pixp, NULL, cx, cy, w, h);
2508 
2509  n = ptaGetCount(ptat);
2510  for (i = 0; i < n; i++) {
2511  ptaGetIPt(ptat, i, &x, &y);
2512  if (x < 0 || x >= w || y < 0 || y >= h)
2513  continue;
2514  pixSetPixel(pixd, x, y, color);
2515  }
2516 
2517  ptaDestroy(&ptat);
2518  return pixd;
2519 }
2520 
2521 
2541 PTA *
2543  PIX *pixp,
2544  PTA *ptap,
2545  l_int32 cx,
2546  l_int32 cy,
2547  l_int32 w,
2548  l_int32 h)
2549 {
2550 l_int32 i, j, n, np, x, y, xp, yp, xf, yf;
2551 PTA *ptat, *ptad;
2552 
2553  PROCNAME("ptaReplicatePattern");
2554 
2555  if (!ptas)
2556  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
2557  if (!pixp && !ptap)
2558  return (PTA *)ERROR_PTR("no pattern is defined", procName, NULL);
2559  if (pixp && ptap)
2560  L_WARNING("pixp and ptap defined; using ptap\n", procName);
2561 
2562  n = ptaGetCount(ptas);
2563  ptad = ptaCreate(n);
2564  if (ptap)
2565  ptat = ptaClone(ptap);
2566  else
2567  ptat = ptaGetPixelsFromPix(pixp, NULL);
2568  np = ptaGetCount(ptat);
2569  for (i = 0; i < n; i++) {
2570  ptaGetIPt(ptas, i, &x, &y);
2571  for (j = 0; j < np; j++) {
2572  ptaGetIPt(ptat, j, &xp, &yp);
2573  xf = x - cx + xp;
2574  yf = y - cy + yp;
2575  if (xf >= 0 && xf < w && yf >= 0 && yf < h)
2576  ptaAddPt(ptad, xf, yf);
2577  }
2578  }
2579 
2580  ptaDestroy(&ptat);
2581  return ptad;
2582 }
2583 
2584 
2593 PIX *
2595  PTAA *ptaa)
2596 {
2597 l_int32 i, j, w, h, npta, npt, x, y, rv, gv, bv;
2598 l_uint32 *pixela;
2599 NUMA *na1, *na2, *na3;
2600 PIX *pixd;
2601 PTA *pta;
2602 
2603  PROCNAME("pixDisplayPtaa");
2604 
2605  if (!pixs)
2606  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2607  if (!ptaa)
2608  return (PIX *)ERROR_PTR("ptaa not defined", procName, NULL);
2609  npta = ptaaGetCount(ptaa);
2610  if (npta == 0)
2611  return (PIX *)ERROR_PTR("no pta", procName, NULL);
2612 
2613  if ((pixd = pixConvertTo32(pixs)) == NULL)
2614  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2615  pixGetDimensions(pixd, &w, &h, NULL);
2616 
2617  /* Make a colormap for the paths */
2618  if ((pixela = (l_uint32 *)LEPT_CALLOC(npta, sizeof(l_uint32))) == NULL) {
2619  pixDestroy(&pixd);
2620  return (PIX *)ERROR_PTR("calloc fail for pixela", procName, NULL);
2621  }
2622  na1 = numaPseudorandomSequence(256, 14657);
2623  na2 = numaPseudorandomSequence(256, 34631);
2624  na3 = numaPseudorandomSequence(256, 54617);
2625  for (i = 0; i < npta; i++) {
2626  numaGetIValue(na1, i % 256, &rv);
2627  numaGetIValue(na2, i % 256, &gv);
2628  numaGetIValue(na3, i % 256, &bv);
2629  composeRGBPixel(rv, gv, bv, &pixela[i]);
2630  }
2631  numaDestroy(&na1);
2632  numaDestroy(&na2);
2633  numaDestroy(&na3);
2634 
2635  for (i = 0; i < npta; i++) {
2636  pta = ptaaGetPta(ptaa, i, L_CLONE);
2637  npt = ptaGetCount(pta);
2638  for (j = 0; j < npt; j++) {
2639  ptaGetIPt(pta, j, &x, &y);
2640  if (x < 0 || x >= w || y < 0 || y >= h)
2641  continue;
2642  pixSetPixel(pixd, x, y, pixela[i]);
2643  }
2644  ptaDestroy(&pta);
2645  }
2646 
2647  LEPT_FREE(pixela);
2648  return pixd;
2649 }
l_int32 ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1131
l_int32 ptaGetQuadraticLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, NUMA **pnafit)
ptaGetQuadraticLSF()
Definition: ptafunc1.c:1130
l_int32 gaussjordan(l_float32 **a, l_float32 *b, l_int32 n)
gaussjordan()
Definition: affine.c:1346
l_int32 ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:970
l_int32 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:1751
l_int32 gplotSimple1(NUMA *na, l_int32 outformat, const char *outroot, const char *title)
gplotSimple1()
Definition: gplot.c:569
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:322
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:1880
l_int32 numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:472
l_int32 ptaGetCubicLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pd, NUMA **pnafit)
ptaGetCubicLSF()
Definition: ptafunc1.c:1243
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
PIX * pixGenerateFromPta(PTA *pta, l_int32 w, l_int32 h)
pixGenerateFromPta()
Definition: ptafunc1.c:1946
l_int32 ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:341
l_int32 pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:180
l_int32 ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:524
l_int32 ptaGetLinearLSF(PTA *pta, l_float32 *pa, l_float32 *pb, NUMA **pnafit)
ptaGetLinearLSF()
Definition: ptafunc1.c:1029
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:115
l_int32 ptaaJoin(PTAA *ptaad, PTAA *ptaas, l_int32 istart, l_int32 iend)
ptaaJoin()
Definition: ptafunc1.c:202
PIX * pixDisplayPtaaPattern(PIX *pixd, PIX *pixs, PTAA *ptaa, PIX *pixp, l_int32 cx, l_int32 cy)
pixDisplayPtaaPattern()
Definition: ptafunc1.c:2415
l_int32 numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:691
l_int32 boxContainsPt(BOX *box, l_float32 x, l_float32 y, l_int32 *pcontains)
boxContainsPt()
Definition: boxfunc1.c:1080
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:263
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:186
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:503
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:577
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1602
l_int32 ptaConvertToNuma(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaConvertToNuma()
Definition: ptafunc1.c:2298
l_int32 boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:860
PTA * ptaGetBoundaryPixels(PIX *pixs, l_int32 type)
ptaGetBoundaryPixels()
Definition: ptafunc1.c:1987
l_int32 pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2278
l_int32 numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:935
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:117
Definition: pix.h:492
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:962
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:144
PTA * ptaSubsample(PTA *ptas, l_int32 subfactor)
ptaSubsample()
Definition: ptafunc1.c:111
NUMA * numaPseudorandomSequence(l_int32 size, l_int32 seed)
numaPseudorandomSequence()
Definition: numafunc1.c:2969
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:760
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1060
PTA * numaConvertToPta1(NUMA *na)
numaConvertToPta1()
Definition: ptafunc1.c:2232
Definition: array.h:59
static const l_int32 L_INSERT
Definition: pix.h:710
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1574
PIX * pixDisplayPtaa(PIX *pixs, PTAA *ptaa)
pixDisplayPtaa()
Definition: ptafunc1.c:2594
l_int32 ptaNoisyLinearLSF(PTA *pta, l_float32 factor, PTA **pptad, l_float32 *pa, l_float32 *pb, l_float32 *pmederr, NUMA **pnafit)
ptaNoisyLinearLSF()
Definition: ptafunc1.c:1509
l_int32 ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:154
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:295
Definition: pix.h:532
PIX * pixMorphSequence(PIX *pixs, const char *sequence, l_int32 dispsep)
pixMorphSequence()
Definition: morphseq.c:133
PTA * ptaCyclicPerm(PTA *ptas, l_int32 xs, l_int32 ys)
ptaCyclicPerm()
Definition: ptafunc1.c:318
PTA * ptaGetNeighborPixLocs(PIX *pixs, l_int32 x, l_int32 y, l_int32 conn)
ptaGetNeighborPixLocs()
Definition: ptafunc1.c:2176
PTA * ptaSelectByValue(PTA *ptas, l_float32 xth, l_float32 yth, l_int32 type, l_int32 relation)
ptaSelectByValue()
Definition: ptafunc1.c:894
l_int32 ptaContainsPt(PTA *pta, l_int32 x, l_int32 y)
ptaContainsPt()
Definition: ptafunc1.c:650
l_int32 boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:309
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:182
PTAA * ptaaGetBoundaryPixels(PIX *pixs, l_int32 type, l_int32 connectivity, BOXA **pboxa, PIXA **ppixa)
ptaaGetBoundaryPixels()
Definition: ptafunc1.c:2036
PTA * ptaGetInsideBox(PTA *ptas, BOX *box)
ptaGetInsideBox()
Definition: ptafunc1.c:518
l_float32 l_angleBetweenVectors(l_float32 x1, l_float32 y1, l_float32 x2, l_float32 y2)
l_angleBetweenVectors()
Definition: ptafunc1.c:812
l_int32 applyQuadraticFit(l_float32 a, l_float32 b, l_float32 c, l_float32 x, l_float32 *py)
applyQuadraticFit()
Definition: ptafunc1.c:1700
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:517
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:545
l_int32 pixcmapGetColor32(PIXCMAP *cmap, l_int32 index, l_uint32 *pval32)
pixcmapGetColor32()
Definition: colormap.c:749
l_int32 pixPlotAlongPta(PIX *pixs, PTA *pta, l_int32 outformat, const char *title)
pixPlotAlongPta()
Definition: ptafunc1.c:1792
l_int32 ptaGetQuarticLSF(PTA *pta, l_float32 *pa, l_float32 *pb, l_float32 *pc, l_float32 *pd, l_float32 *pe, NUMA **pnafit)
ptaGetQuarticLSF()
Definition: ptafunc1.c:1373
BOX * ptaGetBoundingRegion(PTA *pta)
ptaGetBoundingRegion()
Definition: ptafunc1.c:424
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:224
Definition: pix.h:454
l_float32 * y
Definition: pix.h:522
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:359
PTA * pixFindCornerPixels(PIX *pixs)
pixFindCornerPixels()
Definition: ptafunc1.c:558
l_int32 ptaGetMinMax(PTA *pta, l_float32 *pxmin, l_float32 *pymin, l_float32 *pxmax, l_float32 *pymax)
ptaGetMinMax()
Definition: ptafunc1.c:841
l_int32 ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:554
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1040
l_int32 pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:251
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2542
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:660
l_int32 ptaTestIntersection(PTA *pta1, PTA *pta2)
ptaTestIntersection()
Definition: ptafunc1.c:679
l_int32 composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2659
l_int32 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:1596
PTA * numaConvertToPta2(NUMA *nax, NUMA *nay)
numaConvertToPta2()
Definition: ptafunc1.c:2262
PIX * pixDisplayPta(PIX *pixd, PIX *pixs, PTA *pta)
pixDisplayPta()
Definition: ptafunc1.c:2349
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:451
Definition: pix.h:134
Definition: pix.h:706
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
l_int32 applyCubicFit(l_float32 a, l_float32 b, l_float32 c, l_float32 d, l_float32 x, l_float32 *py)
applyCubicFit()
Definition: ptafunc1.c:1725
l_int32 ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:468
PTA * ptaSelectRange(PTA *ptas, l_int32 first, l_int32 last)
ptaSelectRange()
Definition: ptafunc1.c:374
l_int32 applyLinearFit(l_float32 a, l_float32 b, l_float32 x, l_float32 *py)
applyLinearFit()
Definition: ptafunc1.c:1676
l_int32 numaGetMedian(NUMA *na, l_float32 *pval)
numaGetMedian()
Definition: numafunc1.c:3119
Definition: pix.h:201
PTAA * ptaaIndexLabeledPixels(PIX *pixs, l_int32 *pncc)
ptaaIndexLabeledPixels()
Definition: ptafunc1.c:2119
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:715
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:726
PTA * ptaTransform(PTA *ptas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
ptaTransform()
Definition: ptafunc1.c:720
PIX * pixDisplayPtaPattern(PIX *pixd, PIX *pixs, PTA *pta, PIX *pixp, l_int32 cx, l_int32 cy, l_uint32 color)
pixDisplayPtaPattern()
Definition: ptafunc1.c:2482
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1052
PTA * ptaReverse(PTA *ptas, l_int32 type)
ptaReverse()
Definition: ptafunc1.c:242
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1893
Definition: pix.h:480
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:398
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:164
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1830
PTA * ptaTranspose(PTA *ptas)
ptaTranspose()
Definition: ptafunc1.c:278
Definition: pix.h:517
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:157
l_int32 ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1201