Vgrid Manual

Next:   [Index]

This manual is for Vgrid (version 1.0, 21 July 2021).

Copyright © 2020, 2021 Sonia Diaz Pacheco.

This manual is free documentation: you have unlimited permission to copy, distribute, and modify it.

Next:   [Index]

1 Introduction

Vgrid is a virtual grid program for radiology that enhances the contrast of radiographs by means of the algorithm ‘Adaptive Windowing’.

Vgrid reads images in PNG greyscale or RGB format and saves images in PNG format using by default the same bit depth as the input image. Vgrid accepts images with a bit depth of 8 or 16 bits.

If no file names are specified, vgrid reads an image from standard input and writes the result to standard output.

Next: , Previous:   [Index]

2 Invoking vgrid

The format for running vgrid is:

vgrid [options] [files]

If no options are given, vgrid produces an image with contrast improved by means of ‘Adaptive Windowing’.

A hyphen ‘-’ used as a file argument means standard input. It can be mixed with other files and is read just once, the first time it appears in the command line.

vgrid supports the following options:


Print an informative help message describing the options and exit.


Print the version number of vgrid on the standard output and exit. This version number should be included in all bug reports.

-b n

Force the bit depth of the images produced (8 or 16). By default vgrid produces an image with the same bith depth as the input image. Changing the bit depth of the image does not alter the fraction of the available range of values really used in the output image. (See ‘--expand’).


Write the image produced to standard output. ‘-c’ overrides ‘-o’.


Copy input to output, perhaps performing some changes like inversion ‘-i’, expansion ‘-e’, or bit depth ‘-b’.


Expand real pixel values when writing the output image so that they fill the full range of possible values for the output bit depth. ‘--expand’ does not change the bit depth of the image. It simply expands the values to fill the whole available range at any bit depth being used. (See ‘--bit-depth’).


Force overwrite of output files.


Invert image levels (white <—> black) when reading an image. Each pixel value ‘val’ is replaced by ‘maxval - val, where maxval is the maximum possible pixel value of the input PNG image (255 or 65535). ‘--invert’ has no effect with ‘--raw-copy’.


Show image information from the PNG header. If ‘-v’ is also specified, show statistics about the image data (min, max, range, mean, and mode).


Process color (RGB) images. If this option is not specified, vgrid saves the image in greyscale format.

-m radius

Run the image produced by the algorithm (or by ‘--copy’) through a median filter over a square area of side 2 * radius + 1 around each pixel. The median is calculated only among the pixels in the image. The image is not extended with zeros or other values. The central element (median) of incomplete neighborhoods around the border pixels is floor(neighborhood_size - 1 / 2).

-o file

If ‘-c’ has not been also specified, write the image produced to ‘file’. ‘-o - is equivalent to ‘-c’.

-p file

Compare each PNG image given in the command line with file and print status (identical, equivalent, or differ). ‘equivalent’ means that no pixel in the image differs by more than 1 from the corresponding pixel in file. Exit with status 1 if any image differs from file.


Quiet operation. Suppress all messages.

-R width,height,bit-depth,channels

Convert raw pixel data to PNG output. The name of the output file is constructed by removing an optional extension ‘.raw’ and appending a extension ‘.png’, instead of inserting ‘_vg’ before the extension as other operations do. Options like ‘--bit-depth’, ‘--expand’, or ‘--invert’ have no effect when doing a raw copy. Use, for example, ‘vgrid -c --raw-copy ... | vgrid -Ci ... to produce an inverted image.

-s suf

Build the output file name by inserting the suffix suf before the extension of file instead of inserting the default ‘_vg’.

-S file

Subtract file from each image specified in the command line pixel per pixel and write each output to its own PNG file. If the bit depth of the images differ, the deeper image is scaled down to match the bit depth of the shallower image before performing the subtraction. In the resulting greyscale image, the 0 is assigned the grey tone in the middle (( maxval + 1 ) / 2), negative values have darker tones, and positive values have brighter tones. The differences are truncated to the range [-( maxval + 1 ) / 2, ( maxval - 1 ) / 2].

