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 * 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