Leptonica  1.77.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 #include <math.h>
59 #include "allheaders.h"
60 
61 
62 /*-------------------------------------------------------------*
63  * Composable coordinate transforms *
64  *-------------------------------------------------------------*/
89 l_float32 *
90 createMatrix2dTranslate(l_float32 transx,
91  l_float32 transy)
92 {
93 l_float32 *mat;
94 
95  PROCNAME("createMatrix2dTranslate");
96 
97  if ((mat = (l_float32 *)LEPT_CALLOC(9, sizeof(l_float32))) == NULL)
98  return (l_float32 *)ERROR_PTR("mat not made", procName, NULL);
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  PROCNAME("createMatrix2dScale");
136 
137  if ((mat = (l_float32 *)LEPT_CALLOC(9, sizeof(l_float32))) == NULL)
138  return (l_float32 *)ERROR_PTR("mat not made", procName, NULL);
139  mat[0] = scalex;
140  mat[4] = scaley;
141  mat[8] = 1;
142  return mat;
143 }
144 
145 
181 l_float32 *
182 createMatrix2dRotate(l_float32 xc,
183  l_float32 yc,
184  l_float32 angle)
185 {
186 l_float32 sina, cosa;
187 l_float32 *mat;
188 
189  PROCNAME("createMatrix2dRotate");
190 
191  if ((mat = (l_float32 *)LEPT_CALLOC(9, sizeof(l_float32))) == NULL)
192  return (l_float32 *)ERROR_PTR("mat not made", procName, NULL);
193  sina = sin(angle);
194  cosa = cos(angle);
195  mat[0] = mat[4] = cosa;
196  mat[1] = -sina;
197  mat[2] = xc * (1.0 - cosa) + yc * sina;
198  mat[3] = sina;
199  mat[5] = yc * (1.0 - cosa) - xc * sina;
200  mat[8] = 1;
201  return mat;
202 }
203 
204 
205 
206 /*-------------------------------------------------------------*
207  * Special coordinate transforms on pta *
208  *-------------------------------------------------------------*/
222 PTA *
224  l_float32 transx,
225  l_float32 transy)
226 {
227 l_int32 i, npts;
228 l_float32 x, y;
229 PTA *ptad;
230 
231  PROCNAME("ptaTranslate");
232 
233  if (!ptas)
234  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
235 
236  npts = ptaGetCount(ptas);
237  if ((ptad = ptaCreate(npts)) == NULL)
238  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
239  for (i = 0; i < npts; i++) {
240  ptaGetPt(ptas, i, &x, &y);
241  ptaAddPt(ptad, x + transx, y + transy);
242  }
243 
244  return ptad;
245 }
246 
247 
261 PTA *
262 ptaScale(PTA *ptas,
263  l_float32 scalex,
264  l_float32 scaley)
265 {
266 l_int32 i, npts;
267 l_float32 x, y;
268 PTA *ptad;
269 
270  PROCNAME("ptaScale");
271 
272  if (!ptas)
273  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
274 
275  npts = ptaGetCount(ptas);
276  if ((ptad = ptaCreate(npts)) == NULL)
277  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
278  for (i = 0; i < npts; i++) {
279  ptaGetPt(ptas, i, &x, &y);
280  ptaAddPt(ptad, scalex * x, scaley * y);
281  }
282 
283  return ptad;
284 }
285 
286 
312 PTA *
314  l_float32 xc,
315  l_float32 yc,
316  l_float32 angle)
317 {
318 l_int32 i, npts;
319 l_float32 x, y, xp, yp, sina, cosa;
320 PTA *ptad;
321 
322  PROCNAME("ptaRotate");
323 
324  if (!ptas)
325  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
326 
327  npts = ptaGetCount(ptas);
328  if ((ptad = ptaCreate(npts)) == NULL)
329  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
330  sina = sin(angle);
331  cosa = cos(angle);
332  for (i = 0; i < npts; i++) {
333  ptaGetPt(ptas, i, &x, &y);
334  xp = xc + (x - xc) * cosa - (y - yc) * sina;
335  yp = yc + (x - xc) * sina + (y - yc) * cosa;
336  ptaAddPt(ptad, xp, yp);
337  }
338 
339  return ptad;
340 }
341 
342 
343 /*-------------------------------------------------------------*
344  * Special coordinate transforms on boxa *
345  *-------------------------------------------------------------*/
357 BOXA *
359  l_float32 transx,
360  l_float32 transy)
361 {
362 PTA *ptas, *ptad;
363 BOXA *boxad;
364 
365  PROCNAME("boxaTranslate");
366 
367  if (!boxas)
368  return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
369 
370  ptas = boxaConvertToPta(boxas, 4);
371  ptad = ptaTranslate(ptas, transx, transy);
372  boxad = ptaConvertToBoxa(ptad, 4);
373  ptaDestroy(&ptas);
374  ptaDestroy(&ptad);
375  return boxad;
376 }
377 
378 
390 BOXA *
392  l_float32 scalex,
393  l_float32 scaley)
394 {
395 PTA *ptas, *ptad;
396 BOXA *boxad;
397 
398  PROCNAME("boxaScale");
399 
400  if (!boxas)
401  return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
402 
403  ptas = boxaConvertToPta(boxas, 4);
404  ptad = ptaScale(ptas, scalex, scaley);
405  boxad = ptaConvertToBoxa(ptad, 4);
406  ptaDestroy(&ptas);
407  ptaDestroy(&ptad);
408  return boxad;
409 }
410 
411 
423 BOXA *
425  l_float32 xc,
426  l_float32 yc,
427  l_float32 angle)
428 {
429 PTA *ptas, *ptad;
430 BOXA *boxad;
431 
432  PROCNAME("boxaRotate");
433 
434  if (!boxas)
435  return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
436 
437  ptas = boxaConvertToPta(boxas, 4);
438  ptad = ptaRotate(ptas, xc, yc, angle);
439  boxad = ptaConvertToBoxa(ptad, 4);
440  ptaDestroy(&ptas);
441  ptaDestroy(&ptad);
442  return boxad;
443 }
444 
445 
446 /*-------------------------------------------------------------*
447  * General affine coordinate transform *
448  *-------------------------------------------------------------*/
456 PTA *
458  l_float32 *mat)
459 {
460 l_int32 i, npts;
461 l_float32 vecs[3], vecd[3];
462 PTA *ptad;
463 
464  PROCNAME("ptaAffineTransform");
465 
466  if (!ptas)
467  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
468  if (!mat)
469  return (PTA *)ERROR_PTR("transform not defined", procName, NULL);
470 
471  vecs[2] = 1;
472  npts = ptaGetCount(ptas);
473  if ((ptad = ptaCreate(npts)) == NULL)
474  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
475  for (i = 0; i < npts; i++) {
476  ptaGetPt(ptas, i, &vecs[0], &vecs[1]);
477  l_productMatVec(mat, vecs, vecd, 3);
478  ptaAddPt(ptad, vecd[0], vecd[1]);
479  }
480 
481  return ptad;
482 }
483 
484 
492 BOXA *
494  l_float32 *mat)
495 {
496 PTA *ptas, *ptad;
497 BOXA *boxad;
498 
499  PROCNAME("boxaAffineTransform");
500 
501  if (!boxas)
502  return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
503  if (!mat)
504  return (BOXA *)ERROR_PTR("transform not defined", procName, NULL);
505 
506  ptas = boxaConvertToPta(boxas, 4);
507  ptad = ptaAffineTransform(ptas, mat);
508  boxad = ptaConvertToBoxa(ptad, 4);
509  ptaDestroy(&ptas);
510  ptaDestroy(&ptad);
511  return boxad;
512 }
513 
514 
515 /*-------------------------------------------------------------*
516  * Matrix operations *
517  *-------------------------------------------------------------*/
527 l_ok
528 l_productMatVec(l_float32 *mat,
529  l_float32 *vecs,
530  l_float32 *vecd,
531  l_int32 size)
532 {
533 l_int32 i, j;
534 
535  PROCNAME("l_productMatVec");
536 
537  if (!mat)
538  return ERROR_INT("matrix not defined", procName, 1);
539  if (!vecs)
540  return ERROR_INT("input vector not defined", procName, 1);
541  if (!vecd)
542  return ERROR_INT("result vector not defined", procName, 1);
543 
544  for (i = 0; i < size; i++) {
545  vecd[i] = 0;
546  for (j = 0; j < size; j++) {
547  vecd[i] += mat[size * i + j] * vecs[j];
548  }
549  }
550  return 0;
551 }
552 
553 
563 l_ok
564 l_productMat2(l_float32 *mat1,
565  l_float32 *mat2,
566  l_float32 *matd,
567  l_int32 size)
568 {
569 l_int32 i, j, k, index;
570 
571  PROCNAME("l_productMat2");
572 
573  if (!mat1)
574  return ERROR_INT("matrix 1 not defined", procName, 1);
575  if (!mat2)
576  return ERROR_INT("matrix 2 not defined", procName, 1);
577  if (!matd)
578  return ERROR_INT("result matrix not defined", procName, 1);
579 
580  for (i = 0; i < size; i++) {
581  for (j = 0; j < size; j++) {
582  index = size * i + j;
583  matd[index] = 0;
584  for (k = 0; k < size; k++)
585  matd[index] += mat1[size * i + k] * mat2[size * k + j];
586  }
587  }
588  return 0;
589 }
590 
591 
602 l_ok
603 l_productMat3(l_float32 *mat1,
604  l_float32 *mat2,
605  l_float32 *mat3,
606  l_float32 *matd,
607  l_int32 size)
608 {
609 l_float32 *matt;
610 
611  PROCNAME("l_productMat3");
612 
613  if (!mat1)
614  return ERROR_INT("matrix 1 not defined", procName, 1);
615  if (!mat2)
616  return ERROR_INT("matrix 2 not defined", procName, 1);
617  if (!mat3)
618  return ERROR_INT("matrix 3 not defined", procName, 1);
619  if (!matd)
620  return ERROR_INT("result matrix not defined", procName, 1);
621 
622  if ((matt = (l_float32 *)LEPT_CALLOC((size_t)size * size,
623  sizeof(l_float32))) == NULL)
624  return ERROR_INT("matt not made", procName, 1);
625  l_productMat2(mat1, mat2, matt, size);
626  l_productMat2(matt, mat3, matd, size);
627  LEPT_FREE(matt);
628  return 0;
629 }
630 
631 
643 l_ok
644 l_productMat4(l_float32 *mat1,
645  l_float32 *mat2,
646  l_float32 *mat3,
647  l_float32 *mat4,
648  l_float32 *matd,
649  l_int32 size)
650 {
651 l_float32 *matt;
652 
653  PROCNAME("l_productMat4");
654 
655  if (!mat1)
656  return ERROR_INT("matrix 1 not defined", procName, 1);
657  if (!mat2)
658  return ERROR_INT("matrix 2 not defined", procName, 1);
659  if (!mat3)
660  return ERROR_INT("matrix 3 not defined", procName, 1);
661  if (!matd)
662  return ERROR_INT("result matrix not defined", procName, 1);
663 
664  if ((matt = (l_float32 *)LEPT_CALLOC((size_t)size * size,
665  sizeof(l_float32))) == NULL)
666  return ERROR_INT("matt not made", procName, 1);
667  l_productMat3(mat1, mat2, mat3, matt, size);
668  l_productMat2(matt, mat4, matd, size);
669  LEPT_FREE(matt);
670  return 0;
671 }
BOXA * boxaScale(BOXA *boxas, l_float32 scalex, l_float32 scaley)
boxaScale()
l_float32 * createMatrix2dScale(l_float32 scalex, l_float32 scaley)
createMatrix2dScale()
PTA * ptaTranslate(PTA *ptas, l_float32 transx, l_float32 transy)
ptaTranslate()
l_ok l_productMatVec(l_float32 *mat, l_float32 *vecs, l_float32 *vecd, l_int32 size)
l_productMatVec()
PTA * boxaConvertToPta(BOXA *boxa, l_int32 ncorners)
boxaConvertToPta()
Definition: boxfunc4.c:753
PTA * ptaScale(PTA *ptas, l_float32 scalex, l_float32 scaley)
ptaScale()
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:342
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:116
BOXA * boxaTranslate(BOXA *boxas, l_float32 transx, l_float32 transy)
boxaTranslate()
BOXA * ptaConvertToBoxa(PTA *pta, l_int32 ncorners)
ptaConvertToBoxa()
Definition: boxfunc4.c:798
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:504
l_ok l_productMat3(l_float32 *mat1, l_float32 *mat2, l_float32 *mat3, l_float32 *matd, l_int32 size)
l_productMat3()
PTA * ptaRotate(PTA *ptas, l_float32 xc, l_float32 yc, l_float32 angle)
ptaRotate()
Definition: pix.h:492
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:525
l_ok l_productMat4(l_float32 *mat1, l_float32 *mat2, l_float32 *mat3, l_float32 *mat4, l_float32 *matd, l_int32 size)
l_productMat4()
l_ok l_productMat2(l_float32 *mat1, l_float32 *mat2, l_float32 *matd, l_int32 size)
l_productMat2()
BOXA * boxaRotate(BOXA *boxas, l_float32 xc, l_float32 yc, l_float32 angle)
boxaRotate()
PTA * ptaAffineTransform(PTA *ptas, l_float32 *mat)
ptaAffineTransform()
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:192
l_float32 * createMatrix2dRotate(l_float32 xc, l_float32 yc, l_float32 angle)
createMatrix2dRotate()
l_float32 * createMatrix2dTranslate(l_float32 transx, l_float32 transy)
createMatrix2dTranslate()
Definition: affinecompose.c:90
BOXA * boxaAffineTransform(BOXA *boxas, l_float32 *mat)
boxaAffineTransform()
Definition: pix.h:517