C PROGRAM NOTCH.FT C ---------------- C C PETER LEMKIN C IMAGE PROCESSING UNIT, DCBD C NATIONAL CANCER INSTITUTE C NATIONAL INSTITUTES OF HEALTH C 9000 ROCKVILLE PIKE C BETHESDA, MD. 20014 C C JAN 20, 1978 C C INTRODUCTION C ------------ C NOTCH.FT IS A CHAINED PROGRAM USED WITH BMON2 C IT RECEIVES ITS ARGUMENTS FROM THE CD AREA AND THE IBM1,IHGH1 C VARIABLES IN COMMON. C THE ARGUMENTS ARE THEN CHECKED C IT SHADE CORRECTS USING A 16X16 MOVING WINDOW. C C _NOTCH,,(Opt. N),(Opt.B) (Opt. /A) C - correct BMi using a moving C NxN averaged window. N is the number of lines of the averaging C filter with a default of 32. Note: n is even and > 1. C The basic notch filter algorithm was suggested by Jack C Sklansky. Parameter B is a valued added (default 0) C to keep negative values from being clipped. It computes for C each pixel Gj(x,y): C C Gj(x,y)=Gi(x,y) - AVGnxn,i(x,y) + B; C C clipped to zero for values < 0. C C AVGnxn,i(c,r) = (1/n*n)*SUM SUM Gi'(x,y); C x=c-n:c+n y=r-n:r+n C - - - - C 2 2 2 2 C C Gi'(x,y) = If x in [0:255] and y in [0:255] C Then Gi(x,y) C Else Relection on edge of Gi(x,y); C C If /A is specified, it performs two passes, the first pass C being used to compute the baseline constant C B, and the 2nd pass to actually perform the operation. C OPDEFS C ------ C S OPDEF RIF 6224 C S OPDEF TADI 1400 S OPDEF DCAI 3400 C S OPDEF DISP1 6435 S OPDEF DISP2 6436 C C S OPDEF MQA 7501 S OPDEF MQL 7421 S OPDEF KRS 6034 S OPDEF BSW 7002 C C C S OPDEF SWAB 7431 S OPDEF SWBA 7447 S OPDEF DAD 7443 S OPDEF DST 7445 S OPDEF DPIC 7573 S OPDEF DCM 7575 S OPDEF CLAMQ 7621 S OPDEF MUY 7405 S OPDEF SHL 7413 S OPDEF DVI 7407 C S OPDEF LSR 7417 C C [1] INITIALIZATION WRITE(1,995) WRITE(3,995) 995 FORMAT('0 NOTCH 1/20/78 - 5:09PM') ET=TIMER(0) C C C [1.1] VERIFY BM SPECS S JMS CKIN S JMS CKOUT C C C [1.2] GET NUMBER OF LINES IN NOTCH FILTER WITH C THE RANGE BEING [2:62]. S TAD \ICNUM S SZA S TAD (-1 /ONLY IF SPECIFY N S AND (0077 S IAC S AND (0176 /MAKE IT EVEN S SNA S TAD (D32 S DCA \N C C COMPUTE: N/2 AND NSQ N2=N/2 N2P1=N2+1 C COMPUTE: NSQ=N*N=4*((N/2)*(N/2)) N2SQ=N2*N2 NSQ=N2SQ+N2SQ+N2SQ+N2SQ C C C [1.3] GET THE BASELINE TO ADD TO THE AVG SUBTRACTION S TAD \ICNUM# S AND (377 S DCA \IBASE C C ZERO THE MAX BASELINE MBASE=0 C C IF /A C THEN DO NOT PRINT HEADER ON 1ST PASS. S TAD \ISW S SZA CLA S JMP \124 /SKIP PRINTING FIRST PASS C C C [1.4] PRINT NOTCH FILTER PARAMETERS C NOTE: IF /A IS SPECIFIED, THEN COME HERE ON 2ND PASS 120 DO 122 IZ=1,3,2 122 WRITE(IZ,123)N,N,IBASE 123 FORMAT(' NOTCH FILTER WINDOW SIZE IS ',I3,'X',I3 1,', BASELINE=',I3) C 124 CONTINUE C C C C [2] SHADE CORRECT BY SUBTRACTING THE AVG16X16 FROM BMI. DO 200 IY1=KY1,KY2 IY=IY1-1 C S TAD \IY S DISP2 C S CPAGE 3 S JMS TTYCTL S JMP \998 /EXIT C C GET BUFFER LOAD(S) FROM (BMI(IY))==>FIELD 6 C PACKED EVERY 256 WORDS. S JMS LOADBUF C C C COMPUTE: CENTER LINE OF BUFFER POINTERS. KYR=IRING+N2-1 C IF KYR > N-1 C THEN KYR_KYR-N S TAD \N S CIA S TAD \KYR S SMA CLA S TAD \N S CIA S TAD \KYR S IAC /ADD 1 SINCE [1:32] NOT [0:31] S DCA \KYR C*********DEBUG***** S 6344 S AND (0004 S SNA CLA S JMP \1997 WRITE(3,1996)IRING,KYR 1996 FORMAT(' IRING=',I5,', KYR=',I5,/) 1997 CONTINUE C********************** C C C C [2.1] PROCESS A LINE PIXEL BY PIXEL DO 201 IX1=KX1,KX2 IX=IX1-1 C S TAD \IX S DISP1 C C C [2.1.1] COMPUTE SHADING CORRECTION IA=0 C******DEBUG***** S 6344 S AND (0002 S SZA CLA S JMS AVG /PUT AVG IN IA[1] C****************** C@ JMS AVG /PUT AVG IN IA[1] C C COMPUTE: MBASE=MAX(MBASE,IA); S TAD \IA S CIA S TAD \MBASE S SMA CLA S JMP \205 MBASE=IA C C IF /A THEN DON'T SAVE DATA S\205, TAD \ISW S SZA CLA S JMP \200 /DON'T SAVE DATA C C COMPUTE: CENTER LINE OF BUFFER POINTERS. IYR=KYR IXP=IX S JMS LOOKUP /GET G(IX,IY)==>IVAL IZ=IVAL-IA+IBASE C C MAKE SURE IZ >0 ELSE CLIP AT 0 S TAD \IZ S SPA S CLA S DCA \IZ C C MAKE SURE IZ < 256 ELSE SET TO 255 S TAD \IZ S TAD (-D256 S SMA S CLA CMA /-1 S TAD (D256 S DCA \IZ C C C [2.1.2] STORE OUTPUT IN IBUF4 S CLA CMA S TAD \IX1 S TAD PBUF4 S DCA 7 S CPAGE 4 S TAD \IZ S DCAI 7 /IBUF4[IX1]<==IZ 201 CONTINUE C C C [2.2] OUTPUT IBUF4==>BMJ(IY) MEM=JBM IBYTE=JHGH CALL T3BUF(IBUF4,3) 200 CONTINUE C C C [2.3] DONE WITH A PASS. C IF NOT /A C THEN EXIT C ELSE IBASE_MBASE, RESET /A, GOTO [1.4]; S TAD \ISW S SNA CLA S JMP \998 /DONE! IBASE=MBASE C RESET THE /A SWITCH ISW=0 GOTO 120 C C C [999] RETURN GOTO 998 999 WRITE(1,996) 996 FORMAT('BAD BM SPECIFICATION!') 998 ET=TIMER(2) C C CALL CHAIN('BMON2') C*************************************************** C *SUBROUTINE C K O U T C****************************************************** C C C CHECK WHETHER THE OUTPUT BM SPEC IS LEGAL ELSE GOTO 999. S CPAGE 3 SRCKOUT, JMP I CKOUT S CKOUT, 0 /ENTRY C C [1] TEST IF KOUTFILE="BM" S TAD \KOUTFILE S CIA S TAD BMTEXT S SZA CLA S JMP \999 /FAILED C C [2] TEST IF (KOUTFILE(2) LAND '7700)=DIGIT S TAD \KOUTFILE# S BSW S AND (0077 S TAD (-60 /"0" S SPA S JMP \999 /NO, FAILED S TAD (-D8 /"7" TEST S SMA CLA S JMP \999 /FAILED S JMP RCKOUT /OK. C C C*************************************************** C *SUBROUTINE C K I N C****************************************************** C C C CHECK WHETHER THE INPUT BM SPEC IS LEGAL ELSE GOTO 999. S CPAGE 3 SRCKIN, JMP I CKIN S CKIN, 0 /ENTRY C C [1] TEST IF BMI1="BM" S TAD \SFILE S CIA S TAD BMTEXT S SZA CLA S JMP \999 /FAILED C C [2] TEST IF (BMI1(2) LAND '7700)=DIGIT S TAD \SFILE# S BSW S AND (0077 S TAD (-60 /"0" S SPA S JMP \999 /NO, FAILED S TAD (-D8 /"7" TEST S SMA CLA S JMP \999 /FAILED S JMP RCKIN /OK. C C C*************************************************** C *SUBROUTINE L O A D B U F F C****************************************************** C C C LOAD 16 LINE BUFFER LINE IY FROM (IHGH1,IBM1). C IF IY=0 THEN PRELOAD (-(N/2)+1,...,0,...,N/2) C IF IY>255 THEN USE LINE (255-(IY-255)). C ELSE USE LINE IY. S CPAGE 3 SRLOADBUFF, JMP I LOADBUFF S LOADBUFF, 0 /ENTRY C C C [1] IF IY1=KY1 THEN PRELOAD (-N/2,...,0,...,N/2) C*******DEBUG**** S 6344 /FBW4 S AND (0001 S SNA CLA S JMP \1998 /NO WRITE(3,1999)IY1,IRING 1999 FORMAT(' LOADBUF IY1=',I5,', IRING=',I5) 1998 CONTINUE C******************** IYSV=IY MEM=IBM1 IBYTE=IHGH1 IF(IY1-KY1)1400,1400,1402 C C COPY REVERSED (N/2) LINES 1400 DO 1401 IY0=1,N2 IY=(N2+1) - ((KY1-1)+(IY0)) C COMPUTE BUFFER ADDRESS S CLA CMA S TAD \IY0 S AND (0017 /LOW 16 LINES S CLL BSW; RTL /*256 MAGNITUDE S DCA LADDR1# C C COMPUTE BUFFER FIELD S CLA CMA S TAD \IY0 S RAR /DIVIDE BY 2 S AND (0030 /0:15==>3 C /16:31==>4 C /32:47==>5 C /48:63==>6 S TAD (6231 /BUFFER FIELD S DCA LADDR1 /CDF 30 BUFFER FIELD C C READ 1 LINE S CALL 2,T3BUF S LADDR1, ARG LADDR1 /WILL BE LOAD W/POINTER S ARG (2 /READ 1 LINE INTO BUFFER 1401 CONTINUE C C COPY FORWARD (N/2) LINES DO 1405 IY0=2,N2P1 IY=(KY1-1)+(IY0-1) C COMPUTE BUFFER ADDRESS S CLA CMA S TAD \IY0 S AND (0017 /LOW 16 LINES S CLL BSW; RTL /*256 MAGNITUDE S DCA LADDR2# C C COMPUTE BUFFER FIELD S CLA CMA S TAD \IY0 S RAR /DIVIDE BY 2 S AND (0030 /0:15==>3 C /16:31==>4 C /32:47==>5 C /48:63==>6 S TAD (6231 /BUFFER FIELD S DCA LADDR2 /CDF 30 BUFFER FIELD C C READ 1 LINE S CALL 2,T3BUF S LADDR2, ARG LADDR2 /WILL BE LOAD W/POINTER S ARG (2 /READ 1 LINE INTO BUFFER 1405 CONTINUE C C SET RING PTR TO FRONT OF BUFFER LINE -((N/2)-1) IRING=0 IY=IYSV S JMP RLOADBUFF C C C [2] READ IN LINE IY+N/2 C IF IY > 256 C THEN USE (255-(IY-255)) 1402 IY=IY+N2 IF(IY-255)1404,1404,1403 1403 IY=255-(IY-255) C C C [3] LOAD LINE IY ==>LOC[FIELD(3+IRING/16),(IRING&'17)*256]. 1404 CONTINUE C*****DEBUG**** S 6344 S AND (0010 S SNA CLA S JMP \1994 WRITE(3,1993)IY1,IY,IRING 1993 FORMAT(' LOADBUF[3] IY1=',I5,', IY=',I5,', IRING=',I5) 1994 CONTINUE C********************** S TAD \IRING S CLL BSW;RTL /*256 S AND (0017 /LOW 16 LINES S DCA LADDR3# C C COMPUTE BUFFER FIELD S TAD \IRING S RAR /DIVIDE BY 2 S AND (0030 /0:15==>3 C /16:31==>4 C /32:47==>5 C /48:63==>6 S TAD (6231 /CDF 30 ,BUFFER FIELD S DCA LADDR3 S CALL 2,T3BUF S LADDR3, ARG LADDR3 S ARG (2 /READ LINE C C C [4] INCREMENT IRING MOD N IRING=IRING+1 S TAD \N S CIA S TAD \IRING S SMA CLA S DCA \IRING /ZERO IT IY=IYSV S JMP RLOADBUFF C*************************************************** C *SUBROUTINE L O O K U P C****************************************************** C C C LOOKUP THE GRAY VALUE IN (IXP,IYR). IXP IN [0:255] C AND IYR IN [1:N]. FIRST C MAP IXP TO [0:255]. RETURN THE RESULT IN IVAL C S CPAGE 3 SRLOOKUP, JMP I LOOKUP S LOOKUP, 0 /ENTRY C C C [1] MAP IXP TO 0:255 S TAD \IXP S SPA S CIA /X< 0 ==> MAKE > 0 S TAD (-D256 />256 TEST? S SMA S JMP XGT255 S TAD (D256 /X<256 S JMP SVKX S XGT255, CIA /-256-X S TAD (D766 /510+256 S SVKX, DCA \KX C C C [2] LOOKUP POINT IN FIELDS 3,4,5,6 C COMPUTE BUFFER FIELD S CLA CMA S TAD \IYR S RAR /DIVIDE BY 2 S AND (0030 /0:15==>3 C /16:31==>4 C /32:47==>5 C /48:63==>6 S TAD (6231 /CDF 30 S DCA LKCDF C S CLA CMA S TAD \IYR S AND (0017 /LOW 16 LINES S CLL BSW; RTL /*256 C S CPAGE 12 S TAD \KX /IN COMMON S DCA 7 SLKCDF, 6231 /CDF 60 /BUFFER FIELD S TADI 7 S 6211 /CDF COMMON S DCA \IVAL S JMP RLOOKUP C*************************************************** C *SUBROUTINE C O L S U M C****************************************************** C C C COMPUTE THE COLUMN SUM OF COLUMN IXP IN IC[1:2]. C S CPAGE 3 SRCOLSUM, JMP I COLSUM S COLSUM, 0 /ENTRY C C [1] ZERO DP COUNTER IC=0 S DCA \IC# C C C [2] SUM N COLUMNS DO 1040 IYR=1,N S JMS LOOKUP S CLA CLL S TAD \IC S TAD \IVAL S DCA \IC S SZL /IF LINK, THEN INCRENENT HIGH WORD S ISZ \IC# /S.P. OVF==>DP. INC S CLA 1040 CONTINUE S JMP RCOLSUM C*************************************************** C *SUBROUTINE A V G C****************************************************** C C C COMPUTE THE THE AVG OF THE 16X16 NGH OF IX CURRENT C LINE BUFFERS AND RETURN THE D.P. SUM IN IB[1:2]. NOTE: C IB SHOULD NOT BE DISTROYED AS IT IS USED ON THE NEXT C ITERATION. C THE AVERAGE IS RETURNED IN IA[1]. C S CPAGE 3 SRAVG, JMP I AVG S AVG, 0 /ENTRY C C [1] IF IX=0 THEN COMPUTE 16X16 IB[1:2]. IXSV=IX IF(IX)1420,1420,1421 C C C [1.1] COMPUTE INITIAL IB 1420 IB=0 S DCA \IB# DO 1421 IXPM1=1,N IXP=IXPM1-1 S JMS COLSUM C S SWAB /D.P. IB_IB+IC S CPAGE 11 S DCA \IZ /FORCE COMMON S DAD S \IB S DAD S \IC S DST S \IB S CLAMQ S SWBA 1421 CONTINUE GOTO 1423 C C C [2] COMPUTE INCREMENTAL SUM C ICOMPUTE: D.P. IB_IB+COLSUM(IX)-COLSUM(IX-N); 1422 IXP=IXSV-N S JMS COLSUM S SWAB S CPAGE 12 S DCA \IZ /FORCE COMMON S DAD S \IC S DCM S DAD S \IB S DST S \IB S CLAMQ S SWBA C IX=IXSV S JMS COLSUM S SWAB S CPAGE 11 S DCA \IZ /FORCE COMMON S DAD S \IC S DAD S \IB S DST S \IB S CLAMQ S SWBA C C C [3] COMPUTE IA[1]_IB[1:2]/NSQ S\1423, TAD \NSQ S DCA DVSR S TAD \IB S MQL S TAD \IB# C S CPAGE 2 S DVI S DVSR, 0 /WILL CONTAIN NSQ S CLA /ZERO REMAINDER S MQA /GET QUOTIENT S DCA \IA IX=IXSV S JMP RAVG C ************************************************************ C SUBROUTINE: T T Y C T L (INTERNAL) C ************************************************************ C S CPAGE 3 S RTTYC, JMP I TTYCTL S TTYCTL, 0000 /ENTRY C S KSF /ANYTHING TYPED S JMP NORMAL /NO, RETURN NORMALLY S KRB /GET TYPED CHARACTER S AND (0177 /TAKE CARE OF PARITY PROBLEMS S TAD (-17 /TEST FOR CTRL/O S SNA /SKIP IF NOT CTRL/O S JMP RTTYC /ABORT CALLING ROUTINE (ERROR RETURN) S TAD (-4 /TEST FOR CTRL/S [-17-4=-23(OCTAL)] S SZA CLA /SKIP IF CTRL/S S JMP NORMAL /NOT CTRL/O OR CTRL/S SO RETURN NORMALLY C S SLEEP,KSF /WAIT FOR CTRL/Q S JMP SLEEP /KEEP WAITING S KRB /READ CHARACTER S AND (0177 S TAD (-17 /IS IT A CTRL/O? S SNA /SKIP IF NOT S JMP RTTYC /YES, ABORT S TAD (-2 /TEST FOR CTRL/Q (-17-2=-21 OCTAL) S SZA CLA /SKIP IF SO S JMP SLEEP /NOPE, KEEP SLEEPING C S NORMAL,INC TTYCTL /INCREMENT RETURN ADDRESS FOR NORMAL RETURN S CLA /SAFETY VALVE S JMP RTTYC /RETURN C************** P A R A M E T E R S ************* S PBUF1, \IBUF1 S PBUF2, \IBUF2 S PBUF3, \IBUF3 S PBUF4, \IBUF4 S PI10, \I10 S BMTEXT, TEXT /BM/ END