1 #include <stdlib.h>
2 #include <limits.h>
3 #include <math.h>
4 #include <tina/sys.h>
5 #include <tina/sysfuncs.h>
6 #include <tina/math.h>
7 #include <tina/mathfuncs.h>
8 #include <tina/vision.h>
9 #include <tina/visionfuncs.h>
10 #include "morph.h"
11
12 /****************************************************************************
13 *
14 * imcthin1n() thins the objects in an image
15 * using algorithm in Gonzalez&Wintz
16 * iterates until zero pixels are changed
17 * *pixelcount is the number of changed pixels
18 *
19 * functions called: NONE
20 *
21 *
22 *
23 *****************************************************************************/
24
25 int imcthin1n (
26 Imrect *im1,
27 Imrect *im2,
28 unsigned long *pixelcount)
29 {
30 unsigned int i, j;
31 int count;
32 unsigned long pcount;
33 int a, b, c, d, f, g, h, k;
34 unsigned char m;
35 int sp1;
36 unsigned int jminus1, jplus1;
37 unsigned char **image1, **image2;
38 unsigned char *ipointm1, *ipoint1, *ipointp1;
39 unsigned char *ipoint2;
40 unsigned int xmin, ymin, xmax, ymax;
41
42
43 /*** access image1 structure with error checking ***/
44
45 if ( ( im1 == NULL ) || ( im2 == NULL ) )
46 return (IMAGE_POINTER_NULL ); /* undefined image struct */
47 if ( ( im1->data == NULL ) || ( im2->data == NULL ) )
48 return (IMAGE_DATA_NULL); /* image data corrupt */
49
50 if ( (im1->vtype != uchar_v ) ||
51 (( *im2 ).vtype != uchar_v ))
52 return ( PIXEL_TYPE );
53
54 image1 = (unsigned char **) im1->data;
55 image2 = (unsigned char **) im2->data;
56
57
58 /* get window values with limits checking */
59 xmin = im1->region->lx +1;
60 xmax = im1->region->ux -1;
61 ymin = im1->region->ly +1;
62 ymax = im1->region->uy - 1;
63
64
65 /*** conditional mark logic ***/
66 /* local array is labeled :
67
68 abc 8 4 2
69 def 16 1
70 ghk 32 64 128 */
71
72 *pixelcount = 0;
73 do {
74 pcount = 0;
75 /*** first image pass ***/
76
77 for ( i = ymin; i < ymax; i++ )
78 {
79 ipointm1 = IM_ROW( im1, i - 1);
80 ipoint1 = IM_ROW( im1, i);
81 ipointp1 = IM_ROW( im1, i + 1);
82 ipoint2 = IM_ROW( im2, i);
83 for ( j = xmin; j < xmax; j++ )
84 {
85 m = (unsigned char) FALSE;
86
87 if ( ipoint1 [j] )
88 {
89 jminus1 = j - 1;
90 jplus1 = j + 1;
91
92 a = (ipointm1 [jplus1] ? 1 : 0);
93 b = (ipoint1 [jplus1] ? 1 : 0);
94 c = (ipointp1 [jplus1] ? 1 : 0);
95 d = (ipointm1 [j] ? 1 : 0);
96 f = (ipointp1 [j] ? 1 : 0);
97 g = (ipointm1 [jminus1] ? 1 : 0);
98 h = (ipoint1 [jminus1] ? 1 : 0);
99 k = (ipointp1 [jminus1] ? 1 : 0);
100
101 count = a + b + c + d;
102 count += f + g + h + k;
103 if ( ( count == 1 ) || ( count > 6 ) ) /* condition A */
104 goto nextpixel;
105
106 /* condition B */
107 sp1 = 0;
108 if ( !b && c )
109 sp1++;
110 if ( !c && f )
111 sp1++;
112 if ( !f && k )
113 sp1++;
114 if ( !k && h )
115 sp1++;
116 if ( !h && g )
117 sp1++;
118 if ( !g && d )
119 sp1++;
120 if ( !d && a )
121 sp1++;
122 if ( !a && b )
123 sp1++;
124 if ( sp1 != 1 )
125 goto nextpixel;
126
127 /* conditions C and D */
128 if ( ( b && f && h ) || ( f && h && d ) )
129 goto nextpixel;
130
131 m = (unsigned char) TRUE;
132 pcount++;
133 }
134
135 nextpixel:
136 ;
137
138 ipoint2 [j] = m;
139 }
140 }
141
142 for ( i = ymin; i < ymax; i++ )
143 {
144 ipoint1 = IM_ROW( im1, i);
145 ipoint2 = IM_ROW( im2, i);
146 for ( j = xmin; j < xmax; j++ )
147 if ( ipoint2 [j] )
148 {
149 ipoint1 [j] = (unsigned char) FALSE;
150 ipoint2 [j] = (unsigned char) FALSE;
151 }
152 }
153 /*** second image pass ***/
154 for ( i = ymin; i < ymax; i++ )
155 {
156 ipointm1 = IM_ROW( im1, i - 1);
157 ipoint1 = IM_ROW( im1, i);
158 ipointp1 = IM_ROW( im1, i + 1);
159 ipoint2 = IM_ROW( im2, i);
160 for ( j = xmin; j < xmax; j++ )
161 {
162 m = (unsigned char) FALSE;
163
164 if ( ipoint1 [j] )
165 {
166 jminus1 = j - 1;
167 jplus1 = j + 1;
168
169 a = (ipointm1 [jplus1] ? 1 : 0);
170 b = (ipoint1 [jplus1] ? 1 : 0);
171 c = (ipointp1 [jplus1] ? 1 : 0);
172 d = (ipointm1 [j] ? 1 : 0);
173 f = (ipointp1 [j] ? 1 : 0);
174 g = (ipointm1 [jminus1] ? 1 : 0);
175 h = (ipoint1 [jminus1] ? 1 : 0);
176 k = (ipointp1 [jminus1] ? 1 : 0);
177
178 count = a + b + c + d;
179 count += f + g + h + k;
180 if ( ( count == 1 ) || ( count > 6 ) ) /* condition A */
181 goto nextpixel2;
182
183 /* condition B */
184 sp1 = 0;
185 if ( !b && c )
186 sp1++;
187 if ( !c && f )
188 sp1++;
189 if ( !f && k )
190 sp1++;
191 if ( !k && h )
192 sp1++;
193 if ( !h && g )
194 sp1++;
195 if ( !g && d )
196 sp1++;
197 if ( !d && a )
198 sp1++;
199 if ( !a && b )
200 sp1++;
201 if ( sp1 != 1 )
202 goto nextpixel2;
203
204
205 /* conditions C and D */
206 if ( ( b && f && d ) || ( b && d && h ) )
207 goto nextpixel2;
208
209 m = (unsigned char) TRUE;
210 pcount++;
211 }
212
213 nextpixel2:
214 ;
215
216 ipoint2 [j] = m;
217 }
218 }
219
220 for ( i = ymin; i < ymax; i++ )
221 {
222 ipoint1 = IM_ROW( im1, i);
223 ipoint2 = IM_ROW( im2, i);
224 for ( j = xmin; j < xmax; j++ )
225 if ( ipoint2 [j] )
226 ipoint1 [j] = (unsigned char) FALSE;
227 }
228 ( *pixelcount ) += pcount;
229 }
230 while ( pcount != 0 );
231
232
233 return ( OK );
234 }
235
236 /****************************************************************************
237 *
238 * imcbthin1n() thins the background in an image
239 * using algorithm in G&W
240 * iterates until zero pixels are changed
241 * *pixelcount is the number of changed pixels
242 *
243 * functions called: NONE
244 *
245 *
246 *****************************************************************************/
247
248 int imcbthin1n (
249 Imrect *im1,
250 Imrect *im2,
251 unsigned long *pixelcount)
252 {
253 int status;
254 unsigned int i, j;
255 unsigned char *ipoint1;
256 unsigned int xmin, ymin;
257
258 /*** access image1 structure with error checking ***/
259
260 if ( ( im1 == NULL ) || ( im2 == NULL ) )
261 return (IMAGE_POINTER_NULL ); /* undefined image struct */
262 if ( ( im1->data == NULL ) || ( im2->data == NULL ) )
263 return (IMAGE_DATA_NULL); /* image data corrupt */
264
265 if ( (im1->vtype != uchar_v ) ||
266 (( *im2 ).vtype != uchar_v ))
267 return ( PIXEL_TYPE );
268
269
270
271 /* reverse image region */
272 for ( i = im1->region->ly; i < im1->region->uy ; i++ )
273 {
274 ipoint1 = (unsigned char *) IM_ROW( im1, i );
275 for ( j = im1->region->lx; j < im1->region->ux; j++ )
276 ipoint1 [j] = (unsigned char) !ipoint1 [j];
277 }
278
279 if((status = imcthin1n( im1, im2, pixelcount )) != OK )
280 return( status );
281
282 for ( i = im1->region->ly; i < im1->region->uy ; i++ )
283 {
284 ipoint1 = (unsigned char *) IM_ROW( im1, i );
285 for ( j = im1->region->lx; j < im1->region->ux; j++ )
286 ipoint1 [j] = (unsigned char) !ipoint1 [j];
287 }
288
289 return OK;
290 }
291
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.