Leptonica  1.83.1
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  if (!ptas)
226  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
227 
228  npts = ptaGetCount(ptas);
229  if ((ptad = ptaCreate(npts)) == NULL)
230  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
231  for (i = 0; i < npts; i++) {
232  ptaGetPt(ptas, i, &x, &y);
233  ptaAddPt(ptad, x + transx, y + transy);
234  }
235 
236  return ptad;
237 }
238 
239 
253 PTA *
254 ptaScale(PTA *ptas,
255  l_float32 scalex,
256  l_float32 scaley)
257 {
258 l_int32 i, npts;
259 l_float32 x, y;
260 PTA *ptad;
261 
262  if (!ptas)
263  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
264 
265  npts = ptaGetCount(ptas);
266  if ((ptad = ptaCreate(npts)) == NULL)
267  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
268  for (i = 0; i < npts; i++) {
269  ptaGetPt(ptas, i, &x, &y);
270  ptaAddPt(ptad, scalex * x, scaley * y);
271  }
272 
273  return ptad;
274 }
275 
276 
302 PTA *
304  l_float32 xc,
305  l_float32 yc,
306  l_float32 angle)
307 {
308 l_int32 i, npts;
309 l_float32 x, y, xp, yp, sina, cosa;
310 PTA *ptad;
311 
312  if (!ptas)
313  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
314 
315  npts = ptaGetCount(ptas);
316  if ((ptad = ptaCreate(npts)) == NULL)
317  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
318  sina = sin(angle);
319  cosa = cos(angle);
320  for (i = 0; i < npts; i++) {
321  ptaGetPt(ptas, i, &x, &y);
322  xp = xc + (x - xc) * cosa - (y - yc) * sina;
323  yp = yc + (x - xc) * sina + (y - yc) * cosa;
324  ptaAddPt(ptad, xp, yp);
325  }
326 
327  return ptad;
328 }
329 
330 
331 /*-------------------------------------------------------------*
332  * Special coordinate transforms on boxa *
333  *-------------------------------------------------------------*/
345 BOXA *
347  l_float32 transx,
348  l_float32 transy)
349 {
350 PTA *ptas, *ptad;
351 BOXA *boxad;
352 
353  if (!boxas)
354  return (BOXA *)ERROR_PTR("boxas not defined", __func__, NULL);
355 
356  ptas = boxaConvertToPta(boxas, 4);
357  ptad = ptaTranslate(ptas, transx, transy);
358  boxad = ptaConvertToBoxa(ptad, 4);
359  ptaDestroy(&ptas);
360  ptaDestroy(&ptad);
361  return boxad;
362 }
363 
364 
376 BOXA *
378  l_float32 scalex,
379  l_float32 scaley)
380 {
381 PTA *ptas, *ptad;
382 BOXA *boxad;
383 
384  if (!boxas)
385  return (BOXA *)ERROR_PTR("boxas not defined", __func__, NULL);
386 
387  ptas = boxaConvertToPta(boxas, 4);
388  ptad = ptaScale(ptas, scalex, scaley);
389  boxad = ptaConvertToBoxa(ptad, 4);
390  ptaDestroy(&ptas);
391  ptaDestroy(&ptad);
392  return boxad;
393 }
394 
395 
407 BOXA *
409  l_float32 xc,
410  l_float32 yc,
411  l_float32 angle)
412 {
413 PTA *ptas, *ptad;
414 BOXA *boxad;
415 
416  if (!boxas)
417  return (BOXA *)ERROR_PTR("boxas not defined", __func__, NULL);
418 
419  ptas = boxaConvertToPta(boxas, 4);
420  ptad = ptaRotate(ptas, xc, yc, angle);
421  boxad = ptaConvertToBoxa(ptad, 4);
422  ptaDestroy(&ptas);
423  ptaDestroy(&ptad);
424  return boxad;
425 }
426 
427 
428 /*-------------------------------------------------------------*
429  * General affine coordinate transform *
430  *-------------------------------------------------------------*/
438 PTA *
440  l_float32 *mat)
441 {
442 l_int32 i, npts;
443 l_float32 vecs[3], vecd[3];
444 PTA *ptad;
445 
446  if (!ptas)
447  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
448  if (!mat)
449  return (PTA *)ERROR_PTR("transform not defined", __func__, NULL);
450 
451  vecs[2] = 1;
452  npts = ptaGetCount(ptas);
453  if ((ptad = ptaCreate(npts)) == NULL)
454  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
455  for (i = 0; i < npts; i++) {
456  ptaGetPt(ptas, i, &vecs[0], &vecs[1]);
457  l_productMatVec(mat, vecs, vecd, 3);
458  ptaAddPt(ptad, vecd[0], vecd[1]);
459  }
460 
461  return ptad;
462 }
463 
464 
472 BOXA *
474  l_float32 *mat)
475 {
476 PTA *ptas, *ptad;
477 BOXA *boxad;
478 
479  if (!boxas)
480  return (BOXA *)ERROR_PTR("boxas not defined", __func__, NULL);
481  if (!mat)
482  return (BOXA *)ERROR_PTR("transform not defined", __func__, NULL);
483 
484  ptas = boxaConvertToPta(boxas, 4);
485  ptad = ptaAffineTransform(ptas, mat);
486  boxad = ptaConvertToBoxa(ptad, 4);
487  ptaDestroy(&ptas);
488  ptaDestroy(&ptad);
489  return boxad;
490 }
491 
492 
493 /*-------------------------------------------------------------*
494  * Matrix operations *
495  *-------------------------------------------------------------*/
505 l_ok
506 l_productMatVec(l_float32 *mat,
507  l_float32 *vecs,
508  l_float32 *vecd,
509  l_int32 size)
510 {
511 l_int32 i, j;
512 
513  if (!mat)
514  return ERROR_INT("matrix not defined", __func__, 1);
515  if (!vecs)
516  return ERROR_INT("input vector not defined", __func__, 1);
517  if (!vecd)
518  return ERROR_INT("result vector not defined", __func__, 1);
519 
520  for (i = 0; i < size; i++) {
521  vecd[i] = 0;
522  for (j = 0; j < size; j++) {
523  vecd[i] += mat[size * i + j] * vecs[j];
524  }
525  }
526  return 0;
527 }
528 
529 
539 l_ok
540 l_productMat2(l_float32 *mat1,
541  l_float32 *mat2,
542  l_float32 *matd,
543  l_int32 size)
544 {
545 l_int32 i, j, k, index;
546 
547  if (!mat1)
548  return ERROR_INT("matrix 1 not defined", __func__, 1);
549  if (!mat2)
550  return ERROR_INT("matrix 2 not defined", __func__, 1);
551  if (!matd)
552  return ERROR_INT("result matrix not defined", __func__, 1);
553 
554  for (i = 0; i < size; i++) {
555  for (j = 0; j < size; j++) {
556  index = size * i + j;
557  matd[index] = 0;
558  for (k = 0; k < size; k++)
559  matd[index] += mat1[size * i + k] * mat2[size * k + j];
560  }
561  }
562  return 0;
563 }
564 
565 
576 l_ok
577 l_productMat3(l_float32 *mat1,
578  l_float32 *mat2,
579  l_float32 *mat3,
580  l_float32 *matd,
581  l_int32 size)
582 {
583 l_float32 *matt;
584 
585  if (!mat1)
586  return ERROR_INT("matrix 1 not defined", __func__, 1);
587  if (!mat2)
588  return ERROR_INT("matrix 2 not defined", __func__, 1);
589  if (!mat3)
590  return ERROR_INT("matrix 3 not defined", __func__, 1);
591  if (!matd)
592  return ERROR_INT("result matrix not defined", __func__, 1);
593 
594  if ((matt = (l_float32 *)LEPT_CALLOC((size_t)size * size,
595  sizeof(l_float32))) == NULL)
596  return ERROR_INT("matt not made", __func__, 1);
597  l_productMat2(mat1, mat2, matt, size);
598  l_productMat2(matt, mat3, matd, size);
599  LEPT_FREE(matt);
600  return 0;
601 }
602 
603 
615 l_ok
616 l_productMat4(l_float32 *mat1,
617  l_float32 *mat2,
618  l_float32 *mat3,
619  l_float32 *mat4,
620  l_float32 *matd,
621  l_int32 size)
622 {
623 l_float32 *matt;
624 
625  if (!mat1)
626  return ERROR_INT("matrix 1 not defined", __func__, 1);
627  if (!mat2)
628  return ERROR_INT("matrix 2 not defined", __func__, 1);
629  if (!mat3)
630  return ERROR_INT("matrix 3 not defined", __func__, 1);
631  if (!matd)
632  return ERROR_INT("result matrix not defined", __func__, 1);
633 
634  if ((matt = (l_float32 *)LEPT_CALLOC((size_t)size * size,
635  sizeof(l_float32))) == NULL)
636  return ERROR_INT("matt not made", __func__, 1);
637  l_productMat3(mat1, mat2, mat3, matt, size);
638  l_productMat2(matt, mat4, matd, size);
639  LEPT_FREE(matt);
640  return 0;
641 }
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:781
PTA * boxaConvertToPta(BOXA *boxa, l_int32 ncorners)
boxaConvertToPta()
Definition: boxfunc4.c:738
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:328
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:499
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:480
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191