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