Leptonica 1.82.0
Image processing and image analysis suite
affinecompose.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
58#ifdef HAVE_CONFIG_H
59#include <config_auto.h>
60#endif /* HAVE_CONFIG_H */
61
62#include <math.h>
63#include "allheaders.h"
64
65/*-------------------------------------------------------------*
66 * Composable coordinate transforms *
67 *-------------------------------------------------------------*/
92l_float32 *
93createMatrix2dTranslate(l_float32 transx,
94 l_float32 transy)
95{
96l_float32 *mat;
97
98 mat = (l_float32 *)LEPT_CALLOC(9, sizeof(l_float32));
99 mat[0] = mat[4] = mat[8] = 1;
100 mat[2] = transx;
101 mat[5] = transy;
102 return mat;
103}
104
105
129l_float32 *
130createMatrix2dScale(l_float32 scalex,
131 l_float32 scaley)
132{
133l_float32 *mat;
134
135 mat = (l_float32 *)LEPT_CALLOC(9, sizeof(l_float32));
136 mat[0] = scalex;
137 mat[4] = scaley;
138 mat[8] = 1;
139 return mat;
140}
141
142
178l_float32 *
180 l_float32 yc,
181 l_float32 angle)
182{
183l_float32 sina, cosa;
184l_float32 *mat;
185
186 mat = (l_float32 *)LEPT_CALLOC(9, sizeof(l_float32));
187 sina = sin(angle);
188 cosa = cos(angle);
189 mat[0] = mat[4] = cosa;
190 mat[1] = -sina;
191 mat[2] = xc * (1.0 - cosa) + yc * sina;
192 mat[3] = sina;
193 mat[5] = yc * (1.0 - cosa) - xc * sina;
194 mat[8] = 1;
195 return mat;
196}
197
198
199
200/*-------------------------------------------------------------*
201 * Special coordinate transforms on pta *
202 *-------------------------------------------------------------*/
216PTA *
218 l_float32 transx,
219 l_float32 transy)
220{
221l_int32 i, npts;
222l_float32 x, y;
223PTA *ptad;
224
225 PROCNAME("ptaTranslate");
226
227 if (!ptas)
228 return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
229
230 npts = ptaGetCount(ptas);
231 if ((ptad = ptaCreate(npts)) == NULL)
232 return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
233 for (i = 0; i < npts; i++) {
234 ptaGetPt(ptas, i, &x, &y);
235 ptaAddPt(ptad, x + transx, y + transy);
236 }
237
238 return ptad;
239}
240
241
255PTA *
257 l_float32 scalex,
258 l_float32 scaley)
259{
260l_int32 i, npts;
261l_float32 x, y;
262PTA *ptad;
263
264 PROCNAME("ptaScale");
265
266 if (!ptas)
267 return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
268
269 npts = ptaGetCount(ptas);
270 if ((ptad = ptaCreate(npts)) == NULL)
271 return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
272 for (i = 0; i < npts; i++) {
273 ptaGetPt(ptas, i, &x, &y);
274 ptaAddPt(ptad, scalex * x, scaley * y);
275 }
276
277 return ptad;
278}
279
280
306PTA *
308 l_float32 xc,
309 l_float32 yc,
310 l_float32 angle)
311{
312l_int32 i, npts;
313l_float32 x, y, xp, yp, sina, cosa;
314PTA *ptad;
315
316 PROCNAME("ptaRotate");
317
318 if (!ptas)
319 return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
320
321 npts = ptaGetCount(ptas);
322 if ((ptad = ptaCreate(npts)) == NULL)
323 return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
324 sina = sin(angle);
325 cosa = cos(angle);
326 for (i = 0; i < npts; i++) {
327 ptaGetPt(ptas, i, &x, &y);
328 xp = xc + (x - xc) * cosa - (y - yc) * sina;
329 yp = yc + (x - xc) * sina + (y - yc) * cosa;
330 ptaAddPt(ptad, xp, yp);
331 }
332
333 return ptad;
334}
335
336
337/*-------------------------------------------------------------*
338 * Special coordinate transforms on boxa *
339 *-------------------------------------------------------------*/
351BOXA *
353 l_float32 transx,
354 l_float32 transy)
355{
356PTA *ptas, *ptad;
357BOXA *boxad;
358
359 PROCNAME("boxaTranslate");
360
361 if (!boxas)
362 return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
363
364 ptas = boxaConvertToPta(boxas, 4);
365 ptad = ptaTranslate(ptas, transx, transy);
366 boxad = ptaConvertToBoxa(ptad, 4);
367 ptaDestroy(&ptas);
368 ptaDestroy(&ptad);
369 return boxad;
370}
371
372
384BOXA *
386 l_float32 scalex,
387 l_float32 scaley)
388{
389PTA *ptas, *ptad;
390BOXA *boxad;
391
392 PROCNAME("boxaScale");
393
394 if (!boxas)
395 return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
396
397 ptas = boxaConvertToPta(boxas, 4);
398 ptad = ptaScale(ptas, scalex, scaley);
399 boxad = ptaConvertToBoxa(ptad, 4);
400 ptaDestroy(&ptas);
401 ptaDestroy(&ptad);
402 return boxad;
403}
404
405
417BOXA *
419 l_float32 xc,
420 l_float32 yc,
421 l_float32 angle)
422{
423PTA *ptas, *ptad;
424BOXA *boxad;
425
426 PROCNAME("boxaRotate");
427
428 if (!boxas)
429 return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
430
431 ptas = boxaConvertToPta(boxas, 4);
432 ptad = ptaRotate(ptas, xc, yc, angle);
433 boxad = ptaConvertToBoxa(ptad, 4);
434 ptaDestroy(&ptas);
435 ptaDestroy(&ptad);
436 return boxad;
437}
438
439
440/*-------------------------------------------------------------*
441 * General affine coordinate transform *
442 *-------------------------------------------------------------*/
450PTA *
452 l_float32 *mat)
453{
454l_int32 i, npts;
455l_float32 vecs[3], vecd[3];
456PTA *ptad;
457
458 PROCNAME("ptaAffineTransform");
459
460 if (!ptas)
461 return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
462 if (!mat)
463 return (PTA *)ERROR_PTR("transform not defined", procName, NULL);
464
465 vecs[2] = 1;
466 npts = ptaGetCount(ptas);
467 if ((ptad = ptaCreate(npts)) == NULL)
468 return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
469 for (i = 0; i < npts; i++) {
470 ptaGetPt(ptas, i, &vecs[0], &vecs[1]);
471 l_productMatVec(mat, vecs, vecd, 3);
472 ptaAddPt(ptad, vecd[0], vecd[1]);
473 }
474
475 return ptad;
476}
477
478
486BOXA *
488 l_float32 *mat)
489{
490PTA *ptas, *ptad;
491BOXA *boxad;
492
493 PROCNAME("boxaAffineTransform");
494
495 if (!boxas)
496 return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
497 if (!mat)
498 return (BOXA *)ERROR_PTR("transform not defined", procName, NULL);
499
500 ptas = boxaConvertToPta(boxas, 4);
501 ptad = ptaAffineTransform(ptas, mat);
502 boxad = ptaConvertToBoxa(ptad, 4);
503 ptaDestroy(&ptas);
504 ptaDestroy(&ptad);
505 return boxad;
506}
507
508
509/*-------------------------------------------------------------*
510 * Matrix operations *
511 *-------------------------------------------------------------*/
521l_ok
522l_productMatVec(l_float32 *mat,
523 l_float32 *vecs,
524 l_float32 *vecd,
525 l_int32 size)
526{
527l_int32 i, j;
528
529 PROCNAME("l_productMatVec");
530
531 if (!mat)
532 return ERROR_INT("matrix not defined", procName, 1);
533 if (!vecs)
534 return ERROR_INT("input vector not defined", procName, 1);
535 if (!vecd)
536 return ERROR_INT("result vector not defined", procName, 1);
537
538 for (i = 0; i < size; i++) {
539 vecd[i] = 0;
540 for (j = 0; j < size; j++) {
541 vecd[i] += mat[size * i + j] * vecs[j];
542 }
543 }
544 return 0;
545}
546
547
557l_ok
558l_productMat2(l_float32 *mat1,
559 l_float32 *mat2,
560 l_float32 *matd,
561 l_int32 size)
562{
563l_int32 i, j, k, index;
564
565 PROCNAME("l_productMat2");
566
567 if (!mat1)
568 return ERROR_INT("matrix 1 not defined", procName, 1);
569 if (!mat2)
570 return ERROR_INT("matrix 2 not defined", procName, 1);
571 if (!matd)
572 return ERROR_INT("result matrix not defined", procName, 1);
573
574 for (i = 0; i < size; i++) {
575 for (j = 0; j < size; j++) {
576 index = size * i + j;
577 matd[index] = 0;
578 for (k = 0; k < size; k++)
579 matd[index] += mat1[size * i + k] * mat2[size * k + j];
580 }
581 }
582 return 0;
583}
584
585
596l_ok
597l_productMat3(l_float32 *mat1,
598 l_float32 *mat2,
599 l_float32 *mat3,
600 l_float32 *matd,
601 l_int32 size)
602{
603l_float32 *matt;
604
605 PROCNAME("l_productMat3");
606
607 if (!mat1)
608 return ERROR_INT("matrix 1 not defined", procName, 1);
609 if (!mat2)
610 return ERROR_INT("matrix 2 not defined", procName, 1);
611 if (!mat3)
612 return ERROR_INT("matrix 3 not defined", procName, 1);
613 if (!matd)
614 return ERROR_INT("result matrix not defined", procName, 1);
615
616 if ((matt = (l_float32 *)LEPT_CALLOC((size_t)size * size,
617 sizeof(l_float32))) == NULL)
618 return ERROR_INT("matt not made", procName, 1);
619 l_productMat2(mat1, mat2, matt, size);
620 l_productMat2(matt, mat3, matd, size);
621 LEPT_FREE(matt);
622 return 0;
623}
624
625
637l_ok
638l_productMat4(l_float32 *mat1,
639 l_float32 *mat2,
640 l_float32 *mat3,
641 l_float32 *mat4,
642 l_float32 *matd,
643 l_int32 size)
644{
645l_float32 *matt;
646
647 PROCNAME("l_productMat4");
648
649 if (!mat1)
650 return ERROR_INT("matrix 1 not defined", procName, 1);
651 if (!mat2)
652 return ERROR_INT("matrix 2 not defined", procName, 1);
653 if (!mat3)
654 return ERROR_INT("matrix 3 not defined", procName, 1);
655 if (!matd)
656 return ERROR_INT("result matrix not defined", procName, 1);
657
658 if ((matt = (l_float32 *)LEPT_CALLOC((size_t)size * size,
659 sizeof(l_float32))) == NULL)
660 return ERROR_INT("matt not made", procName, 1);
661 l_productMat3(mat1, mat2, mat3, matt, size);
662 l_productMat2(matt, mat4, matd, size);
663 LEPT_FREE(matt);
664 return 0;
665}
l_ok l_productMat4(l_float32 *mat1, l_float32 *mat2, l_float32 *mat3, l_float32 *mat4, l_float32 *matd, l_int32 size)
l_productMat4()
PTA * ptaTranslate(PTA *ptas, l_float32 transx, l_float32 transy)
ptaTranslate()
BOXA * boxaAffineTransform(BOXA *boxas, l_float32 *mat)
boxaAffineTransform()
BOXA * boxaScale(BOXA *boxas, l_float32 scalex, l_float32 scaley)
boxaScale()
BOXA * boxaTranslate(BOXA *boxas, l_float32 transx, l_float32 transy)
boxaTranslate()
PTA * ptaScale(PTA *ptas, l_float32 scalex, l_float32 scaley)
ptaScale()
BOXA * boxaRotate(BOXA *boxas, l_float32 xc, l_float32 yc, l_float32 angle)
boxaRotate()
l_float32 * createMatrix2dTranslate(l_float32 transx, l_float32 transy)
createMatrix2dTranslate()
Definition: affinecompose.c:93
l_ok l_productMat3(l_float32 *mat1, l_float32 *mat2, l_float32 *mat3, l_float32 *matd, l_int32 size)
l_productMat3()
l_float32 * createMatrix2dScale(l_float32 scalex, l_float32 scaley)
createMatrix2dScale()
PTA * ptaAffineTransform(PTA *ptas, l_float32 *mat)
ptaAffineTransform()
l_float32 * createMatrix2dRotate(l_float32 xc, l_float32 yc, l_float32 angle)
createMatrix2dRotate()
l_ok l_productMatVec(l_float32 *mat, l_float32 *vecs, l_float32 *vecd, l_int32 size)
l_productMatVec()
PTA * ptaRotate(PTA *ptas, l_float32 xc, l_float32 yc, l_float32 angle)
ptaRotate()
l_ok l_productMat2(l_float32 *mat1, l_float32 *mat2, l_float32 *matd, l_int32 size)
l_productMat2()
PTA * boxaConvertToPta(BOXA *boxa, l_int32 ncorners)
boxaConvertToPta()
Definition: boxfunc4.c:761
BOXA * ptaConvertToBoxa(PTA *pta, l_int32 ncorners)
ptaConvertToBoxa()
Definition: boxfunc4.c:806
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
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
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
Definition: pix.h:492
Definition: pix.h:517