Leptonica  1.82.0
Image processing and image analysis suite
correlscore.c
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 
27 /*
28  * correlscore.c
29  *
30  * These are functions for computing correlation between
31  * pairs of 1 bpp images.
32  *
33  * Optimized 2 pix correlators (for jbig2 clustering)
34  * l_int32 pixCorrelationScore()
35  * l_int32 pixCorrelationScoreThresholded()
36  *
37  * Simple 2 pix correlators
38  * l_int32 pixCorrelationScoreSimple()
39  * l_int32 pixCorrelationScoreShifted()
40  *
41  * There are other, more application-oriented functions, that
42  * compute the correlation between two binary images, taking into
43  * account small translational shifts, between two binary images.
44  * These are:
45  * compare.c: pixBestCorrelation()
46  * Uses coarse-to-fine translations of full image
47  * recogident.c: pixCorrelationBestShift()
48  * Uses small shifts between c.c. centroids.
49  */
50 
51 #ifdef HAVE_CONFIG_H
52 #include <config_auto.h>
53 #endif /* HAVE_CONFIG_H */
54 
55 #include <math.h>
56 #include "allheaders.h"
57 
58 /* -------------------------------------------------------------------- *
59  * Optimized 2 pix correlators (for jbig2 clustering) *
60  * -------------------------------------------------------------------- */
127 l_ok
128 pixCorrelationScore(PIX *pix1,
129  PIX *pix2,
130  l_int32 area1,
131  l_int32 area2,
132  l_float32 delx, /* x(1) - x(3) */
133  l_float32 dely, /* y(1) - y(3) */
134  l_int32 maxdiffw,
135  l_int32 maxdiffh,
136  l_int32 *tab,
137  l_float32 *pscore)
138 {
139 l_int32 wi, hi, wt, ht, delw, delh, idelx, idely, count;
140 l_int32 wpl1, wpl2, lorow, hirow, locol, hicol;
141 l_int32 x, y, pix1lskip, pix2lskip, rowwords1, rowwords2;
142 l_uint32 word1, word2, andw;
143 l_uint32 *row1, *row2;
144 
145  PROCNAME("pixCorrelationScore");
146 
147  if (!pscore)
148  return ERROR_INT("&score not defined", procName, 1);
149  *pscore = 0.0;
150  if (!pix1 || pixGetDepth(pix1) != 1)
151  return ERROR_INT("pix1 undefined or not 1 bpp", procName, 1);
152  if (!pix2 || pixGetDepth(pix2) != 1)
153  return ERROR_INT("pix2 undefined or not 1 bpp", procName, 1);
154  if (!tab)
155  return ERROR_INT("tab not defined", procName, 1);
156  if (area1 <= 0 || area2 <= 0)
157  return ERROR_INT("areas must be > 0", procName, 1);
158 
159  /* Eliminate based on size difference */
160  pixGetDimensions(pix1, &wi, &hi, NULL);
161  pixGetDimensions(pix2, &wt, &ht, NULL);
162  delw = L_ABS(wi - wt);
163  if (delw > maxdiffw)
164  return 0;
165  delh = L_ABS(hi - ht);
166  if (delh > maxdiffh)
167  return 0;
168 
169  /* Round difference to nearest integer */
170  if (delx >= 0)
171  idelx = (l_int32)(delx + 0.5);
172  else
173  idelx = (l_int32)(delx - 0.5);
174  if (dely >= 0)
175  idely = (l_int32)(dely + 0.5);
176  else
177  idely = (l_int32)(dely - 0.5);
178 
179  count = 0;
180  wpl1 = pixGetWpl(pix1);
181  wpl2 = pixGetWpl(pix2);
182  rowwords2 = wpl2;
183 
184  /* What rows of pix1 need to be considered? Only those underlying the
185  * shifted pix2. */
186  lorow = L_MAX(idely, 0);
187  hirow = L_MIN(ht + idely, hi);
188 
189  /* Get the pointer to the first row of each image that will be
190  * considered. */
191  row1 = pixGetData(pix1) + wpl1 * lorow;
192  row2 = pixGetData(pix2) + wpl2 * (lorow - idely);
193 
194  /* Similarly, figure out which columns of pix1 will be considered. */
195  locol = L_MAX(idelx, 0);
196  hicol = L_MIN(wt + idelx, wi);
197 
198  if (idelx >= 32) {
199  /* pix2 is shifted far enough to the right that pix1's first
200  * word(s) won't contribute to the count. Increment its
201  * pointer to point to the first word that will contribute,
202  * and adjust other values accordingly. */
203  pix1lskip = idelx >> 5; /* # of words to skip on left */
204  row1 += pix1lskip;
205  locol -= pix1lskip << 5;
206  hicol -= pix1lskip << 5;
207  idelx &= 31;
208  } else if (idelx <= -32) {
209  /* pix2 is shifted far enough to the left that its first word(s)
210  * won't contribute to the count. Increment its pointer
211  * to point to the first word that will contribute,
212  * and adjust other values accordingly. */
213  pix2lskip = -((idelx + 31) >> 5); /* # of words to skip on left */
214  row2 += pix2lskip;
215  rowwords2 -= pix2lskip;
216  idelx += pix2lskip << 5;
217  }
218 
219  if ((locol >= hicol) || (lorow >= hirow)) { /* there is no overlap */
220  count = 0;
221  } else {
222  /* How many words of each row of pix1 need to be considered? */
223  rowwords1 = (hicol + 31) >> 5;
224 
225  if (idelx == 0) {
226  /* There's no lateral offset; simple case. */
227  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
228  for (x = 0; x < rowwords1; x++) {
229  andw = row1[x] & row2[x];
230  count += tab[andw & 0xff] +
231  tab[(andw >> 8) & 0xff] +
232  tab[(andw >> 16) & 0xff] +
233  tab[andw >> 24];
234  }
235  }
236  } else if (idelx > 0) {
237  /* pix2 is shifted to the right. word 0 of pix1 is touched by
238  * word 0 of pix2; word 1 of pix1 is touched by word 0 and word
239  * 1 of pix2, and so on up to the last word of pix1 (word N),
240  * which is touched by words N-1 and N of pix1... if there is a
241  * word N. Handle the two cases (pix2 has N-1 words and pix2
242  * has at least N words) separately.
243  *
244  * Note: we know that pix2 has at least N-1 words (i.e.,
245  * rowwords2 >= rowwords1 - 1) by the following logic.
246  * We can pretend that idelx <= 31 because the >= 32 logic
247  * above adjusted everything appropriately. Then
248  * hicol <= wt + idelx <= wt + 31, so
249  * hicol + 31 <= wt + 62
250  * rowwords1 = (hicol + 31) >> 5 <= (wt + 62) >> 5
251  * rowwords2 == (wt + 31) >> 5, so
252  * rowwords1 <= rowwords2 + 1 */
253  if (rowwords2 < rowwords1) {
254  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
255  /* Do the first iteration so the loop can be
256  * branch-free. */
257  word1 = row1[0];
258  word2 = row2[0] >> idelx;
259  andw = word1 & word2;
260  count += tab[andw & 0xff] +
261  tab[(andw >> 8) & 0xff] +
262  tab[(andw >> 16) & 0xff] +
263  tab[andw >> 24];
264 
265  for (x = 1; x < rowwords2; x++) {
266  word1 = row1[x];
267  word2 = (row2[x] >> idelx) |
268  (row2[x - 1] << (32 - idelx));
269  andw = word1 & word2;
270  count += tab[andw & 0xff] +
271  tab[(andw >> 8) & 0xff] +
272  tab[(andw >> 16) & 0xff] +
273  tab[andw >> 24];
274  }
275 
276  /* Now the last iteration - we know that this is safe
277  * (i.e. rowwords1 >= 2) because rowwords1 > rowwords2
278  * > 0 (if it was 0, we'd have taken the "count = 0"
279  * fast-path out of here). */
280  word1 = row1[x];
281  word2 = row2[x - 1] << (32 - idelx);
282  andw = word1 & word2;
283  count += tab[andw & 0xff] +
284  tab[(andw >> 8) & 0xff] +
285  tab[(andw >> 16) & 0xff] +
286  tab[andw >> 24];
287  }
288  } else {
289  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
290  /* Do the first iteration so the loop can be
291  * branch-free. This section is the same as above
292  * except for the different limit on the loop, since
293  * the last iteration is the same as all the other
294  * iterations (beyond the first). */
295  word1 = row1[0];
296  word2 = row2[0] >> idelx;
297  andw = word1 & word2;
298  count += tab[andw & 0xff] +
299  tab[(andw >> 8) & 0xff] +
300  tab[(andw >> 16) & 0xff] +
301  tab[andw >> 24];
302 
303  for (x = 1; x < rowwords1; x++) {
304  word1 = row1[x];
305  word2 = (row2[x] >> idelx) |
306  (row2[x - 1] << (32 - idelx));
307  andw = word1 & word2;
308  count += tab[andw & 0xff] +
309  tab[(andw >> 8) & 0xff] +
310  tab[(andw >> 16) & 0xff] +
311  tab[andw >> 24];
312  }
313  }
314  }
315  } else {
316  /* pix2 is shifted to the left. word 0 of pix1 is touched by
317  * word 0 and word 1 of pix2, and so on up to the last word of
318  * pix1 (word N), which is touched by words N and N+1 of
319  * pix2... if there is a word N+1. Handle the two cases (pix2
320  * has N words and pix2 has at least N+1 words) separately. */
321  if (rowwords1 < rowwords2) {
322  /* pix2 has at least N+1 words, so every iteration through
323  * the loop can be the same. */
324  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
325  for (x = 0; x < rowwords1; x++) {
326  word1 = row1[x];
327  word2 = row2[x] << -idelx;
328  word2 |= row2[x + 1] >> (32 + idelx);
329  andw = word1 & word2;
330  count += tab[andw & 0xff] +
331  tab[(andw >> 8) & 0xff] +
332  tab[(andw >> 16) & 0xff] +
333  tab[andw >> 24];
334  }
335  }
336  } else {
337  /* pix2 has only N words, so the last iteration is broken
338  * out. */
339  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
340  for (x = 0; x < rowwords1 - 1; x++) {
341  word1 = row1[x];
342  word2 = row2[x] << -idelx;
343  word2 |= row2[x + 1] >> (32 + idelx);
344  andw = word1 & word2;
345  count += tab[andw & 0xff] +
346  tab[(andw >> 8) & 0xff] +
347  tab[(andw >> 16) & 0xff] +
348  tab[andw >> 24];
349  }
350 
351  word1 = row1[x];
352  word2 = row2[x] << -idelx;
353  andw = word1 & word2;
354  count += tab[andw & 0xff] +
355  tab[(andw >> 8) & 0xff] +
356  tab[(andw >> 16) & 0xff] +
357  tab[andw >> 24];
358  }
359  }
360  }
361  }
362 
363  *pscore = (l_float32)count * (l_float32)count /
364  ((l_float32)area1 * (l_float32)area2);
365 /* lept_stderr("score = %5.3f, count = %d, area1 = %d, area2 = %d\n",
366  *pscore, count, area1, area2); */
367  return 0;
368 }
369 
370 
425 l_int32
426 pixCorrelationScoreThresholded(PIX *pix1,
427  PIX *pix2,
428  l_int32 area1,
429  l_int32 area2,
430  l_float32 delx, /* x(1) - x(3) */
431  l_float32 dely, /* y(1) - y(3) */
432  l_int32 maxdiffw,
433  l_int32 maxdiffh,
434  l_int32 *tab,
435  l_int32 *downcount,
436  l_float32 score_threshold)
437 {
438 l_int32 wi, hi, wt, ht, delw, delh, idelx, idely, count;
439 l_int32 wpl1, wpl2, lorow, hirow, locol, hicol, untouchable;
440 l_int32 x, y, pix1lskip, pix2lskip, rowwords1, rowwords2;
441 l_uint32 word1, word2, andw;
442 l_uint32 *row1, *row2;
443 l_float32 score;
444 l_int32 threshold;
445 
446  PROCNAME("pixCorrelationScoreThresholded");
447 
448  if (!pix1 || pixGetDepth(pix1) != 1)
449  return ERROR_INT("pix1 undefined or not 1 bpp", procName, 0);
450  if (!pix2 || pixGetDepth(pix2) != 1)
451  return ERROR_INT("pix2 undefined or not 1 bpp", procName, 0);
452  if (!tab)
453  return ERROR_INT("tab not defined", procName, 0);
454  if (area1 <= 0 || area2 <= 0)
455  return ERROR_INT("areas must be > 0", procName, 0);
456 
457  /* Eliminate based on size difference */
458  pixGetDimensions(pix1, &wi, &hi, NULL);
459  pixGetDimensions(pix2, &wt, &ht, NULL);
460  delw = L_ABS(wi - wt);
461  if (delw > maxdiffw)
462  return FALSE;
463  delh = L_ABS(hi - ht);
464  if (delh > maxdiffh)
465  return FALSE;
466 
467  /* Round difference to nearest integer */
468  if (delx >= 0)
469  idelx = (l_int32)(delx + 0.5);
470  else
471  idelx = (l_int32)(delx - 0.5);
472  if (dely >= 0)
473  idely = (l_int32)(dely + 0.5);
474  else
475  idely = (l_int32)(dely - 0.5);
476 
477  /* Compute the correlation count that is needed so that
478  * count * count / (area1 * area2) >= score_threshold */
479  threshold = (l_int32)ceil(sqrt((l_float64)score_threshold * area1 * area2));
480 
481  count = 0;
482  wpl1 = pixGetWpl(pix1);
483  wpl2 = pixGetWpl(pix2);
484  rowwords2 = wpl2;
485 
486  /* What rows of pix1 need to be considered? Only those underlying the
487  * shifted pix2. */
488  lorow = L_MAX(idely, 0);
489  hirow = L_MIN(ht + idely, hi);
490 
491  /* Get the pointer to the first row of each image that will be
492  * considered. */
493  row1 = pixGetData(pix1) + wpl1 * lorow;
494  row2 = pixGetData(pix2) + wpl2 * (lorow - idely);
495  if (hirow <= hi) {
496  /* Some rows of pix1 will never contribute to count */
497  untouchable = downcount[hirow - 1];
498  }
499 
500  /* Similarly, figure out which columns of pix1 will be considered. */
501  locol = L_MAX(idelx, 0);
502  hicol = L_MIN(wt + idelx, wi);
503 
504  if (idelx >= 32) {
505  /* pix2 is shifted far enough to the right that pix1's first
506  * word(s) won't contribute to the count. Increment its
507  * pointer to point to the first word that will contribute,
508  * and adjust other values accordingly. */
509  pix1lskip = idelx >> 5; /* # of words to skip on left */
510  row1 += pix1lskip;
511  locol -= pix1lskip << 5;
512  hicol -= pix1lskip << 5;
513  idelx &= 31;
514  } else if (idelx <= -32) {
515  /* pix2 is shifted far enough to the left that its first word(s)
516  * won't contribute to the count. Increment its pointer
517  * to point to the first word that will contribute,
518  * and adjust other values accordingly. */
519  pix2lskip = -((idelx + 31) >> 5); /* # of words to skip on left */
520  row2 += pix2lskip;
521  rowwords2 -= pix2lskip;
522  idelx += pix2lskip << 5;
523  }
524 
525  if ((locol >= hicol) || (lorow >= hirow)) { /* there is no overlap */
526  count = 0;
527  } else {
528  /* How many words of each row of pix1 need to be considered? */
529  rowwords1 = (hicol + 31) >> 5;
530 
531  if (idelx == 0) {
532  /* There's no lateral offset; simple case. */
533  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
534  for (x = 0; x < rowwords1; x++) {
535  andw = row1[x] & row2[x];
536  count += tab[andw & 0xff] +
537  tab[(andw >> 8) & 0xff] +
538  tab[(andw >> 16) & 0xff] +
539  tab[andw >> 24];
540  }
541 
542  /* If the count is over the threshold, no need to
543  * calculate any further. Likewise, return early if the
544  * count plus the maximum count attainable from further
545  * rows is below the threshold. */
546  if (count >= threshold) return TRUE;
547  if (count + downcount[y] - untouchable < threshold) {
548  return FALSE;
549  }
550  }
551  } else if (idelx > 0) {
552  /* pix2 is shifted to the right. word 0 of pix1 is touched by
553  * word 0 of pix2; word 1 of pix1 is touched by word 0 and word
554  * 1 of pix2, and so on up to the last word of pix1 (word N),
555  * which is touched by words N-1 and N of pix1... if there is a
556  * word N. Handle the two cases (pix2 has N-1 words and pix2
557  * has at least N words) separately.
558  *
559  * Note: we know that pix2 has at least N-1 words (i.e.,
560  * rowwords2 >= rowwords1 - 1) by the following logic.
561  * We can pretend that idelx <= 31 because the >= 32 logic
562  * above adjusted everything appropriately. Then
563  * hicol <= wt + idelx <= wt + 31, so
564  * hicol + 31 <= wt + 62
565  * rowwords1 = (hicol + 31) >> 5 <= (wt + 62) >> 5
566  * rowwords2 == (wt + 31) >> 5, so
567  * rowwords1 <= rowwords2 + 1 */
568  if (rowwords2 < rowwords1) {
569  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
570  /* Do the first iteration so the loop can be
571  * branch-free. */
572  word1 = row1[0];
573  word2 = row2[0] >> idelx;
574  andw = word1 & word2;
575  count += tab[andw & 0xff] +
576  tab[(andw >> 8) & 0xff] +
577  tab[(andw >> 16) & 0xff] +
578  tab[andw >> 24];
579 
580  for (x = 1; x < rowwords2; x++) {
581  word1 = row1[x];
582  word2 = (row2[x] >> idelx) |
583  (row2[x - 1] << (32 - idelx));
584  andw = word1 & word2;
585  count += tab[andw & 0xff] +
586  tab[(andw >> 8) & 0xff] +
587  tab[(andw >> 16) & 0xff] +
588  tab[andw >> 24];
589  }
590 
591  /* Now the last iteration - we know that this is safe
592  * (i.e. rowwords1 >= 2) because rowwords1 > rowwords2
593  * > 0 (if it was 0, we'd have taken the "count = 0"
594  * fast-path out of here). */
595  word1 = row1[x];
596  word2 = row2[x - 1] << (32 - idelx);
597  andw = word1 & word2;
598  count += tab[andw & 0xff] +
599  tab[(andw >> 8) & 0xff] +
600  tab[(andw >> 16) & 0xff] +
601  tab[andw >> 24];
602 
603  if (count >= threshold) return TRUE;
604  if (count + downcount[y] - untouchable < threshold) {
605  return FALSE;
606  }
607  }
608  } else {
609  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
610  /* Do the first iteration so the loop can be
611  * branch-free. This section is the same as above
612  * except for the different limit on the loop, since
613  * the last iteration is the same as all the other
614  * iterations (beyond the first). */
615  word1 = row1[0];
616  word2 = row2[0] >> idelx;
617  andw = word1 & word2;
618  count += tab[andw & 0xff] +
619  tab[(andw >> 8) & 0xff] +
620  tab[(andw >> 16) & 0xff] +
621  tab[andw >> 24];
622 
623  for (x = 1; x < rowwords1; x++) {
624  word1 = row1[x];
625  word2 = (row2[x] >> idelx) |
626  (row2[x - 1] << (32 - idelx));
627  andw = word1 & word2;
628  count += tab[andw & 0xff] +
629  tab[(andw >> 8) & 0xff] +
630  tab[(andw >> 16) & 0xff] +
631  tab[andw >> 24];
632  }
633 
634  if (count >= threshold) return TRUE;
635  if (count + downcount[y] - untouchable < threshold) {
636  return FALSE;
637  }
638  }
639  }
640  } else {
641  /* pix2 is shifted to the left. word 0 of pix1 is touched by
642  * word 0 and word 1 of pix2, and so on up to the last word of
643  * pix1 (word N), which is touched by words N and N+1 of
644  * pix2... if there is a word N+1. Handle the two cases (pix2
645  * has N words and pix2 has at least N+1 words) separately. */
646  if (rowwords1 < rowwords2) {
647  /* pix2 has at least N+1 words, so every iteration through
648  * the loop can be the same. */
649  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
650  for (x = 0; x < rowwords1; x++) {
651  word1 = row1[x];
652  word2 = row2[x] << -idelx;
653  word2 |= row2[x + 1] >> (32 + idelx);
654  andw = word1 & word2;
655  count += tab[andw & 0xff] +
656  tab[(andw >> 8) & 0xff] +
657  tab[(andw >> 16) & 0xff] +
658  tab[andw >> 24];
659  }
660 
661  if (count >= threshold) return TRUE;
662  if (count + downcount[y] - untouchable < threshold) {
663  return FALSE;
664  }
665  }
666  } else {
667  /* pix2 has only N words, so the last iteration is broken
668  * out. */
669  for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
670  for (x = 0; x < rowwords1 - 1; x++) {
671  word1 = row1[x];
672  word2 = row2[x] << -idelx;
673  word2 |= row2[x + 1] >> (32 + idelx);
674  andw = word1 & word2;
675  count += tab[andw & 0xff] +
676  tab[(andw >> 8) & 0xff] +
677  tab[(andw >> 16) & 0xff] +
678  tab[andw >> 24];
679  }
680 
681  word1 = row1[x];
682  word2 = row2[x] << -idelx;
683  andw = word1 & word2;
684  count += tab[andw & 0xff] +
685  tab[(andw >> 8) & 0xff] +
686  tab[(andw >> 16) & 0xff] +
687  tab[andw >> 24];
688 
689  if (count >= threshold) return TRUE;
690  if (count + downcount[y] - untouchable < threshold) {
691  return FALSE;
692  }
693  }
694  }
695  }
696  }
697 
698  score = (l_float32)count * (l_float32)count /
699  ((l_float32)area1 * (l_float32)area2);
700  if (score >= score_threshold) {
701  lept_stderr(
702  "count %d < threshold %d but score %g >= score_threshold %g\n",
703  count, threshold, score, score_threshold);
704  }
705  return FALSE;
706 }
707 
708 
709 /* -------------------------------------------------------------------- *
710  * Simple 2 pix correlators (for jbig2 clustering) *
711  * -------------------------------------------------------------------- */
735 l_ok
736 pixCorrelationScoreSimple(PIX *pix1,
737  PIX *pix2,
738  l_int32 area1,
739  l_int32 area2,
740  l_float32 delx, /* x(1) - x(3) */
741  l_float32 dely, /* y(1) - y(3) */
742  l_int32 maxdiffw,
743  l_int32 maxdiffh,
744  l_int32 *tab,
745  l_float32 *pscore)
746 {
747 l_int32 wi, hi, wt, ht, delw, delh, idelx, idely, count;
748 PIX *pixt;
749 
750  PROCNAME("pixCorrelationScoreSimple");
751 
752  if (!pscore)
753  return ERROR_INT("&score not defined", procName, 1);
754  *pscore = 0.0;
755  if (!pix1 || pixGetDepth(pix1) != 1)
756  return ERROR_INT("pix1 undefined or not 1 bpp", procName, 1);
757  if (!pix2 || pixGetDepth(pix2) != 1)
758  return ERROR_INT("pix2 undefined or not 1 bpp", procName, 1);
759  if (!tab)
760  return ERROR_INT("tab not defined", procName, 1);
761  if (!area1 || !area2)
762  return ERROR_INT("areas must be > 0", procName, 1);
763 
764  /* Eliminate based on size difference */
765  pixGetDimensions(pix1, &wi, &hi, NULL);
766  pixGetDimensions(pix2, &wt, &ht, NULL);
767  delw = L_ABS(wi - wt);
768  if (delw > maxdiffw)
769  return 0;
770  delh = L_ABS(hi - ht);
771  if (delh > maxdiffh)
772  return 0;
773 
774  /* Round difference to nearest integer */
775  if (delx >= 0)
776  idelx = (l_int32)(delx + 0.5);
777  else
778  idelx = (l_int32)(delx - 0.5);
779  if (dely >= 0)
780  idely = (l_int32)(dely + 0.5);
781  else
782  idely = (l_int32)(dely - 0.5);
783 
784  /* pixt = pixAnd(NULL, pix1, pix2), including shift.
785  * To insure that pixels are ON only within the
786  * intersection of pix1 and the shifted pix2:
787  * (1) Start with pixt cleared and equal in size to pix1.
788  * (2) Blit the shifted pix2 onto pixt. Then all ON pixels
789  * are within the intersection of pix1 and the shifted pix2.
790  * (3) AND pix1 with pixt. */
791  pixt = pixCreateTemplate(pix1);
792  pixRasterop(pixt, idelx, idely, wt, ht, PIX_SRC, pix2, 0, 0);
793  pixRasterop(pixt, 0, 0, wi, hi, PIX_SRC & PIX_DST, pix1, 0, 0);
794  pixCountPixels(pixt, &count, tab);
795  pixDestroy(&pixt);
796 
797  *pscore = (l_float32)count * (l_float32)count /
798  ((l_float32)area1 * (l_float32)area2);
799 /* lept_stderr("score = %5.3f, count = %d, area1 = %d, area2 = %d\n",
800  *pscore, count, area1, area2); */
801  return 0;
802 }
803 
804 
838 l_ok
839 pixCorrelationScoreShifted(PIX *pix1,
840  PIX *pix2,
841  l_int32 area1,
842  l_int32 area2,
843  l_int32 delx,
844  l_int32 dely,
845  l_int32 *tab,
846  l_float32 *pscore)
847 {
848 l_int32 w1, h1, w2, h2, count;
849 PIX *pixt;
850 
851  PROCNAME("pixCorrelationScoreShifted");
852 
853  if (!pscore)
854  return ERROR_INT("&score not defined", procName, 1);
855  *pscore = 0.0;
856  if (!pix1 || pixGetDepth(pix1) != 1)
857  return ERROR_INT("pix1 undefined or not 1 bpp", procName, 1);
858  if (!pix2 || pixGetDepth(pix2) != 1)
859  return ERROR_INT("pix2 undefined or not 1 bpp", procName, 1);
860  if (!tab)
861  return ERROR_INT("tab not defined", procName, 1);
862  if (!area1 || !area2)
863  return ERROR_INT("areas must be > 0", procName, 1);
864 
865  pixGetDimensions(pix1, &w1, &h1, NULL);
866  pixGetDimensions(pix2, &w2, &h2, NULL);
867 
868  /* To insure that pixels are ON only within the
869  * intersection of pix1 and the shifted pix2:
870  * (1) Start with pixt cleared and equal in size to pix1.
871  * (2) Blit the shifted pix2 onto pixt. Then all ON pixels
872  * are within the intersection of pix1 and the shifted pix2.
873  * (3) AND pix1 with pixt. */
874  pixt = pixCreateTemplate(pix1);
875  pixRasterop(pixt, delx, dely, w2, h2, PIX_SRC, pix2, 0, 0);
876  pixRasterop(pixt, 0, 0, w1, h1, PIX_SRC & PIX_DST, pix1, 0, 0);
877  pixCountPixels(pixt, &count, tab);
878  pixDestroy(&pixt);
879 
880  *pscore = (l_float32)count * (l_float32)count /
881  ((l_float32)area1 * (l_float32)area2);
882  return 0;
883 }
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1937
#define PIX_DST
Definition: pix.h:331
#define PIX_SRC
Definition: pix.h:330
l_ok pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
Definition: rop.c:204
Definition: pix.h:139
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306