Leptonica 1.68
C Image Processing Library

dwacomb.2.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  *      Top-level fast binary morphology with auto-generated sels
00018  *
00019  *             PIX     *pixMorphDwa_2()
00020  *             PIX     *pixFMorphopGen_2()
00021  */
00022 
00023 #include <string.h>
00024 #include "allheaders.h"
00025 
00026 PIX *pixMorphDwa_2(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
00027 PIX *pixFMorphopGen_2(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
00028 l_int32 fmorphopgen_low_2(l_uint32 *datad, l_int32 w,
00029                           l_int32 h, l_int32 wpld,
00030                           l_uint32 *datas, l_int32 wpls,
00031                           l_int32 index);
00032 
00033 static l_int32   NUM_SELS_GENERATED = 76;
00034 static char  SEL_NAMES[][80] = {
00035                              "sel_comb_4h",
00036                              "sel_comb_4v",
00037                              "sel_comb_5h",
00038                              "sel_comb_5v",
00039                              "sel_comb_6h",
00040                              "sel_comb_6v",
00041                              "sel_comb_7h",
00042                              "sel_comb_7v",
00043                              "sel_comb_8h",
00044                              "sel_comb_8v",
00045                              "sel_comb_9h",
00046                              "sel_comb_9v",
00047                              "sel_comb_10h",
00048                              "sel_comb_10v",
00049                              "sel_comb_12h",
00050                              "sel_comb_12v",
00051                              "sel_comb_14h",
00052                              "sel_comb_14v",
00053                              "sel_comb_15h",
00054                              "sel_comb_15v",
00055                              "sel_comb_16h",
00056                              "sel_comb_16v",
00057                              "sel_comb_18h",
00058                              "sel_comb_18v",
00059                              "sel_comb_20h",
00060                              "sel_comb_20v",
00061                              "sel_comb_21h",
00062                              "sel_comb_21v",
00063                              "sel_comb_22h",
00064                              "sel_comb_22v",
00065                              "sel_comb_24h",
00066                              "sel_comb_24v",
00067                              "sel_comb_25h",
00068                              "sel_comb_25v",
00069                              "sel_comb_27h",
00070                              "sel_comb_27v",
00071                              "sel_comb_28h",
00072                              "sel_comb_28v",
00073                              "sel_comb_30h",
00074                              "sel_comb_30v",
00075                              "sel_comb_32h",
00076                              "sel_comb_32v",
00077                              "sel_comb_33h",
00078                              "sel_comb_33v",
00079                              "sel_comb_35h",
00080                              "sel_comb_35v",
00081                              "sel_comb_36h",
00082                              "sel_comb_36v",
00083                              "sel_comb_39h",
00084                              "sel_comb_39v",
00085                              "sel_comb_40h",
00086                              "sel_comb_40v",
00087                              "sel_comb_42h",
00088                              "sel_comb_42v",
00089                              "sel_comb_44h",
00090                              "sel_comb_44v",
00091                              "sel_comb_45h",
00092                              "sel_comb_45v",
00093                              "sel_comb_48h",
00094                              "sel_comb_48v",
00095                              "sel_comb_49h",
00096                              "sel_comb_49v",
00097                              "sel_comb_50h",
00098                              "sel_comb_50v",
00099                              "sel_comb_52h",
00100                              "sel_comb_52v",
00101                              "sel_comb_54h",
00102                              "sel_comb_54v",
00103                              "sel_comb_55h",
00104                              "sel_comb_55v",
00105                              "sel_comb_56h",
00106                              "sel_comb_56v",
00107                              "sel_comb_60h",
00108                              "sel_comb_60v",
00109                              "sel_comb_63h",
00110                              "sel_comb_63v"};
00111 
00112 /*!
00113  *  pixMorphDwa_2()
00114  *
00115  *      Input:  pixd (usual 3 choices: null, == pixs, != pixs)
00116  *              pixs (1 bpp)
00117  *              operation  (L_MORPH_DILATE, L_MORPH_ERODE,
00118  *                          L_MORPH_OPEN, L_MORPH_CLOSE)
00119  *              sel name
00120  *      Return: pixd
00121  *
00122  *  Notes:
00123  *      (1) This simply adds a border, calls the appropriate
00124  *          pixFMorphopGen_*(), and removes the border.
00125  *          See the notes for that function.
00126  *      (2) The size of the border depends on the operation
00127  *          and the boundary conditions.
00128  */
00129 PIX *
00130 pixMorphDwa_2(PIX     *pixd,
00131               PIX     *pixs,
00132               l_int32  operation,
00133               char    *selname)
00134 {
00135 l_int32  bordercolor, bordersize;
00136 PIX     *pixt1, *pixt2, *pixt3;
00137 
00138     PROCNAME("pixMorphDwa_2");
00139 
00140     if (!pixs)
00141         return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
00142     if (pixGetDepth(pixs) != 1)
00143         return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
00144 
00145         /* Set the border size */
00146     bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
00147     bordersize = 32;
00148     if (bordercolor == 0 && operation == L_MORPH_CLOSE)
00149         bordersize += 32;
00150 
00151     pixt1 = pixAddBorder(pixs, bordersize, 0);
00152     pixt2 = pixFMorphopGen_2(NULL, pixt1, operation, selname);
00153     pixt3 = pixRemoveBorder(pixt2, bordersize);
00154     pixDestroy(&pixt1);
00155     pixDestroy(&pixt2);
00156 
00157     if (!pixd)
00158         return pixt3;
00159 
00160     pixCopy(pixd, pixt3);
00161     pixDestroy(&pixt3);
00162     return pixd;
00163 }
00164 
00165 
00166 /*!
00167  *  pixFMorphopGen_2()
00168  *
00169  *      Input:  pixd (usual 3 choices: null, == pixs, != pixs)
00170  *              pixs (1 bpp)
00171  *              operation  (L_MORPH_DILATE, L_MORPH_ERODE,
00172  *                          L_MORPH_OPEN, L_MORPH_CLOSE)
00173  *              sel name
00174  *      Return: pixd
00175  *
00176  *  Notes:
00177  *      (1) This is a dwa operation, and the Sels must be limited in
00178  *          size to not more than 31 pixels about the origin.
00179  *      (2) A border of appropriate size (32 pixels, or 64 pixels
00180  *          for safe closing with asymmetric b.c.) must be added before
00181  *          this function is called.
00182  *      (3) This handles all required setting of the border pixels
00183  *          before erosion and dilation.
00184  *      (4) The closing operation is safe; no pixels can be removed
00185  *          near the boundary.
00186  */
00187 PIX *
00188 pixFMorphopGen_2(PIX     *pixd,
00189                  PIX     *pixs,
00190                  l_int32  operation,
00191                  char    *selname)
00192 {
00193 l_int32    i, index, found, w, h, wpls, wpld, bordercolor, erodeop, borderop;
00194 l_uint32  *datad, *datas, *datat;
00195 PIX       *pixt;
00196 
00197     PROCNAME("pixFMorphopGen_2");
00198 
00199     if (!pixs)
00200         return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
00201     if (pixGetDepth(pixs) != 1)
00202         return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
00203 
00204         /* Get boundary colors to use */
00205     bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
00206     if (bordercolor == 1)
00207         erodeop = PIX_SET;
00208     else
00209         erodeop = PIX_CLR;
00210 
00211     found = FALSE;
00212     for (i = 0; i < NUM_SELS_GENERATED; i++) {
00213         if (strcmp(selname, SEL_NAMES[i]) == 0) {
00214             found = TRUE;
00215             index = 2 * i;
00216             break;
00217         }
00218     }
00219     if (found == FALSE)
00220         return (PIX *)ERROR_PTR("sel index not found", procName, pixd);
00221 
00222     if (!pixd) {
00223         if ((pixd = pixCreateTemplate(pixs)) == NULL)
00224             return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00225     }
00226     else  /* for in-place or pre-allocated */
00227         pixResizeImageData(pixd, pixs);
00228     wpls = pixGetWpl(pixs);
00229     wpld = pixGetWpl(pixd);
00230 
00231         /* The images must be surrounded, in advance, with a border of
00232          * size 32 pixels (or 64, for closing), that we'll read from.
00233          * Fabricate a "proper" image as the subimage within the 32
00234          * pixel border, having the following parameters:  */
00235     w = pixGetWidth(pixs) - 64;
00236     h = pixGetHeight(pixs) - 64;
00237     datas = pixGetData(pixs) + 32 * wpls + 1;
00238     datad = pixGetData(pixd) + 32 * wpld + 1;
00239 
00240     if (operation == L_MORPH_DILATE || operation == L_MORPH_ERODE) {
00241         borderop = PIX_CLR;
00242         if (operation == L_MORPH_ERODE) {
00243             borderop = erodeop;
00244             index++;
00245         }
00246         if (pixd == pixs) {  /* in-place; generate a temp image */
00247             if ((pixt = pixCopy(NULL, pixs)) == NULL)
00248                 return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
00249             datat = pixGetData(pixt) + 32 * wpls + 1;
00250             pixSetOrClearBorder(pixt, 32, 32, 32, 32, borderop);
00251             fmorphopgen_low_2(datad, w, h, wpld, datat, wpls, index);
00252             pixDestroy(&pixt);
00253         }
00254         else { /* not in-place */
00255             pixSetOrClearBorder(pixs, 32, 32, 32, 32, borderop);
00256             fmorphopgen_low_2(datad, w, h, wpld, datas, wpls, index);
00257         }
00258     }
00259     else {  /* opening or closing; generate a temp image */
00260         if ((pixt = pixCreateTemplate(pixs)) == NULL)
00261             return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
00262         datat = pixGetData(pixt) + 32 * wpls + 1;
00263         if (operation == L_MORPH_OPEN) {
00264             pixSetOrClearBorder(pixs, 32, 32, 32, 32, erodeop);
00265             fmorphopgen_low_2(datat, w, h, wpls, datas, wpls, index+1);
00266             pixSetOrClearBorder(pixt, 32, 32, 32, 32, PIX_CLR);
00267             fmorphopgen_low_2(datad, w, h, wpld, datat, wpls, index);
00268         }
00269         else {  /* closing */
00270             pixSetOrClearBorder(pixs, 32, 32, 32, 32, PIX_CLR);
00271             fmorphopgen_low_2(datat, w, h, wpls, datas, wpls, index);
00272             pixSetOrClearBorder(pixt, 32, 32, 32, 32, erodeop);
00273             fmorphopgen_low_2(datad, w, h, wpld, datat, wpls, index+1);
00274         }
00275         pixDestroy(&pixt);
00276     }
00277 
00278     return pixd;
00279 }
00280 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines