Leptonica 1.68
C Image Processing Library

binmorph3_reg.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  *  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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines