Leptonica  1.82.0
Image processing and image analysis suite
fmorphgen.1.c
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
34 #include <string.h>
35 #include "allheaders.h"
36 
37 PIX *pixMorphDwa_1(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
38 PIX *pixFMorphopGen_1(PIX *pixd, PIX *pixs, l_int32 operation, char *selname);
39 l_int32 fmorphopgen_low_1(l_uint32 *datad, l_int32 w,
40  l_int32 h, l_int32 wpld,
41  l_uint32 *datas, l_int32 wpls,
42  l_int32 index);
43 
44 static l_int32 NUM_SELS_GENERATED = 58;
45 static char SEL_NAMES[][80] = {
46  "sel_2h",
47  "sel_3h",
48  "sel_4h",
49  "sel_5h",
50  "sel_6h",
51  "sel_7h",
52  "sel_8h",
53  "sel_9h",
54  "sel_10h",
55  "sel_11h",
56  "sel_12h",
57  "sel_13h",
58  "sel_14h",
59  "sel_15h",
60  "sel_20h",
61  "sel_21h",
62  "sel_25h",
63  "sel_30h",
64  "sel_31h",
65  "sel_35h",
66  "sel_40h",
67  "sel_41h",
68  "sel_45h",
69  "sel_50h",
70  "sel_51h",
71  "sel_2v",
72  "sel_3v",
73  "sel_4v",
74  "sel_5v",
75  "sel_6v",
76  "sel_7v",
77  "sel_8v",
78  "sel_9v",
79  "sel_10v",
80  "sel_11v",
81  "sel_12v",
82  "sel_13v",
83  "sel_14v",
84  "sel_15v",
85  "sel_20v",
86  "sel_21v",
87  "sel_25v",
88  "sel_30v",
89  "sel_31v",
90  "sel_35v",
91  "sel_40v",
92  "sel_41v",
93  "sel_45v",
94  "sel_50v",
95  "sel_51v",
96  "sel_2",
97  "sel_3",
98  "sel_4",
99  "sel_5",
100  "sel_2dp",
101  "sel_2dm",
102  "sel_5dp",
103  "sel_5dm"};
104 
124 PIX *
125 pixMorphDwa_1(PIX *pixd,
126  PIX *pixs,
127  l_int32 operation,
128  char *selname)
129 {
130 l_int32 bordercolor, bordersize;
131 PIX *pixt1, *pixt2, *pixt3;
132 
133  PROCNAME("pixMorphDwa_1");
134 
135  if (!pixs)
136  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
137  if (pixGetDepth(pixs) != 1)
138  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
139 
140  /* Set the border size */
141  bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
142  bordersize = 32;
143  if (bordercolor == 0 && operation == L_MORPH_CLOSE)
144  bordersize += 32;
145 
146  pixt1 = pixAddBorder(pixs, bordersize, 0);
147  pixt2 = pixFMorphopGen_1(NULL, pixt1, operation, selname);
148  pixt3 = pixRemoveBorder(pixt2, bordersize);
149  pixDestroy(&pixt1);
150  pixDestroy(&pixt2);
151 
152  if (!pixd)
153  return pixt3;
154 
155  pixCopy(pixd, pixt3);
156  pixDestroy(&pixt3);
157  return pixd;
158 }
159 
160 
184 PIX *
185 pixFMorphopGen_1(PIX *pixd,
186  PIX *pixs,
187  l_int32 operation,
188  char *selname)
189 {
190 l_int32 i, index, found, w, h, wpls, wpld, bordercolor, erodeop, borderop;
191 l_uint32 *datad, *datas, *datat;
192 PIX *pixt;
193 
194  PROCNAME("pixFMorphopGen_1");
195 
196  if (!pixs)
197  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
198  if (pixGetDepth(pixs) != 1)
199  return (PIX *)ERROR_PTR("pixs must be 1 bpp", procName, pixd);
200 
201  /* Get boundary colors to use */
202  bordercolor = getMorphBorderPixelColor(L_MORPH_ERODE, 1);
203  if (bordercolor == 1)
204  erodeop = PIX_SET;
205  else
206  erodeop = PIX_CLR;
207 
208  found = FALSE;
209  for (i = 0; i < NUM_SELS_GENERATED; i++) {
210  if (strcmp(selname, SEL_NAMES[i]) == 0) {
211  found = TRUE;
212  index = 2 * i;
213  break;
214  }
215  }
216  if (found == FALSE)
217  return (PIX *)ERROR_PTR("sel index not found", procName, pixd);
218 
219  if (!pixd) {
220  if ((pixd = pixCreateTemplate(pixs)) == NULL)
221  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
222  }
223  else /* for in-place or pre-allocated */
224  pixResizeImageData(pixd, pixs);
225  wpls = pixGetWpl(pixs);
226  wpld = pixGetWpl(pixd);
227 
228  /* The images must be surrounded, in advance, with a border of
229  * size 32 pixels (or 64, for closing), that we'll read from.
230  * Fabricate a "proper" image as the subimage within the 32
231  * pixel border, having the following parameters: */
232  w = pixGetWidth(pixs) - 64;
233  h = pixGetHeight(pixs) - 64;
234  datas = pixGetData(pixs) + 32 * wpls + 1;
235  datad = pixGetData(pixd) + 32 * wpld + 1;
236 
237  if (operation == L_MORPH_DILATE || operation == L_MORPH_ERODE) {
238  borderop = PIX_CLR;
239  if (operation == L_MORPH_ERODE) {
240  borderop = erodeop;
241  index++;
242  }
243  if (pixd == pixs) { /* in-place; generate a temp image */
244  if ((pixt = pixCopy(NULL, pixs)) == NULL)
245  return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
246  datat = pixGetData(pixt) + 32 * wpls + 1;
247  pixSetOrClearBorder(pixt, 32, 32, 32, 32, borderop);
248  fmorphopgen_low_1(datad, w, h, wpld, datat, wpls, index);
249  pixDestroy(&pixt);
250  }
251  else { /* not in-place */
252  pixSetOrClearBorder(pixs, 32, 32, 32, 32, borderop);
253  fmorphopgen_low_1(datad, w, h, wpld, datas, wpls, index);
254  }
255  }
256  else { /* opening or closing; generate a temp image */
257  if ((pixt = pixCreateTemplate(pixs)) == NULL)
258  return (PIX *)ERROR_PTR("pixt not made", procName, pixd);
259  datat = pixGetData(pixt) + 32 * wpls + 1;
260  if (operation == L_MORPH_OPEN) {
261  pixSetOrClearBorder(pixs, 32, 32, 32, 32, erodeop);
262  fmorphopgen_low_1(datat, w, h, wpls, datas, wpls, index+1);
263  pixSetOrClearBorder(pixt, 32, 32, 32, 32, PIX_CLR);
264  fmorphopgen_low_1(datad, w, h, wpld, datat, wpls, index);
265  }
266  else { /* closing */
267  pixSetOrClearBorder(pixs, 32, 32, 32, 32, PIX_CLR);
268  fmorphopgen_low_1(datat, w, h, wpls, datas, wpls, index);
269  pixSetOrClearBorder(pixt, 32, 32, 32, 32, erodeop);
270  fmorphopgen_low_1(datad, w, h, wpld, datat, wpls, index+1);
271  }
272  pixDestroy(&pixt);
273  }
274 
275  return pixd;
276 }
277 
l_uint32 getMorphBorderPixelColor(l_int32 type, l_int32 depth)
getMorphBorderPixelColor()
Definition: morph.c:1803
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixResizeImageData(PIX *pixd, const PIX *pixs)
pixResizeImageData()
Definition: pix1.c:768
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1823
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
Definition: pix2.c:1972
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition: pix2.c:1514
#define PIX_CLR
Definition: pix.h:333
#define PIX_SET
Definition: pix.h:334
Definition: pix.h:139