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  *-------------------------------------------------------------*/
92 l_float32 *
93 createMatrix2dTranslate(l_float32 transx,
94  l_float32 transy)
95 {
96 l_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 
129 l_float32 *
130 createMatrix2dScale(l_float32 scalex,
131  l_float32 scaley)
132 {
133 l_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 
178 l_float32 *
179 createMatrix2dRotate(l_float32 xc,
180  l_float32 yc,
181  l_float32 angle)
182 {
183 l_float32 sina, cosa;
184 l_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  *-------------------------------------------------------------*/
216 PTA *
218  l_float32 transx,
219  l_float32 transy)
220 {
221 l_int32 i, npts;
222 l_float32 x, y;
223 PTA *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 
255 PTA *
256 ptaScale(PTA *ptas,
257  l_float32 scalex,
258  l_float32 scaley)
259 {
260 l_int32 i, npts;
261 l_float32 x, y;
262 PTA *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 
306 PTA *
308  l_float32 xc,
309  l_float32 yc,
310  l_float32 angle)
311 {
312 l_int32 i, npts;
313 l_float32 x, y, xp, yp, sina, cosa;
314 PTA *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  *-------------------------------------------------------------*/
351 BOXA *
353  l_float32 transx,
354  l_float32 transy)
355 {
356 PTA *ptas, *ptad;
357 BOXA *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 
384 BOXA *
386  l_float32 scalex,
387  l_float32 scaley)
388 {
389 PTA *ptas, *ptad;
390 BOXA *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 
417 BOXA *
419  l_float32 xc,
420  l_float32 yc,
421  l_float32 angle)
422 {
423 PTA *ptas, *ptad;
424 BOXA *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  *-------------------------------------------------------------*/
450 PTA *
452  l_float32 *mat)
453 {
454 l_int32 i, npts;
455 l_float32 vecs[3], vecd[3];
456 PTA *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 
486 BOXA *
488  l_float32 *mat)
489 {
490 PTA *ptas, *ptad;
491 BOXA *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  *-------------------------------------------------------------*/
521 l_ok
522 l_productMatVec(l_float32 *mat,
523  l_float32 *vecs,
524  l_float32 *vecd,
525  l_int32 size)
526 {
527 l_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 
557 l_ok
558 l_productMat2(l_float32 *mat1,
559  l_float32 *mat2,
560  l_float32 *matd,
561  l_int32 size)
562 {
563 l_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 
596 l_ok
597 l_productMat3(l_float32 *mat1,
598  l_float32 *mat2,
599  l_float32 *mat3,
600  l_float32 *matd,
601  l_int32 size)
602 {
603 l_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 
637 l_ok
638 l_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 {
645 l_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()
BOXA * boxaRotate(BOXA *boxas, l_float32 xc, l_float32 yc, l_float32 angle)
boxaRotate()
BOXA * boxaScale(BOXA *boxas, l_float32 scalex, l_float32 scaley)
boxaScale()
PTA * ptaRotate(PTA *ptas, l_float32 xc, l_float32 yc, l_float32 angle)
ptaRotate()
PTA * ptaScale(PTA *ptas, l_float32 scalex, l_float32 scaley)
ptaScale()
l_float32 * createMatrix2dRotate(l_float32 xc, l_float32 yc, l_float32 angle)
createMatrix2dRotate()
BOXA * boxaTranslate(BOXA *boxas, l_float32 transx, l_float32 transy)
boxaTranslate()
l_ok l_productMat3(l_float32 *mat1, l_float32 *mat2, l_float32 *mat3, l_float32 *matd, l_int32 size)
l_productMat3()
PTA * ptaTranslate(PTA *ptas, l_float32 transx, l_float32 transy)
ptaTranslate()
l_float32 * createMatrix2dTranslate(l_float32 transx, l_float32 transy)
createMatrix2dTranslate()
Definition: affinecompose.c:93
PTA * ptaAffineTransform(PTA *ptas, l_float32 *mat)
ptaAffineTransform()
l_float32 * createMatrix2dScale(l_float32 scalex, l_float32 scaley)
createMatrix2dScale()
BOXA * boxaAffineTransform(BOXA *boxas, l_float32 *mat)
boxaAffineTransform()
l_ok l_productMatVec(l_float32 *mat, l_float32 *vecs, l_float32 *vecd, l_int32 size)
l_productMatVec()
l_ok l_productMat2(l_float32 *mat1, l_float32 *mat2, l_float32 *matd, l_int32 size)
l_productMat2()
BOXA * ptaConvertToBoxa(PTA *pta, l_int32 ncorners)
ptaConvertToBoxa()
Definition: boxfunc4.c:806
PTA * boxaConvertToPta(BOXA *boxa, l_int32 ncorners)
boxaConvertToPta()
Definition: boxfunc4.c:761
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
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
Definition: pix.h:492
Definition: pix.h:517