; NINER
;---------------------------------------------------------------
;! Applies various 3x3 area operaters to an image.
;# TASK ANALYSIS
;-----------------------------------------------------------------------
;;  Copyright (C) 1995
;;  Associated Universities, Inc. Washington DC, USA.
;;
;;  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 Massachusetts Ave, Cambridge,
;;  MA 02139, USA.
;;
;;  Correspondence concerning AIPS should be addressed as follows:
;;         Internet email: aipsmail@nrao.edu.
;;         Postal address: AIPS Project Office
;;                         National Radio Astronomy Observatory
;;                         520 Edgemont Road
;;                         Charlottesville, VA 22903-2475 USA
;-----------------------------------------------------------------------
;---------------------------------------------------------------
NINER     LLLLLLLLLLLLUUUUUUUUUUUU CCCCCCCCCCCCCCCCCCCCCCCCCCCCC
NINER     Applies various 3x3 area operaters to an image.
INNAME                             Input image name (name)
INCLASS                            Input image name (class)
INSEQ             0.0     9999.0   Input image name (seq. #)
INDISK            0.0        9.0   Input image disk unit #
OUTNAME                            Output image name (name)
OUTCLASS                           Output image name (class)
OUTSEQ           -1.0     9999.0   Output image name (seq. #)
OUTDISK           0.0        9.0   Output image disk unit #.
BLC                                Bottom left corner of input
TRC                                Top right corner of input
OPCODE                             Operation code.
CPARM                              User supplied array
DPARM                              User supplied array
----------------------------------------------------------------
NINER
Task:  Task which applies various 3x3 area operators to images.
       Will handle real or integer input, blanking and data
       cubes.  It implements a number of area operators which
       work on the 3x3 matrix of pixels containing and
       surrounding each pixel in the input image.  The most
       unusual operator in the present version is OPCODE
       'SOBL' for the Sobel edge enhancement filter.
Adverbs:
  INNAME.....Input image name (name).       Standard defaults.
  INCLASS....Input image name (class).      Standard defaults.
  INSEQ......Input image name (seq. #).     0 => highest.
  INDISK.....Disk drive # of input image.   0 => any.
  OUTNAME....Output image name (name).      Standard defaults.
  OUTCLASS...Output image name (class).     Standard defaults.
  OUTSEQ.....Output image name (seq. #).    0 => highest unique.
  OUTDISK....Disk drive # of output image.  0 => highest disk
             number with sufficient space.
  BLC........Bottom right corner in input image of desired
             subimage.  Default is entire image.
  TRC........Top right corner in input image of desired
             subimage.  Default is entire image.
  OPCODE.....User specified operation code:
                'NINE' => forms a weighted sum for each data
                          point.  The result is a function of
                          the input data point and the eight
                          surrounding data points.
                                 | DATA(H-1) DATA(H) DATA(H+1) |
                          so for | DATA(I-1) DATA(I) DATA(I+1) |
                                 | DATA(J-1) DATA(J) DATA(J+1) |
                          (a 3x3 sub-window in the input image)
                          C = CPARM
                          and RESULT(I) = C(1)*DATA(H-1) +
                                          C(2)*DATA(H)
                                          + C(3)*DATA(H+1) +
                                          C(4)*DATA(I-1) + ...
                                          + C(9)*DATA(J+1) +
                                          DPARM(1)*DATA(I).
                          In addition, all indefinite values in
                          the input image are not used in
                          computing the result.
             Built-in gradient masks:
                'NORT' =>
                                 |  1  1  1 |
                                 |  1 -2  1 |
                                 | -1 -1 -1 |
                'NE'   =>
                                 |  1  1  1 |
                                 | -1 -2  1 |
                                 | -1 -1  1 |
                'EAST' =>
                                 | -1  1  1 |
                                 | -1 -2  1 |
                                 | -1  1  1 |
                'SE'   =>
                                 | -1 -1  1 |
                                 | -1 -2  1 |
                                 |  1  1  1 |
                'SOUT' =>
                                 | -1 -1 -1 |
                                 |  1 -2  1 |
                                 |  1  1  1 |
                'SW'   =>
                                 |  1 -1 -1 |
                                 |  1 -2 -1 |
                                 |  1  1  1 |
                'WEST' =>
                                 |  1  1 -1 |
                                 |  1 -2 -2 |
                                 |  1  1 -1 |
                'NW'   =>
                                 |  1  1  1 |
                                 |  1 -2 -1 |
                                 |  1 -1 -1 |
                'MSK1' =>
                                 |  0 -1  0 |
                                 | -1  4 -1 |
                                 |  0 -1  0 |
                'MSK2' =>
                                 | -1 -1 -1 |
                                 | -1  8 -1 |
                                 | -1 -1 -1 |
                'MSK3' =>
                                 |  1 -2  1 |
                                 | -2  4 -2 |
                                 |  1 -2  1 |
             Edge enhancement operators:
                'SOBL' => performs the 'Sobel' edge enhancement
                          operation on each data point.  The
                          operation is defined by
                          RESULT(I) = SQRT(X**2 + Y**2) +
                                        DPARM(1)*DATA(I).
                                 | DATA(H-1) DATA(H) DATA(H+1) |
                             for | DATA(I-1) DATA(I) DATA(I+1) |
                                 | DATA(J-1) DATA(J) DATA(J+1) |
                          (a 3x3 sub-window in the input image)
                          X=(DATA(H+1)+2*DATA(I+1)+DATA(J+1))
                            -(DATA(H-1)+2*DATA(I-1)+DATA(J-1))
                          Y=(DATA(H-1)+2*DATA(H)+DATA(H+1))-
                            (DATA(J-1)+2*DATA(J)+DATA(J+1))
                          (default).
                'KRSH' => performs the 'Kirsch' edge enhancement
                          operation on each data point.  The
                          operation is defined by
                          RESULT(I) =
                          max(1, max(abs(5*S(i)-3*T(i))))
                          as i runs from 1 to 8
                                 | DATA(1) DATA(2) DATA(3) |
                             for | DATA(8) DATA(9) DATA(4) |
                                 | DATA(7) DATA(6) DATA(5) |
                          (a 3x3 sub-window in the input image)
                          S(i)=DATA(i) + DATA(i+1) + DATA(i+2)
                          T(i)=DATA(i+3) + DATA(i+4) + DATA(i+5)
                               + DATA(i+6) + DATA(i+7)
                          (the subscripts are evaluated mod 8)
                'WALL' => performs the 'Wallis' edge enhancement
                          operation on each data point.  The
                          operation is defined as follows:
                                 | DATA(H-1) DATA(H) DATA(H+1) |
                             for | DATA(I-1) DATA(I) DATA(I+1) |
                                 | DATA(J-1) DATA(J) DATA(J+1) |
                          RESULT(I)=0.25*log((DATA(I)**4)/
                                      (DATA(H)*DATA(I+1)*DATA(J)
                                       *DATA(I-1)))
  CPARM......User specified array.  If OPCODE is 'NINE' CPARM(J)
             is the weight of the J'th element in the area
             operator function.  Otherwise, the array is fixed.
             (Also see OPCODE above)
  DPARM......User specified array. DPARM(1) is the weight of the
             input image in the computation of the output image.
             DPARM(2) specifies whether the row numbers should
             be output as the task is running (-1=> no,otherwise
             yes).
             (Also see OPCODE above)
----------------------------------------------------------------
NINER:  Task which applies various 3x3 filter operators to
        images.
DOCUMENTOR: Thad A. Polk/Don Wells NRAO.
RELATED PROGRAMS:  All AIPS image tasks.

                          PURPOSE

     NINER is designed to apply 3x3 filters to images. It uses
the 'scrolling buffer' concept with space for a 3-row buffer.
It provides a framework which allows the implementation of any
operator which depends only on the nine pixels of the 3x3
matrix surrounding and including a given pixel position. NINER
can handle up to 7 dimensional images in either integer or real
format and supports blanking.  A subimage of the input image
may be selected. The necessary control information can be
passed to the program via OPCODE, CPARM, and DPARM.

                DETAILS ABOUT SPECIFIC OPCODES

NINE: implements a simple 3x3 convolution. There is one
        peculiarity: if the convolving kernel has a non-zero
        sum, then blank pixels in the input are skipped and
        the sum of the weights is renormalized. But if the
        kernel has a sum of zero, then a blank anywhere in
        the 3x3 area will cause the output value to be blank.
NORT, NE, EAST, SE SOUT, SW, WEST, NW:
      these are special cases of NINE. The kernels are
        arranged so that they are directional derivative
        filters. The output picture resembles a landscape
        viewed from above with illumination at a glancing
        angle from some direction (the "craters on the moon"
        phenomenon).
MSK1, MSK2, MSK3:
      these are also special cases of NINE.  The kernels are
        arranged so that they emphasize point sources.
SOBL: This is the "Sobel" operator as described in the
        enhancement chapter of Pratt's "Digital Image
        Processing". It is a generalized gradient filter.
        It computes the square root of the sum of the squares
        of the directional derivatives in two orthogonal
        directions. Therefore, its output is >=0 everywhere.
        Bright regions in the output are places where the
        intensity "slope" of the image is large, regardless
        of the direction of the slope. This means that SOBL
        is sensitive to edges of all kinds in the image.
        Point sources tend to produce doughnuts. Lines
        (e.g., jets) tend to produce parallel ridges. Edges
        of regions tend to produce ridges which mark the
        loci of maximum gradient of the edges.
KRSH: This is the "Kirsch" operator also described in the
        enhancement chapter of Pratt's "Digital Image
        Processing".  It too is a generalized gradient filter.
        It computes the gradient in the eight possible
        directions and returns as a result the largest value.
        It produces results very similar to the Sobel
        operator but due to the great amount of computation
        involved it is relatively slow compared to the other
        operators.
WALL: This is the "Wallis" operator which also appears in
        Pratt's book.  It computes the base ten log of the
        normalized quotient of the center pixel over the
        product of the four adjacent pixels at each data point.
        It is sensitive to point sources in images.
