| ARX 1.0 The next-generation open source augmented reality toolkit.

Loading...
Searching...
No Matches
arLabelingSub.h
Go to the documentation of this file.
1/*
2 * arLabeling.c
3 * artoolkitX
4 *
5 * This file is part of artoolkitX.
6 *
7 * artoolkitX is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * artoolkitX is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with artoolkitX. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * As a special exception, the copyright holders of this library give you
21 * permission to link this library with independent modules to produce an
22 * executable, regardless of the license terms of these independent modules, and to
23 * copy and distribute the resulting executable under terms of your choice,
24 * provided that you also meet, for each linked independent module, the terms and
25 * conditions of the license of that module. An independent module is a module
26 * which is neither derived from nor based on this library. If you modify this
27 * library, you may extend this exception to your version of the library, but you
28 * are not obligated to do so. If you do not wish to do so, delete this exception
29 * statement from your version.
30 *
31 * Copyright 2018 Realmax, Inc.
32 * Copyright 2015 Daqri, LLC.
33 * Copyright 2003-2015 ARToolworks, Inc.
34 *
35 * Author(s): Hirokazu Kato, Philip Lamb
36 *
37 */
38/*******************************************************
39 *
40 * Author: Hirokazu Kato
41 *
42 * kato@sys.im.hiroshima-cu.ac.jp
43 *
44 * Revision: 4.0
45 * Date: 03/08/13
46 *
47 *******************************************************/
48
49#include <stdlib.h>
50#include <stdio.h>
51#include <string.h> // memset()
52#include <ARX/AR/ar.h>
53#include "arLabelingPrivate.h"
54
55#define AR_PIXEL_SIZE 1
56
57#ifndef AR_LABELING_ADAPTIVE
58# ifndef AR_LABELING_DEBUG_ENABLE_F
59# ifndef AR_LABELING_WHITE_REGION_F
60# ifndef AR_LABELING_FRAME_IMAGE_F
61 int arLabelingSubDBIC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
62# else
63 int arLabelingSubDBRC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
64# endif // !AR_LABELING_FRAME_IMAGE_F
65# else
66# ifndef AR_LABELING_FRAME_IMAGE_F
67 int arLabelingSubDWIC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
68# else
69 int arLabelingSubDWRC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
70# endif // !AR_LABELING_FRAME_IMAGE_F
71# endif // !AR_LABELING_WHITE_REGION_F
72# else
73# ifndef AR_LABELING_WHITE_REGION_F
74# ifndef AR_LABELING_FRAME_IMAGE_F
75 int arLabelingSubEBIC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
76# else
77 int arLabelingSubEBRC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
78# endif // !AR_LABELING_FRAME_IMAGE_F
79# else
80# ifndef AR_LABELING_FRAME_IMAGE_F
81 int arLabelingSubEWIC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
82# else
83 int arLabelingSubEWRC( ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo )
84# endif // !AR_LABELING_FRAME_IMAGE_F
85# endif // !AR_LABELING_WHITE_REGION_F
86# endif // !AR_LABELING_DEBUG_ENABLE_F
87#else
88# ifndef AR_LABELING_DEBUG_ENABLE_F
89# ifndef AR_LABELING_WHITE_REGION_F
90 int arLabelingSubDBZ( ARUint8 *image, const int xsize, const int ysize, ARUint8* image_thresh, ARLabelInfo *labelInfo )
91# else
92 int arLabelingSubDWZ( ARUint8 *image, const int xsize, const int ysize, ARUint8* image_thresh, ARLabelInfo *labelInfo )
93# endif // !AR_LABELING_WHITE_REGION_F
94# else
95# ifndef AR_LABELING_WHITE_REGION_F
96 int arLabelingSubEBZ( ARUint8 *image, const int xsize, const int ysize, ARUint8* image_thresh, ARLabelInfo *labelInfo )
97# else
98 int arLabelingSubEWZ( ARUint8 *image, const int xsize, const int ysize, ARUint8* image_thresh, ARLabelInfo *labelInfo )
99# endif // !AR_LABELING_WHITE_REGION_F
100# endif // !AR_LABELING_DEBUG_ENABLE_F
101#endif
102
103{
104 int lxsize, lysize;
105 ARUint8 *pnt; /* image pointer into source image */
106#ifdef AR_LABELING_ADAPTIVE
107 ARUint8 *pnt_thresh;
108#endif
109 AR_LABELING_LABEL_TYPE *pnt1, *pnt2; /* image pointer into destination (label) image */
110#ifdef AR_LABELING_DEBUG_ENABLE_F
111 ARUint8 *dpnt;
112#endif
113 int *work, *work2;
114 int wk_max; /* work */
115 int i,j,k,l; /* for loop */
116 int *wk; /* pointer for work */
117 int m,n; /* work */
118 int *label_num;
119 int *area;
120 int *clip;
121 ARdouble *pos;
122
123#ifdef AR_LABELING_FRAME_IMAGE_F
124 lxsize = xsize;
125 lysize = ysize;
126#else
127 lxsize = xsize / 2;
128 lysize = ysize / 2;
129#endif
130
131#ifdef AR_LABELING_DEBUG_ENABLE_F
132 //memset( labelInfo->bwImage, 0, lxsize*lysize );
133#endif
134
135 // Set top and bottom rows of labelImage to 0.
136 pnt1 = &(labelInfo->labelImage[0]); // Leftmost pixel of top row of image.
137 pnt2 = &(labelInfo->labelImage[(lysize - 1)*lxsize]); // Leftmost pixel of bottom row of image.
138 for(i = 0; i < lxsize; i++) {
139 *(pnt1++) = *(pnt2++) = 0;
140 }
141
142 // Set leftmost and rightmost columns of labelImage to 0.
143 pnt1 = &(labelInfo->labelImage[0]); // Leftmost pixel of top row of image.
144 pnt2 = &(labelInfo->labelImage[lxsize - 1]); // Rightmost pixel of top row of image.
145 for(i = 0; i < lysize; i++) {
146 *pnt1 = *pnt2 = 0;
147 pnt1 += lxsize;
148 pnt2 += lxsize;
149 }
150
151 wk_max = 0;
152 work = labelInfo->work;
153 work2 = labelInfo->work2;
154 pnt2 = &(labelInfo->labelImage[lxsize + 1]); // Start on 2nd pixel of 2nd row.
155#ifdef AR_LABELING_DEBUG_ENABLE_F
156 dpnt = &(labelInfo->bwImage[lxsize + 1]);
157# ifdef AR_LABELING_FRAME_IMAGE_F
158 pnt = &(image[(xsize + 1)*AR_PIXEL_SIZE]); // Start on 2nd pixel of 2nd row.
159# ifdef AR_LABELING_ADAPTIVE
160 pnt_thresh = &(image_thresh[(xsize + 1)*AR_PIXEL_SIZE]);
161 for(j = 1; j < lysize - 1; j++, pnt += AR_PIXEL_SIZE*2, pnt_thresh += AR_PIXEL_SIZE*2, pnt2 += 2, dpnt += 2) { // Process rows. At end of each row, skips last pixel of row and first pixel of next row.
162 for(i = 1; i < lxsize - 1; i++, pnt += AR_PIXEL_SIZE, pnt_thresh += AR_PIXEL_SIZE, pnt2++, dpnt++) { // Process columns.
163# else
164 for(j = 1; j < lysize - 1; j++, pnt += AR_PIXEL_SIZE*2, pnt2 += 2, dpnt += 2) { // Process rows. At end of each row, skips last pixel of row and first pixel of next row.
165 for(i = 1; i < lxsize - 1; i++, pnt += AR_PIXEL_SIZE, pnt2++, dpnt++) { // Process columns.
166# endif
167# else
168 pnt = &(image[(xsize*2 + 2)*AR_PIXEL_SIZE]);
169 for(j = 1; j < lysize - 1; j++, pnt += AR_PIXEL_SIZE*4, pnt2 += 2, dpnt += 2) {
170 for(i = 1; i < lxsize - 1; i++, pnt += AR_PIXEL_SIZE*2, pnt2++, dpnt++) {
171# endif
172#else
173# ifdef AR_LABELING_FRAME_IMAGE_F
174 pnt = &(image[(xsize + 1)*AR_PIXEL_SIZE]); // Start on 2nd pixel of 2nd row.
175# ifdef AR_LABELING_ADAPTIVE
176 pnt_thresh = &(image_thresh[(xsize + 1)*AR_PIXEL_SIZE]);
177 for(j = 1; j < lysize - 1; j++, pnt += AR_PIXEL_SIZE*2, pnt_thresh += AR_PIXEL_SIZE*2, pnt2 += 2) { // Process rows. At end of each row, skips last pixel of row and first pixel of next row.
178 for(i = 1; i < lxsize - 1; i++, pnt += AR_PIXEL_SIZE, pnt_thresh += AR_PIXEL_SIZE, pnt2++) { // Process columns.
179# else
180 for(j = 1; j < lysize - 1; j++, pnt += AR_PIXEL_SIZE*2, pnt2 += 2) { // Process rows. At end of each row, skips last pixel of row and first pixel of next row.
181 for(i = 1; i < lxsize - 1; i++, pnt += AR_PIXEL_SIZE, pnt2++) { // Process columns.
182# endif
183# else
184 pnt = &(image[(xsize*2 + 2)*AR_PIXEL_SIZE]);
185 for(j = 1; j < lysize - 1; j++, pnt += AR_PIXEL_SIZE*4, pnt2 += 2) {
186 for(i = 1; i < lxsize - 1; i++, pnt += AR_PIXEL_SIZE*2, pnt2++) {
187# endif
188#endif // AR_LABELING_DEBUG_ENABLE_F
189
190#ifndef AR_LABELING_WHITE_REGION_F
191// Black region.
192# ifndef AR_LABELING_ADAPTIVE
193 if( *pnt <= labelingThresh ) {
194# else
195 if( *pnt <= *pnt_thresh ) {
196# endif
197#else
198// White region.
199# ifndef AR_LABELING_ADAPTIVE
200 if( *pnt > labelingThresh ) {
201# else
202 if( *pnt > *pnt_thresh ) {
203# endif
204#endif // !AR_LABELING_WHITE_REGION_F
205 // pnt is in region.
206# ifdef AR_LABELING_DEBUG_ENABLE_F
207 *dpnt = 255;
208# endif
209 pnt1 = &(pnt2[-lxsize]);
210 if( *pnt1 > 0 ) {
211 *pnt2 = *pnt1;
212 l = ((*pnt2) - 1) * 7;
213 work2[l+0] ++; // area
214 work2[l+1] += i; // pos[0]
215 work2[l+2] += j; // pos[1]
216 work2[l+6] = j; // clip[3]
217 }
218 else if( *(pnt1+1) > 0 ) {
219 if( *(pnt1-1) > 0 ) {
220 m = work[*(pnt1+1)-1];
221 n = work[*(pnt1-1)-1];
222 if( m > n ) {
223 *pnt2 = n;
224 wk = &(work[0]);
225 for(k = 0; k < wk_max; k++) {
226 if( *wk == m ) *wk = n;
227 wk++;
228 }
229 }
230 else if( m < n ) {
231 *pnt2 = m;
232 wk = &(work[0]);
233 for(k = 0; k < wk_max; k++) {
234 if( *wk == n ) *wk = m;
235 wk++;
236 }
237 }
238 else *pnt2 = m;
239 l = ((*pnt2)-1)*7;
240 work2[l+0] ++; // area.
241 work2[l+1] += i; // pos[0]
242 work2[l+2] += j; // pos[1]
243 work2[l+6] = j; // clip[3]
244 }
245 else if( *(pnt2-1) > 0 ) {
246 m = work[*(pnt1+1)-1];
247 n = work[*(pnt2-1)-1];
248 if( m > n ) {
249 *pnt2 = n;
250 wk = &(work[0]);
251 for(k = 0; k < wk_max; k++) {
252 if( *wk == m ) *wk = n;
253 wk++;
254 }
255 }
256 else if( m < n ) {
257 *pnt2 = m;
258 wk = &(work[0]);
259 for(k = 0; k < wk_max; k++) {
260 if( *wk == n ) *wk = m;
261 wk++;
262 }
263 }
264 else *pnt2 = m;
265 l = ((*pnt2)-1)*7;
266 work2[l+0] ++; // area
267 work2[l+1] += i; // pos[0]
268 work2[l+2] += j; // pos[1]
269 }
270 else {
271 *pnt2 = *(pnt1+1);
272 l = ((*pnt2)-1)*7;
273 work2[l+0] ++; // area
274 work2[l+1] += i; // pos[0]
275 work2[l+2] += j; // pos[1]
276 if( work2[l+3] > i ) work2[l+3] = i; // clip[0]
277 work2[l+6] = j; // clip [3]
278 }
279 }
280 else if( *(pnt1-1) > 0 ) {
281 *pnt2 = *(pnt1-1);
282 l = ((*pnt2)-1)*7;
283 work2[l+0] ++; // area
284 work2[l+1] += i; // pos[0]
285 work2[l+2] += j; // pos[1]
286 if( work2[l+4] < i ) work2[l+4] = i; // clip[1]
287 work2[l+6] = j; // clip[3]
288 }
289 else if( *(pnt2-1) > 0) {
290 *pnt2 = *(pnt2-1);
291 l = ((*pnt2)-1)*7;
292 work2[l+0] ++; // area
293 work2[l+1] += i; // pos[0]
294 work2[l+2] += j; // pos[1]
295 if( work2[l+4] < i ) work2[l+4] = i; // clip[1]
296 }
297 else {
298 wk_max++;
299 if( wk_max > AR_LABELING_WORK_SIZE ) {
300 ARLOGe("Error: labeling work overflow.\n");
301 return(-1);
302 }
303 work[wk_max-1] = *pnt2 = wk_max;
304 l = (wk_max-1)*7;
305 work2[l+0] = 1; // area
306 work2[l+1] = i; // pos[0]
307 work2[l+2] = j; // pos[1]
308 work2[l+3] = i; // clip[0]
309 work2[l+4] = i; // clip[1]
310 work2[l+5] = j; // clip[2]
311 work2[l+6] = j; // clip[3]
312 }
313 }
314 else {
315 // pnt is NOT in region.
316 *pnt2 = 0;
317#ifdef AR_LABELING_DEBUG_ENABLE_F
318 *dpnt = 0;
319#endif
320 }
321 }
322#ifndef AR_LABELING_FRAME_IMAGE_F
323 pnt += xsize*AR_PIXEL_SIZE;
324#endif
325 }
326
327 label_num = &(labelInfo->label_num);
328 area = &(labelInfo->area[0]);
329 clip = &(labelInfo->clip[0][0]);
330 pos = &(labelInfo->pos[0][0]);
331 j = 1;
332 wk = &(work[0]);
333 for(i = 1; i <= wk_max; i++, wk++) {
334 *wk = (*wk==i)? j++: work[(*wk)-1];
335 }
336 *label_num = j - 1;
337 if( *label_num == 0 ) {
338 return 0;
339 }
340
341 memset( (ARUint8 *)area, 0, *label_num * sizeof(int) );
342 memset( (ARUint8 *)pos, 0, *label_num * 2 * sizeof(ARdouble) );
343 for(i = 0; i < *label_num; i++) {
344 clip[i*4+0] = lxsize;
345 clip[i*4+1] = 0;
346 clip[i*4+2] = lysize;
347 clip[i*4+3] = 0;
348 }
349 for(i = 0; i < wk_max; i++) {
350 j = work[i] - 1;
351 area[j] += work2[i*7+0];
352 pos[j*2+0] += work2[i*7+1];
353 pos[j*2+1] += work2[i*7+2];
354 if( clip[j*4+0] > work2[i*7+3] ) clip[j*4+0] = work2[i*7+3];
355 if( clip[j*4+1] < work2[i*7+4] ) clip[j*4+1] = work2[i*7+4];
356 if( clip[j*4+2] > work2[i*7+5] ) clip[j*4+2] = work2[i*7+5];
357 if( clip[j*4+3] < work2[i*7+6] ) clip[j*4+3] = work2[i*7+6];
358 }
359
360 for( i = 0; i < *label_num; i++ ) {
361 pos[i*2+0] /= area[i];
362 pos[i*2+1] /= area[i];
363 }
364
365 return 0;
366}
ar.h
artoolkitX core routines.
ARUint8
unsigned char ARUint8
Definition: ar.h:92
ARdouble
double ARdouble
Definition: ar.h:99
AR_LABELING_LABEL_TYPE
#define AR_LABELING_LABEL_TYPE
Definition: arConfig.h:111
AR_LABELING_WORK_SIZE
#define AR_LABELING_WORK_SIZE
Definition: arConfig.h:110
arLabelingPrivate.h
arLabelingSubDWIC
int arLabelingSubDWIC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubEBIC
int arLabelingSubEBIC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubEBRC
int arLabelingSubEBRC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubEWZ
int arLabelingSubEWZ(ARUint8 *image, const int xsize, const int ysize, ARUint8 *image_thresh, ARLabelInfo *labelInfo)
arLabelingSubDWZ
int arLabelingSubDWZ(ARUint8 *image, const int xsize, const int ysize, ARUint8 *image_thresh, ARLabelInfo *labelInfo)
arLabelingSubEBZ
int arLabelingSubEBZ(ARUint8 *image, const int xsize, const int ysize, ARUint8 *image_thresh, ARLabelInfo *labelInfo)
arLabelingSubDBRC
int arLabelingSubDBRC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubEWRC
int arLabelingSubEWRC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubDBZ
int arLabelingSubDBZ(ARUint8 *image, const int xsize, const int ysize, ARUint8 *image_thresh, ARLabelInfo *labelInfo)
arLabelingSubDWRC
int arLabelingSubDWRC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubEWIC
int arLabelingSubEWIC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
arLabelingSubDBIC
int arLabelingSubDBIC(ARUint8 *image, int xsize, int ysize, int labelingThresh, ARLabelInfo *labelInfo)
Definition: arLabelingSub.h:61
AR_PIXEL_SIZE
#define AR_PIXEL_SIZE
Definition: arLabelingSub.h:55
ARLOGe
#define ARLOGe(...)
Definition: log.h:141
ARLabelInfo
(description)
Definition: ar.h:247
ARLabelInfo::pos
ARdouble pos[AR_LABELING_WORK_SIZE][2]
Definition: ar.h:255
ARLabelInfo::work
int work[AR_LABELING_WORK_SIZE]
Definition: ar.h:256
ARLabelInfo::bwImage
ARUint8 * bwImage
Definition: ar.h:250
ARLabelInfo::clip
int clip[AR_LABELING_WORK_SIZE][4]
Definition: ar.h:254
ARLabelInfo::area
int area[AR_LABELING_WORK_SIZE]
Definition: ar.h:253
ARLabelInfo::label_num
int label_num
Definition: ar.h:252
ARLabelInfo::labelImage
AR_LABELING_LABEL_TYPE * labelImage
Definition: ar.h:248
ARLabelInfo::work2
int work2[AR_LABELING_WORK_SIZE *7]
area, pos[2], clip[4].
Definition: ar.h:257