MLx Home | MLx menu | MLx buttons | Widgets | Index | What's New

The pixel operations are available via the buttons to the left of the image button window. Use the option key when selecting an operation to get a brief description.

- Adjust...
- Edit...
- Make Blank Image
- Fill rectangle
- Fill array random
- Fill array random%
- Paste Image
- Draw Scale

- Arithmetic...
- Transform...
- Filter...

Makes a new image with the horizontal or vertical dimension adjusted accordingly. Pixel replication or nearest interpolation is used. For example, horizontal zooming with a factor of .6666 will make the image 2/3 as wide as the original. If the original aspect ratio was 1:1, the aspect ratio of the new image is 2:3.

Copies one image into another. Handy for putting a border around an image.

The receiving image must be larger than the image being copied. The default is to center the copied image. If the image to be copied is exactly the same as the receiving image, use the Duplicate button.

Flips images (gray scale or RGB color) horizontally or vertically (much like Adobe Photoshop or NIH Image. Done in place, ie. the original data is changed.

These operations may be useful when comparing light micrographs (which are often flipped) with electron micrographs and maps.

**Box Difference** top

Resulting image is difference of mean filters with kernels of differing radii. Good for finding spots. Square areas with edge = 1 + 2 * radius.

This makes a new array that is all black (zeros.) Use the option of (unsigned-byte 8) for and array that is used for display, such as a black channel of an RGB (color) overlay.

**Mean** (filter) top

This is a variation of the box mean filter that preserves the image size by cropping the kernal at the edges as appropriate, ie. at the corners, the kernal will be about 1/4 the normal size, and at the very edges, about 1/2 the normal size. The visual effect of this is not apparent. Lots of image area is preserved in this way.

The box filtering algorithm is from: M. J. McDonnell, Computer Graphics and Image Processing 17:65-70 (81)

This filter is especially fast for large kernels. On a Power Mac, 150 Mhz, both native code, 512x512 gray level image, 63x63 kernel: NIH Image (using a convolution - kernel has all 1's) took 56 seconds. This mean filter took 4 seconds for an integer result (truncated), ten seconds or so for a real result. Note - the convolution operation used in NIH Image is much more flexible than necessary - doing a multiply at every kernel position for every pixel, hence it is much slower. I do not know a faster way in NIH Image to smooth with a large kernel. NIH Image does not preserve the edges in the filtered image.

Output array type is input array type, unless real arithmetic is used, then output array type is double-float.

Clip reduces the range of pixel values of an image. Pixels below the minimum value are set to the minimum value, and pixels above the maximum value are set to the maximum value. Pixel values between the minimum and maximum are not changed.

Clip is useful for display of deviation images, for removing negative (or positive) values from an image and for removing outliers. {note: The MLx - scale - % outliers removes the outliers only for scaling. The scaled array is affected but not the original array.}

Similar to real ratio except that the quotient is zero when either the numerator or denominator are below their respective limits.

This is useful for removing areas from images that have very low (integer) values of numerator or denominator, and thus unreliable ratio values.

Input: a mask (a thresholded image array) Output: an integer, real or complex array

This takes the Euclidian Distance map, according to the algorithm originally developed by Danielsson: Per-Erik Danielsson, Computer Graphics and Image Processing 14:227-248(1980).

The range map values are coordinates (complex values as (x iy) ) giving the x and y distances to the nearest point on the boundary. These are stored as complex valued pixels. The abs function is used to transform these into the radial distance, which is how the distance map is usually used.

The floor of the pixel values multiplied by an optional scale factor is used to give the byte values for display. These values are generally adequate for further analysis. There is an option to give the real values for the distances if more precision is needed. Direction of gradient. The pixel values are the direction of the gradient, scaled for display from 0-255 rather than 0-360 degrees. This type of image is best displayed with the directional palette, where the apparent direction of illumination can be chosen with the mouse. Use the {mlx - false color - directional palette} menu.

**DOG** - Direction of Gradient
top

This display is useful for looking at features with low contrast in the presence of features with high contrast. It can detect changes in the texture of the background of images. Usually, I believe that for small features, or features with sharp edges, if the DOG does not make them visible, nothing will.

The direction of gradient display is strikingly similar to the LEICA Hoffman Modulation Contrast - see add in Microscopy and Analysis, July 1995, Issue 13, p.51.

Error image pixel value: 100 / square root of original pixel value.

This assumes Poisson statistics, and is N/N.

For sticking a constant value into a rectangular region. Mostly used to make arrays or masks for testing algorithms.

Makes a noisy blank image - fills the array with random numbers. Flat distribution, selected limits.

Azriel Rosenfeld Gradient. The advantages of this gradient are that it is fast and that the resulting values are confined to the range of the image values (if they are all positive integers). The (magnitude of the) gradient is the maximum of the absolute values of the difference between the lower and upper neighboring pixels, and the left and right neighboring pixels.

See Rosenfeld, A. and Kak, A., "DIGITAL PICTURE PROCESSING, 2nd Edition, Vol. II", Academic Press, N.Y. 1992

An integer quotient from two integer (16 bit) images. Fast, but loose decimal part of the quotient, of course.

Subtract one integer image from another. Fast.

**Invert Pixel values **top

Subtract all values from max value (usually 255). Image appears as a 'negative' in the photographic sense.

The Linear Hough Transform maps straight line segments into points.

This function works on masks - where the pixels that are parts of lines or edges are white (1) and the rest is black (0).

The mapping is performed by mapping each line pixel into a sinusoid: rho = x * cos(theta) + y * sin(theta) in (theta, rho) space. These sinusoids are accumulated in the Hough array. All sinusoids of pixels that fall in a straight line in image space will overlap within a very small region, resulting in a dot or blob of high intensity (many curves overlap, ie. many pixels in the image are represented) with a skirt of low intensity.

The a dot in the Hough array at (theta, rho) corresponds to pixels lying on the straight line that is rho pixels from the center of the image. Theta is the angle of inclination (from the positive x axis) of the perpendicular to the line.

#| Adaptation from Lispix code on VAX. ;1JUN94

Image space: x,y. Origin (0,0) at upper left. Image need NOT be square. Image is BINARY, same as for the blobber. (?? Option - gray level image.)

Hough space: theta, rho. 0= theta 180°, or 0- radians. -d rho d , d is half the diagonal distance to corner of image, pixels, (Euclidian)

For each non zero point in the image mask (x,y): rho = x * cos(theta) + y * sin(theta) Where theta goes through its range of values, rho determined by geometry to lie within range above.

Time saving look up table schemes: let Image by X pixels on a side, and theta have T values. 1. cos(theta) and sin(theta). -> 2T values stored. 2. rho*cos(theta) and rho*sin(theta) -> 2TX values stored.

If there is one full length line in the image, need XT calculations. scheme 2 probably best.

References:

Charles R. Dyer, "Gauge Inspection Using Hough Transforms", IEEE Trans. on Pattern Analysis and Machine Intelligence PAMI-5(6):621-623 (1983)

Russ, John C., Bright, David S. , Russ, J. Christian, and Hare, Thomas M., "Application of the Hough Transform to Electron Diffraction Patterns", Jour. of Computer Assisted Micro. 1(1):3-37 (1989)

If image is N x M, center is (ceiling N 2), (ceiling M 2)

The median filter is similar to the mean filter in that the image size is preserved by using a reduced kernel near the edges and corners. The pixel value (of the new image) is the median pixel value of the kernel. The kernel is a square with radius r - the edge size is 2*r + 1. In other words, a radius of 2 gives a 5x5 kernel, with 25 pixel values inside it. The median is pixel number 12 (starting at zero), after the values are sorted by intensity.

The LISP code is different from the following fortran code, and does
a sort for each pixel. That makes it slower than the following algorithm,
but the length of code is 10x shorter. `FORTRAN version: `

Median Filter code listing.

General real array operation. It is slow, but will do lots of things.

Takes the ratio of two arrays, forcing the result to be a real number. (If both the numerator and denominator arrays have integer values, LISP gives the results as integers or as rational numbers, when necessary. When arithmetic is continued using integers and rational numbers (exact arithmetic - this is desirable in other contexts), the size of the numerators and denominators grow rapidly and calculations slow down. The sizes of the numerator and denominator are not bounded, as LISP also has a BIGNUM capability - where arithmetic can be done with arbitrarily large integers (also desirable in other contexts, but not here).

Note that ratio images often have outliers, and thus need to be scaled properly before detail becomes visible. See scaling.

Input pixel values need not be integer.

Works on two byte images. Some computers write the high byte first, some the low byte first. If your image looks 'bit sliced' or 'solarized' when read from a file from another machine, perhaps the bytes need reversing. This operation is done in place because the reversed bytes version of the image is useless, except to show a strange bit-sliced (intensity wrap around) rendition that shows detail in the background. The direction of gradient is more useful for that:

Scales an image to (unsigned-byte 8) - 0 - 255. The image array will be scaled, and be like the scaled image array for the window.

This operates on the image data. Use the scale button for (temporary) scaling for display.

Scales an image to (unsigned-byte 16) - 0 - 65536.

Shrink top

Reduces size of image (decimation). Pixels are summed. For example, if the shrink factor is 2, then new(0, 0) = old(0, 0) + old(1, 0) + old(0, 1) + old(1, 1), and new(i j) = old(2i-1, 2j-1) + old(2i, 2j-1) + old(2i-1,2j) + old(2i,2j).

Use integer shrink factors. (For non integral factors, see aspect_ratio pixel op.)

Shrink is useful if the image is over sampled (is blurry), or has noise that needs averaging.

Shrink (used to be shrink sum)

gives integer values, but the range of values will of course be greater than the original image. The array element type is expanded to allow for this. (In other words, if the input array has element type (unsigned-byte 8) or bytes, the summed pixels are likely to exceed 255, and therefore not fit into this element type. If a byte array is desired, use the {MLx - Pixel Array Ops - Scale to Byte} command.

(shrink average has been eliminated).

Takes the log of an image. Double-float (real) result.

Different computer languages write the arrays row by row, or collumn by collumn. Transposing makes the image flipped along the upper left - lower right diagonal Xij->Xji, and the dimmensions of the array are reversed. The transpose function transposes the images again, so that they appear properly.

Both gray level and RGB images can be transposed. (2/97). Note that more than one image can be transposed at once.

```
c 29-NOV-84 DSB Median Filter c Algorithm from Huang, Thomas S.,
IEEE Trans on Acoustics, c Speech, and Signal Processing, ASSP-27 (no.1):13-18
(1979) c Also adaped from sliding smooth, DSB. c c Algorithm is as follows
(for one scan line):
```

```
c 1. Get histogram for 1st window, median and ltmdn. c (ltmdn is
# pixels with gray level less than median) c a. mdn is median of this window.
```

```
c 2. For next window: delete left collumn and add right collumn,
c updating the histogram and ltmdn. c a. If glevel mdn then c decrement
ltmdn if on left collumn. c see code for rest of this.
```

```
c b. Now, ltmdn has # pixels in current window that have c gray
level less than median of previous window.
```

```
c 3. Update mdn to current window. let th = int(half # pixels c
in window) c a. if ltmdn > th then c 1. mdn = mdn - 1 c 2. ltmdn = ltmdn
- hist_array(mdn) c 3. stop when ltmdn = th c b. else, while ltmdn + hist_array
(mdn) = th : c 1. ltmdn = ltmdn + hist_array(mdn) c 2. mdn = mdn + 1
```

`subroutine median_filter`

`th = int( (2*W+1)**2 / 2)`

`c&&&--------------------- first window on line ----------------------`

```
DO I = hist_lo_lim, hist_hi_lim !initialize HIST_ARRAY(I)=0 !hist
END DO
```

`I = S_BDR(1) !set index for 1st window`

```
c ... get histogram ... min_glevel = hist_hi_lim DO L = J-W, J+W
DO K = I-W, I+W glevel = pix(k,l,in1) min_glevel = min(min_glevel,glevel)
hist_array(glevel)=hist_array(glevel)+1 END DO END DO
```

```
c ... get median and ltmdn idum = min_glevel ltmdn = hist_array(idum)
DO while (ltmdn.lt.(th + 1)) ! ltmdn .lt. # of median idum=idum+1 ltmdn
= ltmdn + hist_array(idum) end do mdn = idum ltmdn = ltmdn - hist_array(idum)
!loop done once to often. c ltmdn is # strictly less than median pix(i,j,out1)=mdn
```

`c---------------- succeeding windows on line -------------------------`

```
DO I = S_BDR(1)+1,S_BDR(3) DO K = J-W,J+W l_glev= PIX(I-W-1,K,IN1)
r_glev = PIX(I+W,K,IN1) ! update hist hist_array(l_glev) = hist_array(l_glev)
- 1 hist_array(r_glev) = hist_array(r_glev) + 1
```

```
if (l_glev.lt.mdn) ltmdn = ltmdn - 1 if (r_glev.lt.mdn) ltmdn =
ltmdn + 1
```

`END DO`

```
c ... end updating hist and ltmdn ... c ... now, have to find the
new median ...
```

```
if (ltmdn.gt.th) then !median has decreased do while (ltmdn.gt.th)
mdn = mdn - 1 ltmdn = ltmdn - hist_array(mdn) end do else !median has not
decreased do while ( (ltmdn + hist_array(mdn)).le.th) ltmdn = ltmdn + hist_array(mdn)
mdn = mdn + 1 end do end if
```

`pix(i,j,out1) = mdn`

`END DO END DO`

`RETURN end`