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 * -------------------------------------------------------------------- */
127l_ok
128pixCorrelationScore(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{
139l_int32 wi, hi, wt, ht, delw, delh, idelx, idely, count;
140l_int32 wpl1, wpl2, lorow, hirow, locol, hicol;
141l_int32 x, y, pix1lskip, pix2lskip, rowwords1, rowwords2;
142l_uint32 word1, word2, andw;
143l_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
425l_int32
426pixCorrelationScoreThresholded(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{
438l_int32 wi, hi, wt, ht, delw, delh, idelx, idely, count;
439l_int32 wpl1, wpl2, lorow, hirow, locol, hicol, untouchable;
440l_int32 x, y, pix1lskip, pix2lskip, rowwords1, rowwords2;
441l_uint32 word1, word2, andw;
442l_uint32 *row1, *row2;
443l_float32 score;
444l_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) {
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 * -------------------------------------------------------------------- */
735l_ok
736pixCorrelationScoreSimple(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{
747l_int32 wi, hi, wt, ht, delw, delh, idelx, idely, count;
748PIX *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
838l_ok
839pixCorrelationScoreShifted(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{
848l_int32 w1, h1, w2, h2, count;
849PIX *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}
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_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
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