Leptonica 1.68
C Image Processing Library

correlscore.c

Go to the documentation of this file.
00001 /*====================================================================*
00002  -  Copyright (C) 2001 Leptonica.  All rights reserved.
00003  -  This software is distributed in the hope that it will be
00004  -  useful, but with NO WARRANTY OF ANY KIND.
00005  -  No author or distributor accepts responsibility to anyone for the
00006  -  consequences of using this software, or for whether it serves any
00007  -  particular purpose or works at all, unless he or she says so in
00008  -  writing.  Everyone is granted permission to copy, modify and
00009  -  redistribute this source code, for commercial or non-commercial
00010  -  purposes, with the following restrictions: (1) the origin of this
00011  -  source code must not be misrepresented; (2) modified versions must
00012  -  be plainly marked as such; and (3) this notice may not be removed
00013  -  or altered from any source or modified source distribution.
00014  *====================================================================*/
00015 
00016 /*
00017  * correlscore.c
00018  *
00019  *     These are functions for computing correlation between
00020  *     pairs of 1 bpp images.
00021  *
00022  *         l_float32   pixCorrelationScore()
00023  *         l_int32     pixCorrelationScoreThresholded()
00024  *         l_float32   pixCorrelationScoreSimple()
00025  */
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <math.h>
00030 #include "allheaders.h"
00031 
00032 
00033 /*!
00034  *  pixCorrelationScore()
00035  *
00036  *      Input:  pix1   (test pix, 1 bpp)
00037  *              pix2   (exemplar pix, 1 bpp)
00038  *              area1  (number of on pixels in pix1)
00039  *              area2  (number of on pixels in pix2)
00040  *              delx   (x comp of centroid difference)
00041  *              dely   (y comp of centroid difference)
00042  *              maxdiffw (max width difference of pix1 and pix2)
00043  *              maxdiffh (max height difference of pix1 and pix2)
00044  *              tab    (sum tab for byte)
00045  *      Return: correlation score 
00046  *
00047  *  Note: we check first that the two pix are roughly the same size.
00048  *  For jbclass (jbig2) applications at roughly 300 ppi, maxdiffw and
00049  *  maxdiffh should be at least 2.
00050  *
00051  *  Only if they meet that criterion do we compare the bitmaps. 
00052  *  The centroid difference is used to align the two images to the
00053  *  nearest integer for the correlation.
00054  *
00055  *  The correlation score is the ratio of the square of the number of
00056  *  pixels in the AND of the two bitmaps to the product of the number
00057  *  of ON pixels in each.  Denote the number of ON pixels in pix1
00058  *  by |1|, the number in pix2 by |2|, and the number in the AND
00059  *  of pix1 and pix2 by |1 & 2|.  The correlation score is then
00060  *  (|1 & 2|)**2 / (|1|*|2|).
00061  *
00062  *  This score is compared with an input threshold, which can
00063  *  be modified depending on the weight of the template.
00064  *  The modified threshold is
00065  *     thresh + (1.0 - thresh) * weight * R
00066  *  where 
00067  *     weight is a fixed input factor between 0.0 and 1.0
00068  *     R = |2| / area(2)
00069  *  and area(2) is the total number of pixels in 2 (i.e., width x height).
00070  *
00071  *  To understand why a weight factor is useful, consider what happens
00072  *  with thick, sans-serif characters that look similar and have a value
00073  *  of R near 1.  Different characters can have a high correlation value,
00074  *  and the classifier will make incorrect substitutions.  The weight
00075  *  factor raises the threshold for these characters.
00076  *
00077  *  Yet another approach to reduce such substitutions is to run the classifier
00078  *  in a non-greedy way, matching to the template with the highest
00079  *  score, not the first template with a score satisfying the matching
00080  *  constraint.  However, this is not particularly effective.
00081  *
00082  *  The implementation here gives the same result as in
00083  *  pixCorrelationScoreSimple(), where a temporary Pix is made to hold
00084  *  the AND and implementation uses rasterop:
00085  *      pixt = pixCreateTemplate(pix1);
00086  *      pixRasterop(pixt, idelx, idely, wt, ht, PIX_SRC, pix2, 0, 0);
00087  *      pixRasterop(pixt, 0, 0, wi, hi, PIX_SRC & PIX_DST, pix1, 0, 0);
00088  *      pixCountPixels(pixt, &count, tab);
00089  *      pixDestroy(&pixt);
00090  *  However, here it is done in a streaming fashion, counting as it goes,
00091  *  and touching memory exactly once, giving a 3-4x speedup over the
00092  *  simple implementation.  This very fast correlation matcher was
00093  *  contributed by William Rucklidge.
00094  */
00095 l_float32
00096 pixCorrelationScore(PIX       *pix1,
00097                     PIX       *pix2,
00098                     l_int32    area1,
00099                     l_int32    area2,
00100                     l_float32  delx,   /* x(1) - x(3) */
00101                     l_float32  dely,   /* y(1) - y(3) */
00102                     l_int32    maxdiffw,
00103                     l_int32    maxdiffh,
00104                     l_int32   *tab)
00105 {
00106 l_int32    wi, hi, wt, ht, delw, delh, idelx, idely, count;
00107 l_int32    wpl1, wpl2, lorow, hirow, locol, hicol;
00108 l_int32    x, y, pix1lskip, pix2lskip, rowwords1, rowwords2;
00109 l_uint32   word1, word2, andw;
00110 l_uint32  *row1, *row2;
00111 l_float32  score;
00112 
00113     PROCNAME("pixCorrelationScore");
00114 
00115     if (!pix1 || pixGetDepth(pix1) != 1)
00116         return (l_float32)ERROR_FLOAT("pix1 not 1 bpp", procName, 0.0);
00117     if (!pix2 || pixGetDepth(pix2) != 1)
00118         return (l_float32)ERROR_FLOAT("pix2 not 1 bpp", procName, 0.0);
00119     if (!tab)
00120         return (l_float32)ERROR_FLOAT("tab not defined", procName, 0.0);
00121     if (area1 <= 0 || area2 <= 0)
00122         return (l_float32)ERROR_FLOAT("areas must be > 0", procName, 0.0);
00123 
00124         /* Eliminate based on size difference */
00125     pixGetDimensions(pix1, &wi, &hi, NULL);
00126     pixGetDimensions(pix2, &wt, &ht, NULL);
00127     delw = L_ABS(wi - wt);
00128     if (delw > maxdiffw)
00129         return 0.0;
00130     delh = L_ABS(hi - ht);
00131     if (delh > maxdiffh)
00132         return 0.0;
00133 
00134         /* Round difference to nearest integer */
00135     if (delx >= 0)
00136         idelx = (l_int32)(delx + 0.5);
00137     else
00138         idelx = (l_int32)(delx - 0.5);
00139     if (dely >= 0)
00140         idely = (l_int32)(dely + 0.5);
00141     else
00142         idely = (l_int32)(dely - 0.5);
00143 
00144     count = 0;
00145     wpl1 = pixGetWpl(pix1);
00146     wpl2 = pixGetWpl(pix2);
00147     rowwords2 = wpl2;
00148 
00149         /* What rows of pix1 need to be considered?  Only those underlying the
00150          * shifted pix2. */
00151     lorow = L_MAX(idely, 0);
00152     hirow = L_MIN(ht + idely, hi);
00153 
00154         /* Get the pointer to the first row of each image that will be
00155          * considered. */
00156     row1 = pixGetData(pix1) + wpl1 * lorow;
00157     row2 = pixGetData(pix2) + wpl2 * (lorow - idely);
00158 
00159         /* Similarly, figure out which columns of pix1 will be considered. */
00160     locol = L_MAX(idelx, 0);
00161     hicol = L_MIN(wt + idelx, wi);
00162 
00163     if (idelx >= 32) {
00164             /* pix2 is shifted far enough to the right that pix1's first
00165              * word(s) won't contribute to the count.  Increment its
00166              * pointer to point to the first word that will contribute,
00167              * and adjust other values accordingly. */
00168         pix1lskip = idelx >> 5;  /* # of words to skip on left */
00169         row1 += pix1lskip;
00170         locol -= pix1lskip << 5;
00171         hicol -= pix1lskip << 5;
00172         idelx &= 31;
00173     } else if (idelx <= -32) {
00174             /* pix2 is shifted far enough to the left that its first word(s)
00175              * won't contribute to the count.  Increment its pointer
00176              * to point to the first word that will contribute,
00177              * and adjust other values accordingly. */
00178         pix2lskip = -((idelx + 31) >> 5);  /* # of words to skip on left */
00179         row2 += pix2lskip;
00180         rowwords2 -= pix2lskip;
00181         idelx += pix2lskip << 5;
00182     }
00183 
00184     if ((locol >= hicol) || (lorow >= hirow)) {  /* there is no overlap */
00185         count = 0;
00186     } else {
00187             /* How many words of each row of pix1 need to be considered? */
00188         rowwords1 = (hicol + 31) >> 5;
00189 
00190         if (idelx == 0) {
00191                 /* There's no lateral offset; simple case. */
00192             for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00193                 for (x = 0; x < rowwords1; x++) {
00194                     andw = row1[x] & row2[x];
00195                     count += tab[andw & 0xff] +
00196                         tab[(andw >> 8) & 0xff] +
00197                         tab[(andw >> 16) & 0xff] +
00198                         tab[andw >> 24];
00199                 }
00200             }
00201         } else if (idelx > 0) {
00202                 /* pix2 is shifted to the right.  word 0 of pix1 is touched by
00203                  * word 0 of pix2; word 1 of pix1 is touched by word 0 and word
00204                  * 1 of pix2, and so on up to the last word of pix1 (word N),
00205                  * which is touched by words N-1 and N of pix1... if there is a
00206                  * word N.  Handle the two cases (pix2 has N-1 words and pix2
00207                  * has at least N words) separately.
00208                  *
00209                  * Note: we know that pix2 has at least N-1 words (i.e.,
00210                  * rowwords2 >= rowwords1 - 1) by the following logic.
00211                  * We can pretend that idelx <= 31 because the >= 32 logic
00212                  * above adjusted everything appropriately.  Then
00213                  * hicol <= wt + idelx <= wt + 31, so
00214                  * hicol + 31 <= wt + 62
00215                  * rowwords1 = (hicol + 31) >> 5 <= (wt + 62) >> 5
00216                  * rowwords2 == (wt + 31) >> 5, so
00217                  * rowwords1 <= rowwords2 + 1 */
00218             if (rowwords2 < rowwords1) {
00219                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00220                         /* Do the first iteration so the loop can be
00221                          * branch-free. */
00222                     word1 = row1[0];
00223                     word2 = row2[0] >> idelx;
00224                     andw = word1 & word2;
00225                     count += tab[andw & 0xff] +
00226                         tab[(andw >> 8) & 0xff] +
00227                         tab[(andw >> 16) & 0xff] +
00228                         tab[andw >> 24];
00229 
00230                     for (x = 1; x < rowwords2; x++) {
00231                         word1 = row1[x];
00232                         word2 = (row2[x] >> idelx) |
00233                             (row2[x - 1] << (32 - idelx));
00234                         andw = word1 & word2;
00235                         count += tab[andw & 0xff] +
00236                             tab[(andw >> 8) & 0xff] +
00237                             tab[(andw >> 16) & 0xff] +
00238                             tab[andw >> 24];
00239                     }
00240 
00241                         /* Now the last iteration - we know that this is safe
00242                          * (i.e.  rowwords1 >= 2) because rowwords1 > rowwords2
00243                          * > 0 (if it was 0, we'd have taken the "count = 0"
00244                          * fast-path out of here). */
00245                     word1 = row1[x];
00246                     word2 = row2[x - 1] << (32 - idelx);
00247                     andw = word1 & word2;
00248                     count += tab[andw & 0xff] +
00249                         tab[(andw >> 8) & 0xff] +
00250                         tab[(andw >> 16) & 0xff] +
00251                         tab[andw >> 24];
00252                 }
00253             } else {
00254                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00255                         /* Do the first iteration so the loop can be
00256                          * branch-free.  This section is the same as above
00257                          * except for the different limit on the loop, since
00258                          * the last iteration is the same as all the other
00259                          * iterations (beyond the first). */
00260                     word1 = row1[0];
00261                     word2 = row2[0] >> idelx;
00262                     andw = word1 & word2;
00263                     count += tab[andw & 0xff] +
00264                         tab[(andw >> 8) & 0xff] +
00265                         tab[(andw >> 16) & 0xff] +
00266                         tab[andw >> 24];
00267 
00268                     for (x = 1; x < rowwords1; x++) {
00269                         word1 = row1[x];
00270                         word2 = (row2[x] >> idelx) |
00271                             (row2[x - 1] << (32 - idelx));
00272                         andw = word1 & word2;
00273                         count += tab[andw & 0xff] +
00274                             tab[(andw >> 8) & 0xff] +
00275                             tab[(andw >> 16) & 0xff] +
00276                             tab[andw >> 24];
00277                     }
00278                 }
00279             }
00280         } else {
00281                 /* pix2 is shifted to the left.  word 0 of pix1 is touched by
00282                  * word 0 and word 1 of pix2, and so on up to the last word of
00283                  * pix1 (word N), which is touched by words N and N+1 of
00284                  * pix2... if there is a word N+1.  Handle the two cases (pix2
00285                  * has N words and pix2 has at least N+1 words) separately. */
00286             if (rowwords1 < rowwords2) {
00287                     /* pix2 has at least N+1 words, so every iteration through
00288                      * the loop can be the same. */
00289                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00290                     for (x = 0; x < rowwords1; x++) {
00291                         word1 = row1[x];
00292                         word2 = row2[x] << -idelx;
00293                         word2 |= row2[x + 1] >> (32 + idelx);
00294                         andw = word1 & word2;
00295                         count += tab[andw & 0xff] +
00296                             tab[(andw >> 8) & 0xff] +
00297                             tab[(andw >> 16) & 0xff] +
00298                             tab[andw >> 24];
00299                     }
00300                 }
00301             } else {
00302                     /* pix2 has only N words, so the last iteration is broken
00303                      * out. */
00304                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00305                     for (x = 0; x < rowwords1 - 1; x++) {
00306                         word1 = row1[x];
00307                         word2 = row2[x] << -idelx;
00308                         word2 |= row2[x + 1] >> (32 + idelx);
00309                         andw = word1 & word2;
00310                         count += tab[andw & 0xff] +
00311                             tab[(andw >> 8) & 0xff] +
00312                             tab[(andw >> 16) & 0xff] +
00313                             tab[andw >> 24];
00314                     }
00315 
00316                     word1 = row1[x];
00317                     word2 = row2[x] << -idelx;
00318                     andw = word1 & word2;
00319                     count += tab[andw & 0xff] +
00320                         tab[(andw >> 8) & 0xff] +
00321                         tab[(andw >> 16) & 0xff] +
00322                         tab[andw >> 24];
00323                 }
00324             }
00325         }
00326     }
00327 
00328     score = (l_float32)(count * count) / (l_float32)(area1 * area2);
00329 /*    fprintf(stderr, "score = %7.3f, count = %d, area1 = %d, area2 = %d\n",
00330              score, count, area1, area2); */
00331     return score;
00332 }
00333 
00334 
00335 /*!
00336  *  pixCorrelationScoreThresholded()
00337  *
00338  *      Input:  pix1   (test pix, 1 bpp)
00339  *              pix2   (exemplar pix, 1 bpp)
00340  *              area1  (number of on pixels in pix1)
00341  *              area2  (number of on pixels in pix2)
00342  *              delx   (x comp of centroid difference)
00343  *              dely   (y comp of centroid difference)
00344  *              maxdiffw (max width difference of pix1 and pix2)
00345  *              maxdiffh (max height difference of pix1 and pix2)
00346  *              tab    (sum tab for byte)
00347  *              downcount (count of 1 pixels below each row of pix1)
00348  *              score_threshold
00349  *      Return: whether the correlation score is >= score_threshold
00350  *
00351  *
00352  *  Note: we check first that the two pix are roughly the same size.
00353  *  Only if they meet that criterion do we compare the bitmaps.
00354  *  The centroid difference is used to align the two images to the
00355  *  nearest integer for the correlation.
00356  *
00357  *  The correlation score is the ratio of the square of the number of
00358  *  pixels in the AND of the two bitmaps to the product of the number
00359  *  of ON pixels in each.  Denote the number of ON pixels in pix1
00360  *  by |1|, the number in pix2 by |2|, and the number in the AND
00361  *  of pix1 and pix2 by |1 & 2|.  The correlation score is then
00362  *  (|1 & 2|)**2 / (|1|*|2|).
00363  *
00364  *  This score is compared with an input threshold, which can
00365  *  be modified depending on the weight of the template.
00366  *  The modified threshold is
00367  *     thresh + (1.0 - thresh) * weight * R
00368  *  where
00369  *     weight is a fixed input factor between 0.0 and 1.0
00370  *     R = |2| / area(2)
00371  *  and area(2) is the total number of pixels in 2 (i.e., width x height).
00372  *
00373  *  To understand why a weight factor is useful, consider what happens
00374  *  with thick, sans-serif characters that look similar and have a value
00375  *  of R near 1.  Different characters can have a high correlation value,
00376  *  and the classifier will make incorrect substitutions.  The weight
00377  *  factor raises the threshold for these characters.
00378  *
00379  *  Yet another approach to reduce such substitutions is to run the classifier
00380  *  in a non-greedy way, matching to the template with the highest
00381  *  score, not the first template with a score satisfying the matching
00382  *  constraint.  However, this is not particularly effective.
00383  *
00384  *  This very fast correlation matcher was contributed by William Rucklidge.
00385  */
00386 l_int32
00387 pixCorrelationScoreThresholded(PIX       *pix1,
00388                                PIX       *pix2,
00389                                l_int32    area1,
00390                                l_int32    area2,
00391                                l_float32  delx,   /* x(1) - x(3) */
00392                                l_float32  dely,   /* y(1) - y(3) */
00393                                l_int32    maxdiffw,
00394                                l_int32    maxdiffh,
00395                                l_int32   *tab,
00396                                l_int32   *downcount,
00397                                l_float32  score_threshold)
00398 {
00399 l_int32    wi, hi, wt, ht, delw, delh, idelx, idely, count;
00400 l_int32    wpl1, wpl2, lorow, hirow, locol, hicol, untouchable;
00401 l_int32    x, y, pix1lskip, pix2lskip, rowwords1, rowwords2;
00402 l_uint32   word1, word2, andw;
00403 l_uint32  *row1, *row2;
00404 l_float32  score;
00405 l_int32    threshold;
00406 
00407     PROCNAME("pixCorrelationScoreThresholded");
00408 
00409     if (!pix1 || pixGetDepth(pix1) != 1)
00410         return ERROR_INT("pix1 not 1 bpp", procName, 0);
00411     if (!pix2 || pixGetDepth(pix2) != 1)
00412         return ERROR_INT("pix2 not 1 bpp", procName, 0);
00413     if (!tab)
00414         return ERROR_INT("tab not defined", procName, 0);
00415     if (area1 <= 0 || area2 <= 0)
00416         return ERROR_INT("areas must be > 0", procName, 0);
00417 
00418         /* Eliminate based on size difference */
00419     pixGetDimensions(pix1, &wi, &hi, NULL);
00420     pixGetDimensions(pix2, &wt, &ht, NULL);
00421     delw = L_ABS(wi - wt);
00422     if (delw > maxdiffw)
00423         return FALSE;
00424     delh = L_ABS(hi - ht);
00425     if (delh > maxdiffh)
00426         return FALSE;
00427 
00428         /* Round difference to nearest integer */
00429     if (delx >= 0)
00430         idelx = (l_int32)(delx + 0.5);
00431     else
00432         idelx = (l_int32)(delx - 0.5);
00433     if (dely >= 0)
00434         idely = (l_int32)(dely + 0.5);
00435     else
00436         idely = (l_int32)(dely - 0.5);
00437 
00438         /* Compute the correlation count that is needed so that
00439          * count * count / (area1 * area2) >= score_threshold */
00440     threshold = (l_int32)ceil(sqrt(score_threshold * area1 * area2));
00441 
00442     count = 0;
00443     wpl1 = pixGetWpl(pix1);
00444     wpl2 = pixGetWpl(pix2);
00445     rowwords2 = wpl2;
00446 
00447         /* What rows of pix1 need to be considered?  Only those underlying the
00448          * shifted pix2. */
00449     lorow = L_MAX(idely, 0);
00450     hirow = L_MIN(ht + idely, hi);
00451 
00452         /* Get the pointer to the first row of each image that will be
00453          * considered. */
00454     row1 = pixGetData(pix1) + wpl1 * lorow;
00455     row2 = pixGetData(pix2) + wpl2 * (lorow - idely);
00456     if (hirow <= hi) {
00457             /* Some rows of pix1 will never contribute to count */
00458         untouchable = downcount[hirow - 1];
00459     }
00460 
00461         /* Similarly, figure out which columns of pix1 will be considered. */
00462     locol = L_MAX(idelx, 0);
00463     hicol = L_MIN(wt + idelx, wi);
00464 
00465     if (idelx >= 32) {
00466             /* pix2 is shifted far enough to the right that pix1's first
00467              * word(s) won't contribute to the count.  Increment its
00468              * pointer to point to the first word that will contribute,
00469              * and adjust other values accordingly. */
00470         pix1lskip = idelx >> 5;  /* # of words to skip on left */
00471         row1 += pix1lskip;
00472         locol -= pix1lskip << 5;
00473         hicol -= pix1lskip << 5;
00474         idelx &= 31;
00475     } else if (idelx <= -32) {
00476             /* pix2 is shifted far enough to the left that its first word(s)
00477              * won't contribute to the count.  Increment its pointer
00478              * to point to the first word that will contribute,
00479              * and adjust other values accordingly. */
00480         pix2lskip = -((idelx + 31) >> 5);  /* # of words to skip on left */
00481         row2 += pix2lskip;
00482         rowwords2 -= pix2lskip;
00483         idelx += pix2lskip << 5;
00484     }
00485 
00486     if ((locol >= hicol) || (lorow >= hirow)) {  /* there is no overlap */
00487         count = 0;
00488     } else {
00489             /* How many words of each row of pix1 need to be considered? */
00490         rowwords1 = (hicol + 31) >> 5;
00491 
00492         if (idelx == 0) {
00493                 /* There's no lateral offset; simple case. */
00494             for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00495                 for (x = 0; x < rowwords1; x++) {
00496                     andw = row1[x] & row2[x];
00497                     count += tab[andw & 0xff] +
00498                         tab[(andw >> 8) & 0xff] +
00499                         tab[(andw >> 16) & 0xff] +
00500                         tab[andw >> 24];
00501                 }
00502 
00503                     /* If the count is over the threshold, no need to
00504                      * calculate any futher.  Likewise, return early if the
00505                      * count plus the maximum count attainable from further
00506                      * rows is below the threshold. */
00507                 if (count >= threshold) return TRUE;
00508                 if (count + downcount[y] - untouchable < threshold) {
00509                     return FALSE;
00510                 }
00511             }
00512         } else if (idelx > 0) {
00513                 /* pix2 is shifted to the right.  word 0 of pix1 is touched by
00514                  * word 0 of pix2; word 1 of pix1 is touched by word 0 and word
00515                  * 1 of pix2, and so on up to the last word of pix1 (word N),
00516                  * which is touched by words N-1 and N of pix1... if there is a
00517                  * word N.  Handle the two cases (pix2 has N-1 words and pix2
00518                  * has at least N words) separately.
00519                  *
00520                  * Note: we know that pix2 has at least N-1 words (i.e.,
00521                  * rowwords2 >= rowwords1 - 1) by the following logic.
00522                  * We can pretend that idelx <= 31 because the >= 32 logic
00523                  * above adjusted everything appropriately.  Then
00524                  * hicol <= wt + idelx <= wt + 31, so
00525                  * hicol + 31 <= wt + 62
00526                  * rowwords1 = (hicol + 31) >> 5 <= (wt + 62) >> 5
00527                  * rowwords2 == (wt + 31) >> 5, so
00528                  * rowwords1 <= rowwords2 + 1 */
00529             if (rowwords2 < rowwords1) {
00530                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00531                         /* Do the first iteration so the loop can be
00532                          * branch-free. */
00533                     word1 = row1[0];
00534                     word2 = row2[0] >> idelx;
00535                     andw = word1 & word2;
00536                     count += tab[andw & 0xff] +
00537                         tab[(andw >> 8) & 0xff] +
00538                         tab[(andw >> 16) & 0xff] +
00539                         tab[andw >> 24];
00540 
00541                     for (x = 1; x < rowwords2; x++) {
00542                         word1 = row1[x];
00543                         word2 = (row2[x] >> idelx) |
00544                             (row2[x - 1] << (32 - idelx));
00545                         andw = word1 & word2;
00546                         count += tab[andw & 0xff] +
00547                             tab[(andw >> 8) & 0xff] +
00548                             tab[(andw >> 16) & 0xff] +
00549                             tab[andw >> 24];
00550                     }
00551 
00552                         /* Now the last iteration - we know that this is safe
00553                          * (i.e.  rowwords1 >= 2) because rowwords1 > rowwords2
00554                          * > 0 (if it was 0, we'd have taken the "count = 0"
00555                          * fast-path out of here). */
00556                     word1 = row1[x];
00557                     word2 = row2[x - 1] << (32 - idelx);
00558                     andw = word1 & word2;
00559                     count += tab[andw & 0xff] +
00560                         tab[(andw >> 8) & 0xff] +
00561                         tab[(andw >> 16) & 0xff] +
00562                         tab[andw >> 24];
00563 
00564                     if (count >= threshold) return TRUE;
00565                     if (count + downcount[y] - untouchable < threshold) {
00566                         return FALSE;
00567                     }
00568                 }
00569             } else {
00570                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00571                         /* Do the first iteration so the loop can be
00572                          * branch-free.  This section is the same as above
00573                          * except for the different limit on the loop, since
00574                          * the last iteration is the same as all the other
00575                          * iterations (beyond the first). */
00576                     word1 = row1[0];
00577                     word2 = row2[0] >> idelx;
00578                     andw = word1 & word2;
00579                     count += tab[andw & 0xff] +
00580                         tab[(andw >> 8) & 0xff] +
00581                         tab[(andw >> 16) & 0xff] +
00582                         tab[andw >> 24];
00583 
00584                     for (x = 1; x < rowwords1; x++) {
00585                         word1 = row1[x];
00586                         word2 = (row2[x] >> idelx) |
00587                             (row2[x - 1] << (32 - idelx));
00588                         andw = word1 & word2;
00589                         count += tab[andw & 0xff] +
00590                             tab[(andw >> 8) & 0xff] +
00591                             tab[(andw >> 16) & 0xff] +
00592                             tab[andw >> 24];
00593                     }
00594 
00595                     if (count >= threshold) return TRUE;
00596                     if (count + downcount[y] - untouchable < threshold) {
00597                         return FALSE;
00598                     }
00599                 }
00600             }
00601         } else {
00602                 /* pix2 is shifted to the left.  word 0 of pix1 is touched by
00603                  * word 0 and word 1 of pix2, and so on up to the last word of
00604                  * pix1 (word N), which is touched by words N and N+1 of
00605                  * pix2... if there is a word N+1.  Handle the two cases (pix2
00606                  * has N words and pix2 has at least N+1 words) separately. */
00607             if (rowwords1 < rowwords2) {
00608                     /* pix2 has at least N+1 words, so every iteration through
00609                      * the loop can be the same. */
00610                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00611                     for (x = 0; x < rowwords1; x++) {
00612                         word1 = row1[x];
00613                         word2 = row2[x] << -idelx;
00614                         word2 |= row2[x + 1] >> (32 + idelx);
00615                         andw = word1 & word2;
00616                         count += tab[andw & 0xff] +
00617                             tab[(andw >> 8) & 0xff] +
00618                             tab[(andw >> 16) & 0xff] +
00619                             tab[andw >> 24];
00620                     }
00621 
00622                     if (count >= threshold) return TRUE;
00623                     if (count + downcount[y] - untouchable < threshold) {
00624                         return FALSE;
00625                     }
00626                 }
00627             } else {
00628                     /* pix2 has only N words, so the last iteration is broken
00629                      * out. */
00630                 for (y = lorow; y < hirow; y++, row1 += wpl1, row2 += wpl2) {
00631                     for (x = 0; x < rowwords1 - 1; x++) {
00632                         word1 = row1[x];
00633                         word2 = row2[x] << -idelx;
00634                         word2 |= row2[x + 1] >> (32 + idelx);
00635                         andw = word1 & word2;
00636                         count += tab[andw & 0xff] +
00637                             tab[(andw >> 8) & 0xff] +
00638                             tab[(andw >> 16) & 0xff] +
00639                             tab[andw >> 24];
00640                     }
00641 
00642                     word1 = row1[x];
00643                     word2 = row2[x] << -idelx;
00644                     andw = word1 & word2;
00645                     count += tab[andw & 0xff] +
00646                         tab[(andw >> 8) & 0xff] +
00647                         tab[(andw >> 16) & 0xff] +
00648                         tab[andw >> 24];
00649 
00650                     if (count >= threshold) return TRUE;
00651                     if (count + downcount[y] - untouchable < threshold) {
00652                         return FALSE;
00653                     }
00654                 }
00655             }
00656         }
00657     }
00658 
00659     score = (l_float32)(count * count) / (l_float32)(area1 * area2);
00660     if (score >= score_threshold) {
00661         fprintf(stderr, "count %d < threshold %d but score %g >= score_threshold %g\n",
00662                 count, threshold, score, score_threshold);
00663     }
00664     return FALSE;
00665 }
00666 
00667 
00668 /*!
00669  *  pixCorrelationScoreSimple()
00670  *
00671  *      Input:  pix1   (test pix, 1 bpp)
00672  *              pix2   (exemplar pix, 1 bpp)
00673  *              area1  (number of on pixels in pix1)
00674  *              area2  (number of on pixels in pix2)
00675  *              delx   (x comp of centroid difference)
00676  *              dely   (y comp of centroid difference)
00677  *              maxdiffw (max width difference of pix1 and pix2)
00678  *              maxdiffh (max height difference of pix1 and pix2)
00679  *              tab    (sum tab for byte)
00680  *      Return: correlation score 
00681  *
00682  *  Notes:
00683  *      (1) This calculates exactly the same value as pixCorrelationScore().
00684  *          It is 2-3x slower, but much simpler to understand.
00685  */
00686 l_float32
00687 pixCorrelationScoreSimple(PIX       *pix1,
00688                           PIX       *pix2,
00689                           l_int32    area1,
00690                           l_int32    area2,
00691                           l_float32  delx,   /* x(1) - x(3) */
00692                           l_float32  dely,   /* y(1) - y(3) */
00693                           l_int32    maxdiffw,
00694                           l_int32    maxdiffh,
00695                           l_int32   *tab)
00696 {
00697 l_int32    wi, hi, wt, ht, delw, delh, idelx, idely, count;
00698 l_float32  score;
00699 PIX       *pixt;
00700 
00701     PROCNAME("pixCorrelationScoreSimple");
00702 
00703     if (!pix1 || pixGetDepth(pix1) != 1)
00704         return (l_float32)ERROR_FLOAT("pix1 not 1 bpp", procName, 0.0);
00705     if (!pix2 || pixGetDepth(pix2) != 1)
00706         return (l_float32)ERROR_FLOAT("pix2 not 1 bpp", procName, 0.0);
00707     if (!tab)
00708         return (l_float32)ERROR_FLOAT("tab not defined", procName, 0.0);
00709     if (!area1 || !area2)
00710         return (l_float32)ERROR_FLOAT("areas must be > 0", procName, 0.0);
00711 
00712         /* Eliminate based on size difference */
00713     pixGetDimensions(pix1, &wi, &hi, NULL);
00714     pixGetDimensions(pix2, &wt, &ht, NULL);
00715     delw = L_ABS(wi - wt);
00716     if (delw > maxdiffw)
00717         return 0.0;
00718     delh = L_ABS(hi - ht);
00719     if (delh > maxdiffh)
00720         return 0.0;
00721 
00722         /* Round difference to nearest integer */
00723     if (delx >= 0)
00724         idelx = (l_int32)(delx + 0.5);
00725     else
00726         idelx = (l_int32)(delx - 0.5);
00727     if (dely >= 0)
00728         idely = (l_int32)(dely + 0.5);
00729     else
00730         idely = (l_int32)(dely - 0.5);
00731 
00732         /*  pixt = pixAnd(NULL, pix1, pix2), including shift.
00733          *  To insure that pixels are ON only within the
00734          *  intersection of pix1 and the shifted pix2:
00735          *  (1) Start with pixt cleared and equal in size to pix1.
00736          *  (2) Blit the shifted pix2 onto pixt.  Then all ON pixels
00737          *      are within the intersection of pix1 and the shifted pix2.
00738          *  (3) AND pix1 with pixt. */
00739     pixt = pixCreateTemplate(pix1);
00740     pixRasterop(pixt, idelx, idely, wt, ht, PIX_SRC, pix2, 0, 0);
00741     pixRasterop(pixt, 0, 0, wi, hi, PIX_SRC & PIX_DST, pix1, 0, 0);
00742     pixCountPixels(pixt, &count, tab);
00743     pixDestroy(&pixt);
00744 
00745     score = (l_float32)(count * count) / (l_float32)(area1 * area2);
00746 /*    fprintf(stderr, "score = %7.3f, count = %d, area1 = %d, area2 = %d\n",
00747              score, count, area1, area2); */
00748     return score;
00749 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines