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