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