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 * binmorph3_reg.c 00018 * 00019 * This is a regression test of dwa functions. It should always 00020 * be run if changes are made to the low-level morphology code. 00021 * 00022 * Some things to note: 00023 * 00024 * (1) This compares results for these operations: 00025 * - rasterop brick (non-separable, separable) 00026 * - dwa brick (separable), as implemented in morphdwa.c 00027 * - dwa brick separable, but using lower-level non-separable 00028 * autogen'd code. 00029 * 00030 * (2) See in-line comments for ordinary closing and safe closing. 00031 * The complication is due to the fact that the results differ 00032 * for symmetric and asymmetric b.c., so we must do some 00033 * fine adjustments of the border when implementing using 00034 * the lower-level code directly. 00035 */ 00036 00037 #include "allheaders.h" 00038 00039 #define TEST_SYMMETRIC 0 /* set to 1 for symmetric b.c.; 00040 otherwise, it tests asymmetric b.c. */ 00041 00042 00043 main(int argc, 00044 char **argv) 00045 { 00046 char *selnameh, *selnamev; 00047 l_int32 ok, same, w, h, i, bordercolor, extraborder; 00048 l_int32 width[3] = {21, 1, 21}; 00049 l_int32 height[3] = {1, 7, 7}; 00050 PIX *pixs, *pixref; 00051 PIX *pixt0, *pixt1, *pixt2, *pixt3, *pixt4; 00052 SEL *sel; 00053 SELA *sela; 00054 static char mainName[] = "binmorph3_reg"; 00055 00056 if (argc != 1) 00057 exit(ERROR_INT(" Syntax: binmorph3_reg", mainName, 1)); 00058 00059 if ((pixs = pixRead("feyn.tif")) == NULL) 00060 exit(ERROR_INT("pix not made", mainName, 1)); 00061 00062 #if TEST_SYMMETRIC 00063 resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC); 00064 #endif /* TEST_SYMMETRIC */ 00065 00066 for (i = 0; i < 3; i++) { 00067 w = width[i]; 00068 h = height[i]; 00069 sel = selCreateBrick(h, w, h / 2, w / 2, SEL_HIT); 00070 selnameh = NULL; 00071 selnamev = NULL; 00072 00073 00074 /* Get the selnames for horiz and vert */ 00075 sela = selaAddBasic(NULL); 00076 if (w > 1) { 00077 if ((selnameh = selaGetBrickName(sela, w, 1)) == NULL) { 00078 selaDestroy(&sela); 00079 return ERROR_INT("dwa hor sel not defined", mainName, 1); 00080 } 00081 } 00082 if (h > 1) { 00083 if ((selnamev = selaGetBrickName(sela, 1, h)) == NULL) { 00084 selaDestroy(&sela); 00085 return ERROR_INT("dwa vert sel not defined", mainName, 1); 00086 } 00087 } 00088 fprintf(stderr, "w = %d, h = %d, selh = %s, selv = %s\n", 00089 w, h, selnameh, selnamev); 00090 ok = TRUE; 00091 selaDestroy(&sela); 00092 00093 /* ----------------- Dilation ----------------- */ 00094 fprintf(stderr, "Testing dilation\n"); 00095 pixref = pixDilate(NULL, pixs, sel); 00096 pixt1 = pixDilateBrickDwa(NULL, pixs, w, h); 00097 pixEqual(pixref, pixt1, &same); 00098 if (!same) { 00099 fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; 00100 } 00101 pixDestroy(&pixt1); 00102 00103 if (w > 1) 00104 pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnameh); 00105 else 00106 pixt1 = pixClone(pixs); 00107 if (h > 1) 00108 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_DILATE, selnamev); 00109 else 00110 pixt2 = pixClone(pixt1); 00111 pixEqual(pixref, pixt2, &same); 00112 if (!same) { 00113 fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; 00114 } 00115 pixDestroy(&pixt1); 00116 pixDestroy(&pixt2); 00117 00118 pixt1 = pixAddBorder(pixs, 32, 0); 00119 if (w > 1) 00120 pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_DILATE, selnameh); 00121 else 00122 pixt2 = pixClone(pixt1); 00123 if (h > 1) 00124 pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_DILATE, selnamev); 00125 else 00126 pixt3 = pixClone(pixt2); 00127 pixt4 = pixRemoveBorder(pixt3, 32); 00128 pixEqual(pixref, pixt4, &same); 00129 if (!same) { 00130 fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; 00131 } 00132 pixDestroy(&pixref); 00133 pixDestroy(&pixt1); 00134 pixDestroy(&pixt2); 00135 pixDestroy(&pixt3); 00136 pixDestroy(&pixt4); 00137 00138 /* ----------------- Erosion ----------------- */ 00139 fprintf(stderr, "Testing erosion\n"); 00140 pixref = pixErode(NULL, pixs, sel); 00141 pixt1 = pixErodeBrickDwa(NULL, pixs, w, h); 00142 pixEqual(pixref, pixt1, &same); 00143 if (!same) { 00144 fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; 00145 } 00146 pixDestroy(&pixt1); 00147 00148 if (w > 1) 00149 pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_ERODE, selnameh); 00150 else 00151 pixt1 = pixClone(pixs); 00152 if (h > 1) 00153 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnamev); 00154 else 00155 pixt2 = pixClone(pixt1); 00156 pixEqual(pixref, pixt2, &same); 00157 if (!same) { 00158 fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; 00159 } 00160 pixDestroy(&pixt1); 00161 pixDestroy(&pixt2); 00162 00163 pixt1 = pixAddBorder(pixs, 32, 0); 00164 if (w > 1) 00165 pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_ERODE, selnameh); 00166 else 00167 pixt2 = pixClone(pixt1); 00168 if (h > 1) 00169 pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_ERODE, selnamev); 00170 else 00171 pixt3 = pixClone(pixt2); 00172 pixt4 = pixRemoveBorder(pixt3, 32); 00173 pixEqual(pixref, pixt4, &same); 00174 if (!same) { 00175 fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; 00176 } 00177 pixDestroy(&pixref); 00178 pixDestroy(&pixt1); 00179 pixDestroy(&pixt2); 00180 pixDestroy(&pixt3); 00181 pixDestroy(&pixt4); 00182 00183 /* ----------------- Opening ----------------- */ 00184 fprintf(stderr, "Testing opening\n"); 00185 pixref = pixOpen(NULL, pixs, sel); 00186 pixt1 = pixOpenBrickDwa(NULL, pixs, w, h); 00187 pixEqual(pixref, pixt1, &same); 00188 if (!same) { 00189 fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; 00190 } 00191 pixDestroy(&pixt1); 00192 00193 if (h == 1) 00194 pixt2 = pixMorphDwa_1(NULL, pixs, L_MORPH_OPEN, selnameh); 00195 else if (w == 1) 00196 pixt2 = pixMorphDwa_1(NULL, pixs, L_MORPH_OPEN, selnamev); 00197 else { 00198 pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_ERODE, selnameh); 00199 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnamev); 00200 pixMorphDwa_1(pixt1, pixt2, L_MORPH_DILATE, selnameh); 00201 pixMorphDwa_1(pixt2, pixt1, L_MORPH_DILATE, selnamev); 00202 pixDestroy(&pixt1); 00203 } 00204 pixEqual(pixref, pixt2, &same); 00205 if (!same) { 00206 fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; 00207 } 00208 pixDestroy(&pixt2); 00209 00210 pixt1 = pixAddBorder(pixs, 32, 0); 00211 if (h == 1) 00212 pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_OPEN, selnameh); 00213 else if (w == 1) 00214 pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_OPEN, selnamev); 00215 else { 00216 pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_ERODE, selnameh); 00217 pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_ERODE, selnamev); 00218 pixFMorphopGen_1(pixt2, pixt3, L_MORPH_DILATE, selnameh); 00219 pixFMorphopGen_1(pixt3, pixt2, L_MORPH_DILATE, selnamev); 00220 pixDestroy(&pixt2); 00221 } 00222 pixt4 = pixRemoveBorder(pixt3, 32); 00223 pixEqual(pixref, pixt4, &same); 00224 if (!same) { 00225 fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; 00226 } 00227 pixDestroy(&pixref); 00228 pixDestroy(&pixt1); 00229 pixDestroy(&pixt3); 00230 pixDestroy(&pixt4); 00231 00232 /* ----------------- Closing ----------------- */ 00233 fprintf(stderr, "Testing closing\n"); 00234 pixref = pixClose(NULL, pixs, sel); 00235 00236 /* Note: L_MORPH_CLOSE for h==1 or w==1 gives safe closing, 00237 * so we can't use it here. */ 00238 if (h == 1) { 00239 pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnameh); 00240 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnameh); 00241 } 00242 else if (w == 1) { 00243 pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnamev); 00244 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_ERODE, selnamev); 00245 } 00246 else { 00247 pixt1 = pixMorphDwa_1(NULL, pixs, L_MORPH_DILATE, selnameh); 00248 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_DILATE, selnamev); 00249 pixMorphDwa_1(pixt1, pixt2, L_MORPH_ERODE, selnameh); 00250 pixMorphDwa_1(pixt2, pixt1, L_MORPH_ERODE, selnamev); 00251 } 00252 pixDestroy(&pixt1); 00253 pixEqual(pixref, pixt2, &same); 00254 if (!same) { 00255 fprintf(stderr, "pixref != pixt2 !\n"); ok = FALSE; 00256 } 00257 pixDestroy(&pixt2); 00258 00259 /* Note: by adding only 32 pixels of border, we get 00260 * the normal closing operation, even when calling 00261 * with L_MORPH_CLOSE, because it requires 32 pixels 00262 * of border to be safe. */ 00263 pixt1 = pixAddBorder(pixs, 32, 0); 00264 if (h == 1) 00265 pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnameh); 00266 else if (w == 1) 00267 pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnamev); 00268 else { 00269 pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_DILATE, selnameh); 00270 pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_DILATE, selnamev); 00271 pixFMorphopGen_1(pixt2, pixt3, L_MORPH_ERODE, selnameh); 00272 pixFMorphopGen_1(pixt3, pixt2, L_MORPH_ERODE, selnamev); 00273 pixDestroy(&pixt2); 00274 } 00275 pixt4 = pixRemoveBorder(pixt3, 32); 00276 pixEqual(pixref, pixt4, &same); 00277 if (!same) { 00278 fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; 00279 } 00280 pixDestroy(&pixref); 00281 pixDestroy(&pixt1); 00282 pixDestroy(&pixt3); 00283 pixDestroy(&pixt4); 00284 00285 /* ------------- Safe Closing ----------------- */ 00286 fprintf(stderr, "Testing safe closing\n"); 00287 pixref = pixCloseSafe(NULL, pixs, sel); 00288 pixt0 = pixCloseSafeBrick(NULL, pixs, w, h); 00289 pixEqual(pixref, pixt0, &same); 00290 if (!same) { 00291 fprintf(stderr, "pixref != pixt0 !\n"); ok = FALSE; 00292 } 00293 pixDestroy(&pixt0); 00294 00295 pixt1 = pixCloseBrickDwa(NULL, pixs, w, h); 00296 pixEqual(pixref, pixt1, &same); 00297 if (!same) { 00298 fprintf(stderr, "pixref != pixt1 !\n"); ok = FALSE; 00299 } 00300 pixDestroy(&pixt1); 00301 00302 bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1); 00303 if (bordercolor == 0) /* asymmetric b.c. */ 00304 extraborder = 32; 00305 else /* symmetric b.c. */ 00306 extraborder = 0; 00307 00308 /* Note: for safe closing we need 64 border pixels. 00309 * However, when we implement a separable Sel 00310 * with pixMorphDwa_*(), we must do dilation and 00311 * erosion explicitly, and these functions only 00312 * add/remove a 32-pixel border. Thus, for that 00313 * case we must add an additional 32-pixel border 00314 * before doing the operations. That is the reason 00315 * why the implementation in morphdwa.c adds the 00316 * 64 bit border and then uses the lower-level 00317 * pixFMorphopGen_*() functions. */ 00318 if (h == 1) 00319 pixt3 = pixMorphDwa_1(NULL, pixs, L_MORPH_CLOSE, selnameh); 00320 else if (w == 1) 00321 pixt3 = pixMorphDwa_1(NULL, pixs, L_MORPH_CLOSE, selnamev); 00322 else { 00323 pixt0 = pixAddBorder(pixs, extraborder, 0); 00324 pixt1 = pixMorphDwa_1(NULL, pixt0, L_MORPH_DILATE, selnameh); 00325 pixt2 = pixMorphDwa_1(NULL, pixt1, L_MORPH_DILATE, selnamev); 00326 pixMorphDwa_1(pixt1, pixt2, L_MORPH_ERODE, selnameh); 00327 pixMorphDwa_1(pixt2, pixt1, L_MORPH_ERODE, selnamev); 00328 pixt3 = pixRemoveBorder(pixt2, extraborder); 00329 pixDestroy(&pixt0); 00330 pixDestroy(&pixt1); 00331 pixDestroy(&pixt2); 00332 } 00333 pixEqual(pixref, pixt3, &same); 00334 if (!same) { 00335 fprintf(stderr, "pixref != pixt3 !\n"); ok = FALSE; 00336 } 00337 pixDestroy(&pixt3); 00338 00339 pixt1 = pixAddBorder(pixs, 32 + extraborder, 0); 00340 if (h == 1) 00341 pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnameh); 00342 else if (w == 1) 00343 pixt3 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_CLOSE, selnamev); 00344 else { 00345 pixt2 = pixFMorphopGen_1(NULL, pixt1, L_MORPH_DILATE, selnameh); 00346 pixt3 = pixFMorphopGen_1(NULL, pixt2, L_MORPH_DILATE, selnamev); 00347 pixFMorphopGen_1(pixt2, pixt3, L_MORPH_ERODE, selnameh); 00348 pixFMorphopGen_1(pixt3, pixt2, L_MORPH_ERODE, selnamev); 00349 pixDestroy(&pixt2); 00350 } 00351 pixt4 = pixRemoveBorder(pixt3, 32 + extraborder); 00352 pixEqual(pixref, pixt4, &same); 00353 if (!same) { 00354 fprintf(stderr, "pixref != pixt4 !\n"); ok = FALSE; 00355 } 00356 pixDestroy(&pixref); 00357 pixDestroy(&pixt1); 00358 pixDestroy(&pixt3); 00359 pixDestroy(&pixt4); 00360 00361 if (ok) 00362 fprintf(stderr, "All morph tests OK!\n"); 00363 selDestroy(&sel); 00364 lept_free(selnameh); 00365 lept_free(selnamev); 00366 00367 } 00368 00369 pixDestroy(&pixs); 00370 return 0; 00371 } 00372