Leptonica 1.68
C Image Processing Library

dwalinear.3.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_3()
00020  *             PIX     *pixFMorphopGen_3()
00021  */
00022 
00023 #include <string.h>
00024 #include "allheaders.h"
00025 
00026 PIX *pixMorphDwa_3(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
00027 PIX *pixFMorphopGen_3(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
00028 l_int32 fmorphopgen_low_3(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 = 124;
00034 static char  SEL_NAMES[][80] = {
00035                              "sel_2h",
00036                              "sel_3h",
00037                              "sel_4h",
00038                              "sel_5h",
00039                              "sel_6h",
00040                              "sel_7h",
00041                              "sel_8h",
00042                              "sel_9h",
00043                              "sel_10h",
00044                              "sel_11h",
00045                              "sel_12h",
00046                              "sel_13h",
00047                              "sel_14h",
00048                              "sel_15h",
00049                              "sel_16h",
00050                              "sel_17h",
00051                              "sel_18h",
00052                              "sel_19h",
00053                              "sel_20h",
00054                              "sel_21h",
00055                              "sel_22h",
00056                              "sel_23h",
00057                              "sel_24h",
00058                              "sel_25h",
00059                              "sel_26h",
00060                              "sel_27h",
00061                              "sel_28h",
00062                              "sel_29h",
00063                              "sel_30h",
00064                              "sel_31h",
00065                              "sel_32h",
00066                              "sel_33h",
00067                              "sel_34h",
00068                              "sel_35h",
00069                              "sel_36h",
00070                              "sel_37h",
00071                              "sel_38h",
00072                              "sel_39h",
00073                              "sel_40h",
00074                              "sel_41h",
00075                              "sel_42h",
00076                              "sel_43h",
00077                              "sel_44h",
00078                              "sel_45h",
00079                              "sel_46h",
00080                              "sel_47h",
00081                              "sel_48h",
00082                              "sel_49h",
00083                              "sel_50h",
00084                              "sel_51h",
00085                              "sel_52h",
00086                              "sel_53h",
00087                              "sel_54h",
00088                              "sel_55h",
00089                              "sel_56h",
00090                              "sel_57h",
00091                              "sel_58h",
00092                              "sel_59h",
00093                              "sel_60h",
00094                              "sel_61h",
00095                              "sel_62h",
00096                              "sel_63h",
00097                              "sel_2v",
00098                              "sel_3v",
00099                              "sel_4v",
00100                              "sel_5v",
00101                              "sel_6v",
00102                              "sel_7v",
00103                              "sel_8v",
00104                              "sel_9v",
00105                              "sel_10v",
00106                              "sel_11v",
00107                              "sel_12v",
00108                              "sel_13v",
00109                              "sel_14v",
00110                              "sel_15v",
00111                              "sel_16v",
00112                              "sel_17v",
00113                              "sel_18v",
00114                              "sel_19v",
00115                              "sel_20v",
00116                              "sel_21v",
00117                              "sel_22v",
00118                              "sel_23v",
00119                              "sel_24v",
00120                              "sel_25v",
00121                              "sel_26v",
00122                              "sel_27v",
00123                              "sel_28v",
00124                              "sel_29v",
00125                              "sel_30v",
00126                              "sel_31v",
00127                              "sel_32v",
00128                              "sel_33v",
00129                              "sel_34v",
00130                              "sel_35v",
00131                              "sel_36v",
00132                              "sel_37v",
00133                              "sel_38v",
00134                              "sel_39v",
00135                              "sel_40v",
00136                              "sel_41v",
00137                              "sel_42v",
00138                              "sel_43v",
00139                              "sel_44v",
00140                              "sel_45v",
00141                              "sel_46v",
00142                              "sel_47v",
00143                              "sel_48v",
00144                              "sel_49v",
00145                              "sel_50v",
00146                              "sel_51v",
00147                              "sel_52v",
00148                              "sel_53v",
00149                              "sel_54v",
00150                              "sel_55v",
00151                              "sel_56v",
00152                              "sel_57v",
00153                              "sel_58v",
00154                              "sel_59v",
00155                              "sel_60v",
00156                              "sel_61v",
00157                              "sel_62v",
00158                              "sel_63v"};
00159 
00160 /*!
00161  *  pixMorphDwa_3()
00162  *
00163  *      Input:  pixd (usual 3 choices: null, == pixs, != pixs)
00164  *              pixs (1 bpp)
00165  *              operation  (L_MORPH_DILATE, L_MORPH_ERODE,
00166  *                          L_MORPH_OPEN, L_MORPH_CLOSE)
00167  *              sel name
00168  *      Return: pixd
00169  *
00170  *  Notes:
00171  *      (1) This simply adds a border, calls the appropriate
00172  *          pixFMorphopGen_*(), and removes the border.
00173  *          See the notes for that function.
00174  *      (2) The size of the border depends on the operation
00175  *          and the boundary conditions.
00176  */
00177 PIX *
00178 pixMorphDwa_3(PIX     *pixd,
00179               PIX     *pixs,
00180               l_int32  operation,
00181               char    *selname)
00182 {
00183 l_int32  bordercolor, bordersize;
00184 PIX     *pixt1, *pixt2, *pixt3;
00185 
00186     PROCNAME("pixMorphDwa_3");
00187 
00188     if (!pixs)
00189         return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
00190     if (pixGetDepth(pixs) != 1)
00191         return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
00192 
00193         /* Set the border size */
00194     bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
00195     bordersize = 32;
00196     if (bordercolor == 0 && operation == L_MORPH_CLOSE)
00197         bordersize += 32;
00198 
00199     pixt1 = pixAddBorder(pixs, bordersize, 0);
00200     pixt2 = pixFMorphopGen_3(NULL, pixt1, operation, selname);
00201     pixt3 = pixRemoveBorder(pixt2, bordersize);
00202     pixDestroy(&pixt1);
00203     pixDestroy(&pixt2);
00204 
00205     if (!pixd)
00206         return pixt3;
00207 
00208     pixCopy(pixd, pixt3);
00209     pixDestroy(&pixt3);
00210     return pixd;
00211 }
00212 
00213 
00214 /*!
00215  *  pixFMorphopGen_3()
00216  *
00217  *      Input:  pixd (usual 3 choices: null, == pixs, != pixs)
00218  *              pixs (1 bpp)
00219  *              operation  (L_MORPH_DILATE, L_MORPH_ERODE,
00220  *                          L_MORPH_OPEN, L_MORPH_CLOSE)
00221  *              sel name
00222  *      Return: pixd
00223  *
00224  *  Notes:
00225  *      (1) This is a dwa operation, and the Sels must be limited in
00226  *          size to not more than 31 pixels about the origin.
00227  *      (2) A border of appropriate size (32 pixels, or 64 pixels
00228  *          for safe closing with asymmetric b.c.) must be added before
00229  *          this function is called.
00230  *      (3) This handles all required setting of the border pixels
00231  *          before erosion and dilation.
00232  *      (4) The closing operation is safe; no pixels can be removed
00233  *          near the boundary.
00234  */
00235 PIX *
00236 pixFMorphopGen_3(PIX     *pixd,
00237                  PIX     *pixs,
00238                  l_int32  operation,
00239                  char    *selname)
00240 {
00241 l_int32    i, index, found, w, h, wpls, wpld, bordercolor, erodeop, borderop;
00242 l_uint32  *datad, *datas, *datat;
00243 PIX       *pixt;
00244 
00245     PROCNAME("pixFMorphopGen_3");
00246 
00247     if (!pixs)
00248         return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
00249     if (pixGetDepth(pixs) != 1)
00250         return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
00251 
00252         /* Get boundary colors to use */
00253     bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
00254     if (bordercolor == 1)
00255         erodeop = PIX_SET;
00256     else
00257         erodeop = PIX_CLR;
00258 
00259     found = FALSE;
00260     for (i = 0; i < NUM_SELS_GENERATED; i++) {
00261         if (strcmp(selname, SEL_NAMES[i]) == 0) {
00262             found = TRUE;
00263             index = 2 * i;
00264             break;
00265         }
00266     }
00267     if (found == FALSE)
00268         return (PIX *)ERROR_PTR("sel index not found", procName, pixd);
00269 
00270     if (!pixd) {
00271         if ((pixd = pixCreateTemplate(pixs)) == NULL)
00272             return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
00273     }
00274     else  /* for in-place or pre-allocated */
00275         pixResizeImageData(pixd, pixs);
00276     wpls = pixGetWpl(pixs);
00277     wpld = pixGetWpl(pixd);
00278 
00279         /* The images must be surrounded, in advance, with a border of
00280          * size 32 pixels (or 64, for closing), that we'll read from.
00281          * Fabricate a "proper" image as the subimage within the 32
00282          * pixel border, having the following parameters:  */
00283     w = pixGetWidth(pixs) - 64;
00284     h = pixGetHeight(pixs) - 64;
00285     datas = pixGetData(pixs) + 32 * wpls + 1;
00286     datad = pixGetData(pixd) + 32 * wpld + 1;
00287 
00288     if (operation == L_MORPH_DILATE || operation == L_MORPH_ERODE) {
00289         borderop = PIX_CLR;
00290         if (operation == L_MORPH_ERODE) {
00291             borderop = erodeop;
00292             index++;
00293         }
00294         if (pixd == pixs) {  /* in-place; generate a temp image */
00295             if ((pixt = pixCopy(NULL, pixs)) == NULL)
00296                 return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
00297             datat = pixGetData(pixt) + 32 * wpls + 1;
00298             pixSetOrClearBorder(pixt, 32, 32, 32, 32, borderop);
00299             fmorphopgen_low_3(datad, w, h, wpld, datat, wpls, index);
00300             pixDestroy(&pixt);
00301         }
00302         else { /* not in-place */
00303             pixSetOrClearBorder(pixs, 32, 32, 32, 32, borderop);
00304             fmorphopgen_low_3(datad, w, h, wpld, datas, wpls, index);
00305         }
00306     }
00307     else {  /* opening or closing; generate a temp image */
00308         if ((pixt = pixCreateTemplate(pixs)) == NULL)
00309             return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
00310         datat = pixGetData(pixt) + 32 * wpls + 1;
00311         if (operation == L_MORPH_OPEN) {
00312             pixSetOrClearBorder(pixs, 32, 32, 32, 32, erodeop);
00313             fmorphopgen_low_3(datat, w, h, wpls, datas, wpls, index+1);
00314             pixSetOrClearBorder(pixt, 32, 32, 32, 32, PIX_CLR);
00315             fmorphopgen_low_3(datad, w, h, wpld, datat, wpls, index);
00316         }
00317         else {  /* closing */
00318             pixSetOrClearBorder(pixs, 32, 32, 32, 32, PIX_CLR);
00319             fmorphopgen_low_3(datat, w, h, wpls, datas, wpls, index);
00320             pixSetOrClearBorder(pixt, 32, 32, 32, 32, erodeop);
00321             fmorphopgen_low_3(datad, w, h, wpld, datat, wpls, index+1);
00322         }
00323         pixDestroy(&pixt);
00324     }
00325 
00326     return pixd;
00327 }
00328 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines