!+++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
!.COPYRIGHT (C) 1990 European Southern Observatory
!.IDENT smooth.prg
!.AUTHOR Klaus Banse, ESO - Garching
!.KEYWORDS Smoothing, Filtering
!.PURPOSE smooth an image bu box-car filtering
!.VERSION 1.0 Creation 900129
!
!-------------------------------------------------------
!
DEFINE/PARAM P1 ? IMA "Enter input frame: "
DEFINE/PARAM P2 ? IMA "Enter output frame: "
DEFINE/PARAM P3 1.,0. N "Enter radius, threshold: "
DEFINE/PARAM P4 Y C "Enter center_flag, Y(es) or N(o): "
WRITE/KEYWORD IN_A {P1}
WRITE/KEYWORD OUT_A {P2}
WRITE/KEYWORD INPUTR/R/1/2 {P3}
WRITE/KEYWORD HISTORY Smooth
WRITE/KEYWORD DEFAULT {P4}
RUN smooth.exe
To run the application execute the procedure via
C @(#)smooth.for 6.3 (ESO-IPG) 1/17/94 17:53:36
C
C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
C.IDENTIFICATION
C program SMOOTH version 5.00 900129
C K. Banse ESO - Garching
C
C.KEYWORDS
C smoothing, average
C
C.PURPOSE
C smooth an image by averaging in the neighborhood
C
C.ALGORITHM
C get the names of input + output frames from Keywords IN_A + IN_B,
C get the radius + threshold for the averaging algorithm from the
C Keyword INPUTI and calculate new points via:
C
C B(n) = SUM A(j), j in neighbourhood of given radius around n, if
C SUM - A(n) > threshold*A(n), else B(n) = A(n)
C
C.INPUT/OUTPUT
C the following Keywords are used:
C
C IN_A/C/1/60 input frame
C OUT_A/C/1/60 output frame
C DEFAULT/C/1/1 default = Y, include center pixel in calculation
C of SUM
C INPUTR/R/1/2 radius ( >0 ), threshold ( in [0,1] ) for
C averaging algorithm
C
C-------------------------------------------------------------------
C
PROGRAM SMOOTH
C
IMPLICIT NONE
C
INTEGER NAXISA,NPIXA(2),IAV,STAT,IRAD
INTEGER IMNOA,IMNOC,PNTRA,PNTRC
INTEGER KNULL,KUNIT(1) !KNULL, KUNIT currently only
INTEGER MADRID(1) !placeholders...!
C
CHARACTER*60 FRAMEA,FRAMEC
CHARACTER CUNITA*64,IDENTA*72,DEFAUL*1
C
DOUBLE PRECISION STEPA(2),STARTA(2) !descr. START + STEP are
C !now double precision
C
REAL THRESH,INPUTR(2),CUTS(4)
C
C the following INCLUDE statements may look strange to a Unix user,
C but the ESO preprocessor takes care of the syntax...
C
INCLUDE 'MID_INCLUDE:ST_DEF.INC' !to get the definitions
C !for the ST interfaces...
C
C very important COMMON block VMR for the pointer emulation in Fortran 77 !!!
COMMON /VMR/ MADRID
C
INCLUDE 'MID_INCLUDE:ST_DAT.INC' !to get the data values
C !for the definitions above...
C
DATA IDENTA /' '/ !initialization of IDENTA, CUNITA
DATA CUNITA /' '/ !is necessary for STIGET ...
C
C set up MIDAS environment + enable automatic error abort
C
CALL STSPRO('SMOOTH')
C
C get name of input frame and map it as an image with pixels
C in floating point format
C use the definitions from the include file ST_DEF.INC (e.g. D_R4_FORMAT)
C
CALL STKRDC('IN_A',1,1,60,IAV,FRAMEA,KUNIT,KNULL,STAT)
CALL STIGET(FRAMEA,D_R4_FORMAT,F_I_MODE,F_IMA_TYPE,
+ 2,NAXISA,NPIXA,STARTA,STEPA,
+ IDENTA,CUNITA,PNTRA,IMNOA,STAT)
C
C a call to STETER will abort the program ...
C
IF (NAXISA.NE.2)
+ CALL STETER(1,'input frame must have 2 dimensions...')
C
C get name of output frame and create and map it
C Note, that this does not fill in any data values
C
CALL STKRDC('OUT_A',1,1,60,IAV,FRAMEC,KUNIT,KNULL,STAT)
CALL STIPUT(FRAMEC,D_R4_FORMAT,F_O_MODE,F_IMA_TYPE,
+ NAXISA,NPIXA,STARTA,STEPA,
+ IDENTA,CUNITA,PNTRC,IMNOC,STAT)
C
C since we use STIGET and STIPUT we cannot have calls of STFGET or STFPUT...
C
C get flag, if center pixel should be included
C get the radius + threshold for the averaging algorithm
C
CALL STKRDC('DEFAULT',1,1,1,IAV,DEFAUL,KUNIT,KNULL,STAT)
CALL STKRDR('INPUTR',1,2,IAV,INPUTR,KUNIT,KNULL,STAT)
IRAD = NINT(INPUTR(1))
THRESH = INPUTR(2)
C
C Now call the subroutine to do the averaging.
C Note, that the address of the input and output array are passed to the
C subroutine using the array MADRID
C
CALL AVERAG(MADRID(PNTRA),MADRID(PNTRC),NPIXA(1),NPIXA(2),
+ IRAD,THRESH,DEFAUL)
C
C update descr. HISTORY with contents of keyword HISTORY + P1, P2, ...
C and copy all non-standard descriptors from input to output frame
C
IDENTA(1:) = ' '
CALL DSCUPT(IMNOA,IMNOC,IDENTA(1:1),STAT)
C
C release files, update keywords and exit
C STSEPI closes all open images, only then are the data values written
C into the result image file
C
CALL STSEPI
C
END
SUBROUTINE AVERAG(A,B,NX,NY,IRAD,THRESH,ALL)
C
C smooth 2-dim image by taking the average of surrounding points,
C if it differs more than THRESH from original value
C
IMPLICIT NONE
C
INTEGER NX,NY,IRAD
INTEGER N,NN,NL,NRL,NP,OFF,OFFA,DIFX,INDX
C
REAL A(1),B(1),THRESH,TEST,COUNT,W
C
CHARACTER ALL*1
C
C initialize COUNT
C to number of pixels in neighbourhood of center
COUNT = FLOAT(IRAD*(IRAD+1)*4) + 1.
C
C first IRAD lines are not treated
C
DO 1000 N=1,IRAD*NX
B(N) = A(N)
1000 CONTINUE
C
C main loop over inner lines
C
DO 5000 NL=IRAD+1,NY-IRAD
OFF = (NL-1)*NX
C
C leave first IRAD values of each line as they are
C
DO 2000 N=OFF+1,OFF+IRAD
B(N) = A(N)
2000 CONTINUE
C
C average in the inner part
C
DO 4000 NP=IRAD+1,NX-IRAD
INDX = OFF + NP !pixel to work on
W = A(INDX) !save original pixel value
TEST = 0.0 !clear sum
C !sum over IRAD lines above
DO 3000 NRL=1,IRAD !and below current line
DIFX = NRL * NX
OFFA = INDX - DIFX - IRAD
DO 2500 NN=OFFA,OFFA+IRAD*2
TEST = TEST + A(NN)
2500 CONTINUE
C
OFFA = OFFA + (2*DIFX)
DO 2800 NN=OFFA,OFFA+IRAD*2
TEST = TEST + A(NN)
2800 CONTINUE
3000 CONTINUE
C
DO 3100 NN=INDX-IRAD,INDX+IRAD !sum over current line
TEST = TEST + A(NN)
3100 CONTINUE
C
C compare average of neighbourhood with pixel in question
C
IF (ALL.NE.'Y') THEN
TEST = (TEST-W) / (COUNT-1.)
ELSE
TEST = TEST/COUNT
ENDIF
C
IF (ABS (TEST-W).GT.ABS (THRESH*W)) THEN
B(INDX) = TEST
ELSE
B(INDX) = W
ENDIF
4000 CONTINUE
C
C leave last IRAD values of each line as they are
C
DO 4100 NN=OFF+NX-IRAD+1,OFF+NX
B(NN) = A(NN)
4100 CONTINUE
C
5000 CONTINUE
C
C end of main loop - last lines are not treated
C
DO 6000 N=(NY-IRAD)*NX+1,NX*NY
B(N) = A(N)
6000 CONTINUE
C
C that's it folks
C
RETURN
END