VIRCAM Pipeline 2.3.12
apclust.c
1/* $Id: apclust.c,v 1.3 2015/08/12 11:16:55 jim Exp $
2 *
3 * This file is part of the CASU Pipeline utilities
4 * Copyright (C) 2015 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: jim $
23 * $Date: 2015/08/12 11:16:55 $
24 * $Revision: 1.3 $
25 * $Name: $
26 */
27
28#include <stdio.h>
29#include <cpl.h>
30
31#include "imcore.h"
32#include "util.h"
33
34static void minmax_xy(int, plstruct *, int *, int *, int *, int *);
35
38/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
70
71void imcore_apclust(ap_t *ap, int np, plstruct *plstr) {
72
73 int i,i1,loop,ik;
74 int is; /* parent name for image in this slice */
75 int ip; /* parent name for image on last line */
76 int ib; /* data block name */
77 int k,j,ix1,ix2,iy1,iy2,nwork,nx,ny,kk;
78 float i2compare,icompare;
79 short int *work;
80
81 /* A couple of useful things */
82
83 i2compare = ap->thresh;
84 icompare = i2compare * ap->multiply;
85
86 /* Get the min and max positions. Create a raster with the IDs of the
87 pixels in the pixel list (algorithm prefers data to be in a raster) */
88
89 minmax_xy(np,plstr,&ix1,&ix2,&iy1,&iy2);
90 nx = ix2 - ix1 + 1;
91 ny = iy2 - iy1 + 1;
92 nwork = nx*ny;
93 work = cpl_malloc(nwork*sizeof(*work));
94 for (i = 0; i < nwork; i++)
95 work[i] = -1;
96 for (k = 0; k < np; k++) {
97 i = plstr[k].x - 1;
98 j = plstr[k].y - 1;
99 kk = (j - iy1)*nx + i - ix1;
100 work[kk] = k;
101 }
102
103 /* Now do the job */
104
105 for (j = iy1; j <= iy2; j++) {
106 for (i = ix1; i <= ix2; i++) {
107 kk = (j - iy1)*nx + i - ix1;
108 k = work[kk];
109 if (k < 0) {
110 ap->lastline[i + 1] = 0;
111 } else {
112 if (plstr[k].zsm > icompare) {
113
114 /* Pixel is above threshold, find which parent it belongs to. */
115
116 is = ap->lastline[i]; /* Parent last pixel this line */
117 ip = ap->lastline[i + 1]; /* Guess belongs to above line */
118 if (ip == 0) {
119
120 /* New parent, or, horizontal slice: */
121
122 if (is == 0) {
123
124 /* Ah - new parent. */
125
126 if (ap->ipstack > ap->maxpa*3/4) {
127 for (ik = 0; ik < ap->maxpa*3/8; ik++)
128 imcore_apfu(ap);
129 }
130 ip = ap->pstack[ap->ipstack++];
131 ap->parent[ip].first = ap->bstack[ap->ibstack];
132 ap->parent[ip].pnop = 0;
133 ap->parent[ip].pnbp = 0;
134 ap->parent[ip].growing = 0;
135 if (j == 0)
136
137 /* It touches first line: */
138
139 ap->parent[ip].touch = 1;
140 else
141 ap->parent[ip].touch = 0;
142
143 /* For hunt thru list for terminates: */
144
145 if (ip > ap->maxip)
146 ap->maxip = ip;
147 } else {
148
149 /* Slice with no vertical join: */
150
151 ip = is;
152 }
153 } else if ((ip > 0 && is > 0) && (ip != is)) {
154
155 /* merge: Join linked lists: */
156
157 ap->blink[ap->parent[ip].last] = ap->parent[is].first;
158
159 /* Copy `last block': */
160
161 ap->parent[ip].last = ap->parent[is].last;
162 ap->parent[ip].pnop += ap->parent[is].pnop;
163 ap->parent[ip].pnbp += ap->parent[is].pnbp;
164
165 /* Fix `lastline' correlator array: */
166
167 ib = ap->parent[is].first;
168 loop = 1;
169 while (loop) {
170 i1 = ap->plessey[ib].x;
171 if (ap->lastline[i1 + 1] == is)
172 ap->lastline[i1 + 1] = ip;
173 if (ap->parent[is].last == ib)
174 loop = 0;
175 else
176 ib = ap->blink[ib];
177 }
178
179 /* Mark parent inactive: */
180
181 ap->parent[is].pnop = -1;
182 ap->parent[is].pnbp = -1;
183
184 /* return name to stack: */
185
186 ap->pstack[--ap->ipstack] = is;
187 }
188
189 /* Add in pixel to linked list: */
190
191 ib = ap->bstack[ap->ibstack++];
192
193 /* Patch forward link into last data block: */
194
195 if (ap->parent[ip].pnop > 0)
196 ap->blink[ap->parent[ip].last] = ib;
197
198 /* Remember last block in chain: */
199
200 ap->parent[ip].last = ib;
201
202 /* Store the data: */
203
204 ap->plessey[ib].x = i;
205 ap->plessey[ib].y = j;
206 ap->plessey[ib].z = plstr[k].z;
207 ap->plessey[ib].zsm = plstr[k].zsm;
208
209 /* increment active count: */
210
211 ap->parent[ip].pnop++;
212
213 /* remember which parent this pixel was for next line: */
214
215 ap->lastline[i + 1] = ip;
216
217 } else {
218
219 /* Pixel was below threshold, mark lastline: */
220
221 ap->lastline[i + 1] = 0;
222 }
223 }
224 }
225 }
226
227 /* Check for images touching left & right edges:
228 OR the touch flag with 2 for left, 4 for right: */
229
230 if(ap->lastline[1] > 0 )
231 ap->parent[ap->lastline[1]].touch |= 2;
232 if(ap->lastline[ap->lsiz] > 0)
233 ap->parent[ap->lastline[ap->lsiz]].touch |= 4;
234 cpl_free(work);
235}
236
237/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
261
262static void minmax_xy(int np, plstruct *plstr, int *ix1, int *ix2, int *iy1,
263 int *iy2) {
264 int i;
265
266 /* Get the minmax of the positions of the pixels in a plstruct. Take
267 1 away from each position so that it runs from 0 rather than 1 */
268
269 *ix1 = plstr[0].x - 1;
270 *ix2 = plstr[0].x - 1;
271 *iy1 = plstr[0].y - 1;
272 *iy2 = plstr[0].y - 1;
273 for (i = 1; i < np; i++) {
274 *ix1 = MIN(*ix1,plstr[i].x - 1);
275 *ix2 = MAX(*ix2,plstr[i].x - 1);
276 *iy1 = MIN(*iy1,plstr[i].y - 1);
277 *iy2 = MAX(*iy2,plstr[i].y - 1);
278 }
279}
280
283/*
284
285$Log: apclust.c,v $
286Revision 1.3 2015/08/12 11:16:55 jim
287Modified procedure names to protect namespace
288
289Revision 1.2 2015/08/07 13:06:54 jim
290Fixed copyright to ESO
291
292Revision 1.1.1.1 2015/06/12 10:44:32 jim
293Initial import
294
295Revision 1.2 2014/04/09 09:09:51 jim
296Detabbed
297
298Revision 1.1.1.1 2013/08/27 12:07:48 jim
299Imported
300
301
302*/
void imcore_apclust(ap_t *ap, int np, plstruct *plstr)
Detect multiple objects from a given Plessey array.
Definition: apclust.c:71
void imcore_apfu(ap_t *ap)
Get rid of the largest contributor in an ap structure.
Definition: terminate.c:194