/* @(#)splocext.c 17.1.1.1 (ES0-DMD) 01/25/02 17:56:15 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* Program : splocext.c /* Author : P. Ballester - ESO Garching */ /* Date : 08.09.94 Version 1.0 */ /* */ /* Purpose : */ /* */ /* Row by row detection of local extrema (e.g. for wavelet transforms) */ /* */ /* Input: */ /* - name of input image : IN_A */ /* - name of output peak detection : OUT_A */ /* - name of output window mask : OUT_B */ #include #include #define ipos2D(col,row,npix) row*npix[0]+col float *fvector(); void free_fvector(); main () { char inframe[100], outpeak[100], outzero[100]; char outwind[100], outmask[100]; char cunit[64], ident[72]; int imnin, imnp, imnz, imnw, imnm, imns, imnb, unit, null; int actvals, naxis, npix[2]; float *pntrin, *pntrp, *pntrw, *pntrz, *pntrm, *pntrs, *pntrb; double start[2], step[2]; int sign_ind1, sign_ind2, slope_ind, i, j, x, row; int sign_previous, sign_current, rows[2]; float previous, current, next, zero_cross; float max_value, abs_value, kappa; SCSPRO ("splocext"); SCKGETC ("IN_A", 1, 60, &actvals, inframe); SCKGETC ("IN_B", 1, 60, &actvals, outpeak); SCKGETC ("OUT_A", 1, 60, &actvals, outzero); SCKGETC ("OUT_B", 1, 60, &actvals, outwind); SCKGETC ("INPUTC", 1, 20, &actvals, outmask); SCKRDI ("INPUTI", 1, 2, &actvals, rows, &unit, &null); SCKRDR ("INPUTR", 1, 1, &actvals, &kappa, &unit, &null); strcpy(ident,""), strcpy(cunit,""); SCIGET(inframe, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, 2, &naxis, npix, start, step, ident, cunit, (char **)&pntrin, &imnin); if (naxis == 1) npix[1]=1; strcpy(ident,"Local extrema detection from: "); strcat(ident,inframe); SCIPUT(outpeak, D_R4_FORMAT, F_IO_MODE, F_IMA_TYPE, naxis, npix, start, step, ident, cunit, (char **)&pntrp, &imnp); strcpy(ident,"Zero Crossings from: "); strcat(ident,inframe); SCIPUT(outzero, D_R4_FORMAT, F_IO_MODE, F_IMA_TYPE, naxis, npix, start, step, ident, cunit, (char **)&pntrz, &imnz); strcpy(ident,"Windows from: "); strcat(ident,inframe); SCIPUT(outwind, D_R4_FORMAT, F_IO_MODE, F_IMA_TYPE, naxis, npix, start, step, ident, cunit, (char **)&pntrw, &imnw); strcpy(ident,"Segmented local extrema from: "); strcat(ident,inframe); SCIPUT("segment.bdf", D_R4_FORMAT, F_IO_MODE, F_IMA_TYPE, naxis, npix, start, step, ident, cunit, (char **)&pntrs, &imns); strcpy(ident,"Window fusion buffer from: "); strcat(ident,inframe); SCIPUT("buffer.bdf", D_R4_FORMAT, F_IO_MODE, F_IMA_TYPE, naxis, npix, start, step, ident, cunit, (char **)&pntrb, &imnb); strcpy(ident,"Features mask from: "); strcat(ident,inframe); SCIPUT(outmask, D_R4_FORMAT, F_IO_MODE, F_IMA_TYPE, 1, npix, start, step, ident, cunit, (char **)&pntrm, &imnm); for (row=0; row0) previous = pntrin[ipos2D(i-1,row,npix)]; current = pntrin[ipos2D(i ,row,npix)]; if (i0 && i 0.) ? 1 : -1; sign_current = (current > 0.) ? 1 : -1; if ((sign_previous + sign_current) == 0) zero_cross = (float) compare(previous,current); } pntrz[ipos2D(i,row,npix)] = zero_cross; } /* Segmentation of each row to generate window mask */ for (i=0; i=0 && pntrz[ipos2D(i-j,row,npix)]==0. && (pntrp[ipos2D(i+j,row,npix)]==0. || j==0); j++) pntrw[ipos2D(i-j,row,npix)] = pntrm[i]; pntrw[ipos2D(i-j,row,npix)] = pntrm[i]; } } /* Removing artifact features */ for (i=1; i next) { for(j=0; (i+j)=0 && (pntrw[ipos2D((i-j),row,npix)] != 0. || j==1); j++) pntrw[ipos2D((i-j),row,npix)] = 0.; printf("Erased until %d\n",i-j+1); }}} } /* For row = .. */ /* Multi-resolution scale fusion */ /* for (row=0; row=0; row--) fusion_scales_up (pntrw, pntrb, pntrz, npix, row); for (i=0; i= b) ? -1 : 1; if (a == b) ret = 0; return(ret); } /***********************************************************************/ /* Subroutine: sign(a) */ static int sign(a) float a; { if (a<0.) return(-1); if (a>0.) return(1); if (a==0.) return(0); } /*************************************************************************/ /* Sorting algorithm: Heapsort method */ /* From: Numerical Recipes, Cambridge University Press, p. 226 */ static int sort(n,ra) int n; float ra[]; { int l,j,ir,i; float rra; l=(n >> 1)+1; ir=n; for (;;) { if (l > 1) rra=ra[--l]; else { rra=ra[ir]; ra[ir]=ra[1]; if (--ir == 1) { ra[1]=rra; return; } } i=l; j=l << 1; while (j <= ir) { if (j < ir && ra[j] < ra[j+1]) ++j; if (rra < ra[j]) { ra[i]=ra[j]; j += (i=j); } else j=ir+1; } ra[i]=rra; } } /***********************************************************************/ static float median(List, N) float *List; int N; { float *Histo, med; int pos, i; pos = (N+1)/2; Histo = fvector(1, N); for (i=1; i<=N; i++) Histo[i] = List[i-1]; sort(N, Histo); med = Histo[pos]; free_fvector(Histo, 1, N); return(med); } /***********************************************************************/ static float mean(List, N) float *List; int N; { float av; int pos, i; av = 0.; for (i=0; i0 && sign_ref == compare(peak,pntrh[ipos2D(i, row, npixh)])) pntrwin[ipos2D(i--, row, npix)] = 1.; } /***********************************************************************/ /* Subroutine: Segment(List, N, kappa); */ static int segment(List, N, kappa) float *List, kappa; int N; { float m, s, t[2], *dev, median(); int i, cnt=0, cnt0; dev = fvector(0, N-1); /* Ignore zeroed values and copies absolute deviations */ for (i=0; i t[0] && List[i] < t[1]) List[i] = 0.; else cnt++, List[i] -= m; } printf("m = %f s = %f Range [%f, %f] Kept %d out of %d\n", m,s,t[0],t[1],cnt,cnt0); free_fvector(dev, 0, N-1); } /***********************************************************************/ static int fusion_scales_down (w, b, z, npix, row) float *w, *b, *z; int npix[], row; { int i,j, k, small_sign, large_sign, max_value = 0; float small_value, large_value; float D_Scale, Scale; if (row == 0) { for (i=0; i large_value) max_value = -1; }} b[ipos2D(i, row, npix)] = 0.; if (max_value == -1) b[ipos2D(i, row, npix)] = b[ipos2D(i, (row-1), npix)]; if (max_value == 1) b[ipos2D(i, row, npix)] = w[ipos2D(i, row, npix)]; }}} } /***********************************************************************/ static int fusion_scales_up (w, b, z, npix, row) float *w, *b, *z; int npix[], row; { int i,j, k, small_sign, large_sign, max_value = 0; float small_value, large_value; float D_Scale, Scale; if (row == npix[1]-1) { for (i=0; i large_value*large_sign && (small_sign + large_sign) != 0) max_value = -1; }} b[ipos2D(i, row, npix)] = 0.; if (max_value == -1) b[ipos2D(i, row, npix)] = w[ipos2D(i, (row), npix)]; if (max_value == 1) b[ipos2D(i, row, npix)] = b[ipos2D(i, (row+1), npix)]; }}} }