This option may be useful to compare the improvements of different processings respect to the original image. This option does not work with color images.


Run self-tests (debug).


Verbose mode. Further -v’s (up to 4) increase the verbosity level.

-Z scale

Produce a reduced image of size 1/scale of the original size per side. Before performing reduction, it discards up to floor(scale/2) pixels at each image border to make image size a multiple of scale. Averages each cluster of scale x scale pixels into one pixel. ‘--expand’ is recommended: ‘vgrid -Z scale -b 8 -e.

Exit status: 0 for a normal exit, 1 for environmental problems (file not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or invalid input file, 3 for an internal consistency error (e.g. bug) which caused vgrid to panic.

3 Algorithm

Adaptive Windowing is based exclusively on linear transformations of pixel values so that the contrast in the neighborhood of each pixel is expanded until it fills the full range of values available. The effect is similar to passing a "contrast magnifier" over the image.

Human vision is very sensitive to local contrast variations, but it is practically insensitive to both absolute luminance and variations of luminance between areas far apart. In order to take advantage of this circumstance, and maximize local contrast around each point, adaptive windowing shifts the average luminosity of each input area to the center of the range of output values. For this it calculates the avarage value of all pixels in each area (local mean) and divides the pixels inside the area in two ranges: "bright", including all the pixels with value larger than or equal to the local mean, and "dark", including all the pixels with value smaller than the local mean. The values of the pixels from each range are then expanded separately around the mean so that each input subrange fills half of the range of output values.

The steps of the algorithm are:

The image is first divided into aproximately square areas. Then three values (mean, minimum, and maximum) are calculated for each area. These values are then adjusted to those of the surrounding areas so as to reduce border artefacts.

For each pixel, a local average and two local ranges (bright and dark) are found using bilinear interpolation among the four areas surrounding the pixel.

The local range (window) of each pixel with value larger or equal to the local average (bright pixel), is expanded until it fills the upper half of the output space (from (maxval+1)/2 to maxval). The local range of each pixel with value smaller than the local average (dark pixel), is expanded until it fills the lower half of the output space (from 0 to (maxval+1)/2-1).

In order to reduce artefacts even further, several images processed using different numbers of areas are averaged. Optionally, the resulting image may be passed through a median filter to reduce the granular aspect of some areas caused by the amplification of noise.

Next: , Previous:   [Index]

4 A small tutorial with examples

Example 1: Process the image ‘file.png’ with Adaptive Windowing and write the output to the file ‘file_vg.png’.

vgrid file.png

Example 2: Like example 1 but writing the result as an 8 bit PNG image even if the input is 16 bit.

vgrid -b8 file.png

Example 3: Like example 1 but reading the image from standard input and writing the result to standard output.

vgrid [options] < infile.png > outfile.png

Example 4: Create the PNG image ‘file.png’ of size 2828 x 2320 pixels, 16-bit greyscale, from the corresponding raw data file.

vgrid --raw-copy=2828,2320,16,1 file.raw

Example 5: Create a reduced PNG image ‘reduced.png’ with sides 8 times smaller than the original PNG image ‘file.png’. The range of pixel values of the reduced image is expanded to fill the whole 8-bit output range.

vgrid --reduce=8 --bit-depth=8 --expand file.png -o reduced.png

5 Reporting bugs

There are probably bugs in vgrid. There are certainly errors and omissions in this manual. If you report them, they will get fixed. If you don’t, no one will ever know about them and they will remain unfixed for all eternity, if not longer.

If you find a bug in vgrid, please send electronic mail to Include the version number, which you can find by running ‘vgrid --version.

Previous:   [Index]

Concept index

Jump to:   A   B   E   G   I   O   U   V  
Index Entry  Section

algorithm: Algorithm

bugs: Problems

examples: Examples

getting help: Problems

introduction: Introduction
invoking: Invoking vgrid

options: Invoking vgrid

usage: Invoking vgrid

version: Invoking vgrid

Jump to:   A   B   E   G   I   O   U   V