Leptonica 1.68
C Image Processing Library
|
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 }