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 * compfilter_reg.c 00018 * 00019 * Tests filters that select components based on size, etc. 00020 */ 00021 00022 #include <stdio.h> 00023 #include <stdlib.h> 00024 #include "allheaders.h" 00025 00026 static void count_pieces(PIX *pix, l_int32 nexp); 00027 static void count_pieces2(BOXA *boxa, l_int32 nexp); 00028 static l_int32 count_ones(NUMA *na, l_int32 nexp, l_int32 index, 00029 const char *name); 00030 00031 static const l_float32 edges[13] = {0.0, 0.2, 0.3, 0.35, 0.4, 0.45, 0.5, 00032 0.55, 0.6, 0.7, 0.8, 0.9, 1.0}; 00033 00034 #if 1 /* for feyn.tif */ 00035 static const l_int32 band[12] = {1, 11, 48, 264, 574, 704, 908, 786, 466, 00036 157, 156, 230}; 00037 static const l_int32 total[12] = {1, 12, 60, 324, 898, 1602, 2510, 3296, 00038 3762, 3919, 4075, 4305}; 00039 #else /* for rabi.png */ 00040 static const l_int32 band[12] = {24, 295, 490, 817, 1768, 962, 8171, 00041 63, 81, 51, 137, 8619}; 00042 static const l_int32 total[12] = {24, 319, 809, 1626, 3394, 4356, 12527, 00043 12590, 12671, 12722, 12859, 21478}; 00044 #endif 00045 00046 00047 main(int argc, 00048 char **argv) 00049 { 00050 l_int32 w, h, n, i, sum, sumi, empty; 00051 BOX *box1, *box2, *box3, *box4; 00052 BOXA *boxa, *boxat; 00053 NUMA *na1, *na2, *na3, *na4, *na5; 00054 NUMA *na2i, *na3i, *na4i, *nat, *naw, *nah; 00055 PIX *pixs, *pixc, *pixt, *pixt2, *pixd, *pixcount; 00056 PIXA *pixas, *pixad, *pixac; 00057 static char mainName[] = "compfilter_reg"; 00058 00059 pixDisplayWrite(NULL, -1); 00060 00061 /* Draw 4 filled boxes of different sizes */ 00062 pixs = pixCreate(200, 200, 1); 00063 box1 = boxCreate(10, 10, 20, 30); 00064 box2 = boxCreate(50, 10, 40, 20); 00065 box3 = boxCreate(110, 10, 35, 5); 00066 box4 = boxCreate(160, 10, 5, 15); 00067 boxa = boxaCreate(4); 00068 boxaAddBox(boxa, box1, L_INSERT); 00069 boxaAddBox(boxa, box2, L_INSERT); 00070 boxaAddBox(boxa, box3, L_INSERT); 00071 boxaAddBox(boxa, box4, L_INSERT); 00072 pixRenderBox(pixs, box1, 1, L_SET_PIXELS); 00073 pixRenderBox(pixs, box2, 1, L_SET_PIXELS); 00074 pixRenderBox(pixs, box3, 1, L_SET_PIXELS); 00075 pixRenderBox(pixs, box4, 1, L_SET_PIXELS); 00076 pixt = pixFillClosedBorders(pixs, 4); 00077 pixDisplayWrite(pixt, 1); 00078 pixt2 = pixCreateTemplate(pixs); 00079 pixRenderHashBox(pixt2, box1, 6, 4, L_POS_SLOPE_LINE, 1, L_SET_PIXELS); 00080 pixRenderHashBox(pixt2, box2, 7, 2, L_POS_SLOPE_LINE, 1, L_SET_PIXELS); 00081 pixRenderHashBox(pixt2, box3, 4, 2, L_VERTICAL_LINE, 1, L_SET_PIXELS); 00082 pixRenderHashBox(pixt2, box4, 3, 1, L_HORIZONTAL_LINE, 1, L_SET_PIXELS); 00083 pixDisplayWrite(pixt2, 1); 00084 00085 /* Exercise the parameters */ 00086 pixd = pixSelectBySize(pixt, 0, 22, 8, L_SELECT_HEIGHT, 00087 L_SELECT_IF_GT, NULL); 00088 count_pieces(pixd, 1); 00089 pixd = pixSelectBySize(pixt, 0, 30, 8, L_SELECT_HEIGHT, 00090 L_SELECT_IF_LT, NULL); 00091 count_pieces(pixd, 3); 00092 pixd = pixSelectBySize(pixt, 0, 5, 8, L_SELECT_HEIGHT, 00093 L_SELECT_IF_GT, NULL); 00094 count_pieces(pixd, 3); 00095 pixd = pixSelectBySize(pixt, 0, 6, 8, L_SELECT_HEIGHT, 00096 L_SELECT_IF_LT, NULL); 00097 count_pieces(pixd, 1); 00098 pixd = pixSelectBySize(pixt, 20, 0, 8, L_SELECT_WIDTH, 00099 L_SELECT_IF_GT, NULL); 00100 count_pieces(pixd, 2); 00101 pixd = pixSelectBySize(pixt, 31, 0, 8, L_SELECT_WIDTH, 00102 L_SELECT_IF_LT, NULL); 00103 count_pieces(pixd, 2); 00104 pixd = pixSelectBySize(pixt, 21, 10, 8, L_SELECT_IF_EITHER, 00105 L_SELECT_IF_LT, NULL); 00106 count_pieces(pixd, 3); 00107 pixd = pixSelectBySize(pixt, 20, 30, 8, L_SELECT_IF_EITHER, 00108 L_SELECT_IF_GT, NULL); 00109 count_pieces(pixd, 2); 00110 pixd = pixSelectBySize(pixt, 22, 32, 8, L_SELECT_IF_BOTH, 00111 L_SELECT_IF_LT, NULL); 00112 count_pieces(pixd, 2); 00113 pixd = pixSelectBySize(pixt, 6, 32, 8, L_SELECT_IF_BOTH, 00114 L_SELECT_IF_LT, NULL); 00115 count_pieces(pixd, 1); 00116 pixd = pixSelectBySize(pixt, 5, 25, 8, L_SELECT_IF_BOTH, 00117 L_SELECT_IF_GT, NULL); 00118 count_pieces(pixd, 1); 00119 pixd = pixSelectBySize(pixt, 25, 5, 8, L_SELECT_IF_BOTH, 00120 L_SELECT_IF_GT, NULL); 00121 count_pieces(pixd, 1); 00122 00123 pixd = pixSelectByAreaPerimRatio(pixt, 1.7, 8, L_SELECT_IF_LT, NULL); 00124 count_pieces(pixd, 2); 00125 pixd = pixSelectByAreaPerimRatio(pixt, 5.5, 8, L_SELECT_IF_LT, NULL); 00126 count_pieces(pixd, 3); 00127 pixd = pixSelectByAreaPerimRatio(pixt, 1.5, 8, L_SELECT_IF_GTE, NULL); 00128 count_pieces(pixd, 2); 00129 pixd = pixSelectByAreaPerimRatio(pixt, 13.0/12.0, 8, L_SELECT_IF_GT, NULL); 00130 count_pieces(pixd, 3); 00131 00132 pixd = pixSelectByAreaFraction(pixt2, 0.3, 8, L_SELECT_IF_LT, NULL); 00133 count_pieces(pixd, 0); 00134 pixd = pixSelectByAreaFraction(pixt2, 0.9, 8, L_SELECT_IF_LT, NULL); 00135 count_pieces(pixd, 4); 00136 pixd = pixSelectByAreaFraction(pixt2, 0.5, 8, L_SELECT_IF_GTE, NULL); 00137 count_pieces(pixd, 3); 00138 pixd = pixSelectByAreaFraction(pixt2, 0.7, 8, L_SELECT_IF_GT, NULL); 00139 count_pieces(pixd, 2); 00140 00141 boxat = boxaSelectBySize(boxa, 21, 10, L_SELECT_IF_EITHER, 00142 L_SELECT_IF_LT, NULL); 00143 count_pieces2(boxat, 3); 00144 boxat = boxaSelectBySize(boxa, 22, 32, L_SELECT_IF_BOTH, 00145 L_SELECT_IF_LT, NULL); 00146 count_pieces2(boxat, 2); 00147 00148 boxaDestroy(&boxa); 00149 pixDestroy(&pixt); 00150 pixDestroy(&pixt2); 00151 pixDestroy(&pixs); 00152 00153 /* Here's the most general method for selecting components. 00154 * We do it for area fraction, but any combination of 00155 * size, area/perimeter ratio and area fraction can be used. */ 00156 pixs = pixRead("feyn.tif"); 00157 /* pixs = pixRead("rabi.png"); */ 00158 pixc = pixCopy(NULL, pixs); /* subtract bands from this */ 00159 pixt = pixCreateTemplate(pixs); /* add bands to this */ 00160 pixGetDimensions(pixs, &w, &h, NULL); 00161 boxa = pixConnComp(pixs, &pixas, 8); 00162 n = boxaGetCount(boxa); 00163 fprintf(stderr, "total: %d\n", n); 00164 na1 = pixaFindAreaFraction(pixas); 00165 nat = numaCreate(0); 00166 numaSetCount(nat, n); /* initialize to all 0 */ 00167 sum = sumi = 0; 00168 pixac = pixaCreate(0); 00169 for (i = 0; i < 12; i++) { 00170 /* Compute within the intervals using an intersection. */ 00171 na2 = numaMakeThresholdIndicator(na1, edges[i], L_SELECT_IF_GTE); 00172 if (i != 11) 00173 na3 = numaMakeThresholdIndicator(na1, edges[i + 1], L_SELECT_IF_LT); 00174 else 00175 na3 = numaMakeThresholdIndicator(na1, edges[i + 1], 00176 L_SELECT_IF_LTE); 00177 na4 = numaLogicalOp(NULL, na2, na3, L_INTERSECTION); 00178 sum += count_ones(na4, 0, 0, NULL); 00179 00180 /* Compute outside the intervals using a union, and invert */ 00181 na2i = numaMakeThresholdIndicator(na1, edges[i], L_SELECT_IF_LT); 00182 if (i != 11) 00183 na3i = numaMakeThresholdIndicator(na1, edges[i + 1], 00184 L_SELECT_IF_GTE); 00185 else 00186 na3i = numaMakeThresholdIndicator(na1, edges[i + 1], 00187 L_SELECT_IF_GT); 00188 na4i = numaLogicalOp(NULL, na3i, na2i, L_UNION); 00189 numaInvert(na4i, na4i); 00190 sumi += count_ones(na4i, 0, 0, NULL); 00191 00192 /* Compare the two methods */ 00193 if (sum == sumi) 00194 fprintf(stderr, "\nCorrect: sum = sumi = %d\n", sum); 00195 else 00196 fprintf(stderr, "\nWRONG: sum = %d, sumi = %d\n", sum, sumi); 00197 00198 /* Reconstruct the image, band by band. */ 00199 numaLogicalOp(nat, nat, na4, L_UNION); 00200 pixad = pixaSelectWithIndicator(pixas, na4, NULL); 00201 pixd = pixaDisplay(pixad, w, h); 00202 pixOr(pixt, pixt, pixd); /* add them in */ 00203 pixcount = pixCopy(NULL, pixt); /* destroyed by count_pieces */ 00204 count_ones(na4, band[i], i, "band"); 00205 count_pieces(pixd, band[i]); 00206 count_ones(nat, total[i], i, "total"); 00207 count_pieces(pixcount, total[i]); 00208 pixaDestroy(&pixad); 00209 00210 /* Remove band successively from full image */ 00211 pixRemoveWithIndicator(pixc, pixas, na4); 00212 pixSaveTiled(pixc, pixac, 4, 1 - i % 2, 25, 8); 00213 00214 numaDestroy(&na2); 00215 numaDestroy(&na3); 00216 numaDestroy(&na4); 00217 numaDestroy(&na2i); 00218 numaDestroy(&na3i); 00219 numaDestroy(&na4i); 00220 } 00221 00222 /* Did we remove all components from pixc? */ 00223 pixZero(pixc, &empty); 00224 if (!empty) 00225 fprintf(stderr, "\nWRONG: not all pixels removed from pixc\n"); 00226 00227 pixDestroy(&pixs); 00228 pixDestroy(&pixc); 00229 pixDestroy(&pixt); 00230 boxaDestroy(&boxa); 00231 pixaDestroy(&pixas); 00232 numaDestroy(&na1); 00233 numaDestroy(&nat); 00234 00235 /* One last extraction. Get all components that have either 00236 * a height of at least 50 or a width of between 30 and 35, 00237 * and also do not have a large area/perimeter ratio. */ 00238 pixs = pixRead("feyn.tif"); 00239 boxa = pixConnComp(pixs, &pixas, 8); 00240 n = boxaGetCount(boxa); 00241 pixaFindDimensions(pixas, &naw, &nah); 00242 na1 = pixaFindAreaPerimRatio(pixas); 00243 na2 = numaMakeThresholdIndicator(nah, 50, L_SELECT_IF_GTE); 00244 na3 = numaMakeThresholdIndicator(naw, 30, L_SELECT_IF_GTE); 00245 na4 = numaMakeThresholdIndicator(naw, 35, L_SELECT_IF_LTE); 00246 na5 = numaMakeThresholdIndicator(na1, 2.5, L_SELECT_IF_LTE); 00247 numaLogicalOp(na3, na3, na4, L_INTERSECTION); 00248 numaLogicalOp(na2, na2, na3, L_UNION); 00249 numaLogicalOp(na2, na2, na5, L_INTERSECTION); 00250 numaInvert(na2, na2); /* get components to be removed */ 00251 pixRemoveWithIndicator(pixs, pixas, na2); 00252 pixSaveTiled(pixs, pixac, 4, 1, 25, 8); 00253 pixDestroy(&pixs); 00254 boxaDestroy(&boxa); 00255 pixaDestroy(&pixas); 00256 numaDestroy(&naw); 00257 numaDestroy(&nah); 00258 numaDestroy(&na1); 00259 numaDestroy(&na2); 00260 numaDestroy(&na3); 00261 numaDestroy(&na4); 00262 numaDestroy(&na5); 00263 00264 00265 pixDisplayMultiple("/tmp/junk_write_display*"); 00266 00267 pixd = pixaDisplay(pixac, 0, 0); 00268 pixDisplay(pixd, 100, 100); 00269 pixWrite("/tmp/junkcomp.jpg", pixd, IFF_JFIF_JPEG); 00270 pixDestroy(&pixd); 00271 pixaDestroy(&pixac); 00272 00273 return 0; 00274 } 00275 00276 00277 void count_pieces(PIX *pix, l_int32 nexp) 00278 { 00279 l_int32 n; 00280 BOXA *boxa; 00281 00282 pixDisplayWrite(pix, 1); 00283 boxa = pixConnComp(pix, NULL, 8); 00284 n = boxaGetCount(boxa); 00285 if (n == nexp) 00286 fprintf(stderr, "Correct: Num. comps: %d\n", n); 00287 else 00288 fprintf(stderr, "WRONG!: Num. comps: %d\n", n); 00289 boxaDestroy(&boxa); 00290 pixDestroy(&pix); 00291 } 00292 00293 void count_pieces2(BOXA *boxa, l_int32 nexp) 00294 { 00295 l_int32 n; 00296 00297 n = boxaGetCount(boxa); 00298 if (n == nexp) 00299 fprintf(stderr, "Correct: Num. boxes: %d\n", n); 00300 else 00301 fprintf(stderr, "WRONG!: Num. boxes: %d\n", n); 00302 boxaDestroy(&boxa); 00303 } 00304 00305 l_int32 count_ones(NUMA *na, l_int32 nexp, l_int32 index, const char *name) 00306 { 00307 l_int32 i, n, val, sum; 00308 00309 n = numaGetCount(na); 00310 sum = 0; 00311 for (i = 0; i < n; i++) { 00312 numaGetIValue(na, i, &val); 00313 if (val == 1) sum++; 00314 } 00315 if (!name) return sum; 00316 if (nexp == sum) 00317 fprintf(stderr, "Correct: %s[%d]: num. ones: %d\n", name, index, sum); 00318 else 00319 fprintf(stderr, "WRONG!: %s[%d]: num. ones: %d\n", name, index, sum); 00320 return 0; 00321 } 00322 00323