VisionX V4    Index Prev Next VisionX V4 Programmers Guide VisionX V4
Subsections

Image Processing VisionX V4 Programs

A number of tools are available to simplify the development of VisionX programs for image processing. An image is considered as a two dimensional array of pixels. In a VisionX file an image is represented by two elements: a bounding box which defines the image structure and a pixel vector which contains the data. A number of different base types for pixels are supported. In addition, each image may have multiple channels. For example, in a color image each pixel has three components (typically red, green and blue).

Within a program a the image programming tools create and maintain a data structure of type VisXimage_t to aid accessing the pixels in an image.

An image structure (including the two list elements) may be dynamically created in VisionX with the VXmakeimage function. The syntax for this function is:

 VXmakeimage( &<i-structure>,<type>,<bounding box>,<channels>);

Where i-structure is the structure to be initialized, type is the base type for the pixels, bounding box specifies the bounding box ( in floating point numbers ) and channels specifies the number of elements for each pixel.

For example, consider the following image declaration:

VisXimage_t foo;
   VXmakeimage ( &foo, VX_PFLOAT, (float){0, 5, 0, 8}, 3);
A (5 x 8) pixel image is created in which each pixel consists of three floating point numbers. The bounding box is specified by an array of four floating point numbers (xmin, xmax, ymin, ymax) and the number of channels is specified by an integer.

Pixel types:

The base pixel types supported by VisionX and their VisionX names are given in the table below:  
Name C-Type Ext Description
VX_PBYTE unsigned char .u most usual byte format
VX_PFLOAT float char .f 32-bit floating point
VX_PDOUBLE double .d 64-bit floating point
VX_PBIT unsigned char .b 1-bit (packed 8/byte)
VX_PCHAR char .c 8-bit signed integer
VX_PSHORT short .s 16-bit signed integer
VX_PINT int .i 32-bit signed integer
VX_PIDX unsigned char .u 8-bit color index

The Ext field specifies the element of the VisXimage data structure which will point to the two dimensional array.

Data Access:

VXmakeimage allocates memory for the image and creates a two dimensional array structure to conveniently access this structure. The following four structure elements are set by VXmakeimage:

.xlo the lowest defined x index
.xhi the highest defined x inde
.ylo the lowest defined y inde
.yhi the highest defined y inde

In addition, the extension corresponding to the pixel data type points to the two dimensional array.

For example, consider the previous (5 x 8) image declaration: All pixels in the image may be set to zero with the following program sequence:

{int i, j;
   for ( i = foo.ylo; y <= foo.yhi; i++ )
       for ( j = foo.xlo; x <= foo.xhi; j++ )
           foo.f[i][j] = 0.0;
}

The array must be referred to as foo.f since it was declared to be of type VX_PFLOAT. The values for the index limits for this example are as follows: foo.xlo = 0, foo.xhi = 14, foo.ylo = 0, and foo.yhi = 7. The x-range is three times the size of the bounding box since each pixel requires three consecutive floating point numbers. That is, the three components of the first pixel in the array are: foo.f[0][0], foo.f[0][1] and foo.f[0][2].

Writing a File:

The VXmakeimage function generates a VisionX list structure containing a bounding box element an image element; for multichannel images a channel specification element is also created. The list is located in the structure element foo.list; therefore the following program sequence could be used to write a file that contains our example image:
{ VisXfile_t fout;
       fout = VXopen("<file name>", 1);
       VXwrite(fout, foo.list);
       VXclose(fout);
}

Reading a File:

VisionX files may contain a large number of different types of elements; the function VXsetimage has been developed to construct an VisXimage structure to conveniently access an image if a pixel type element is found in the file. The syntax for this function is:

 VXsetimage ( &<i-structure>, <pixel-ptr>, <file-struct> );
Where pixel-ptr is a pointer to a pixel data element in a VisionX data list, and file-struct is the structure returned by the VXopen command.

For example, an image structure could be set up with the contents of an VisionX image file with the following program sequence:

VisXfile_t *ifile;
VisXelem_t *list, ptr;
VisXimage_t fie;

       ifile = VXopen("<filename>", 0);
       list  = VXread(ifile);
       if (VXNIL != (ptr = VXfind(list, VX_PBYTE))
           VXsetimage( &fie, ptr, ifile);
The function VXfind will locate the first element in the list of type VX_PBYTE (8-bit unsigned pixels); therfore, the given segment will only create a structure if a byte pixel image is located in the data list. (Note: you can use VXfindin for situations where more than one pixel type is possible). In addition to the array accessing structure elements, the following structure elements are set by VXsetimage.
.type    the pixel type
.chan    the number of channels
.bbx     the bounding box
.imitem  the item in the list where the image is located

Example Program:

A complete VisionX program that illustrates the use of the image structure tools is shown in Figure 2. This program reads a VisionX file and if a byte image is located in that file it generates an output image in which all the pixels have been converted from unsigned char to the short pixel format. Only, the new image is output; any other data items in the input file are ignored.

Figure 2: Example VisionX Program that uses image program tools  


/****************************************************************/
/* Example VisX4 program vimt                                   */
/*            Convert a byte image to a short image             */
/* Syntax:                                                      */
/*        vimt if=infile of=outfile                             */
/****************************************************************/

#include "VisXV4.h"          /* VisX structure include file     */
VisXfile_t *VXin,            /* input file structure            */
           *VXout;           /* output file structure           */
VisXelem_t *VXlist;          /* VisX data structure             */
VisXelem_t *vptr;            /* pixel element pointer           */
VXparam_t par[] =            /* command line structure          */
{
{    "if=",    0,   " input file vimt: convert byte to int"},
{    "of=",    0,   " output file "},
{     0,       0,    0} 
};
#define  IVAL   par[0].val
#define  OVAL   par[1].val

main(argc, argv)
int argc;
char *argv[];
{

VisXimage_t im;        /* input image structure  */
VisXimage_t xim;       /* output image structure */
int        i,j;        /* index counters         */

    VXparse(&argc, &argv, par);    /* parse the command line       */
    VXin  = VXopen(IVAL, 0);       /* open input file              */
    VXout = VXopen(OVAL, 1);       /* open the output file         */

    VXlist = VXread(VXin);         /* read file                    */
    if (VXNIL != (vptr = VXfind(VXlist, VX_PBYTE))){
      VXsetimage(&im, vptr, VXin); /*   initialize input structure */
      VXmakeimage(&xim, VX_PSHORT, im.bbx, im.chan);
                                   /*initialize output structure   */

      for (i = im.ylo; i <= im.yhi; i++)
        for (j = im.xlo; j <= im.xhi; j++)
             xim.s[i][j] = im.u[i][j];

      VXwrite(VXout, xim.list);    /* write data                   */
    }
    VXclose(VXin);                 /* close files                  */
    VXclose(VXout);
    exit(0);
}

The simple program presented in Figure 2 will work on simple files which just contain a single byte image. The following more advanced program segment shown in Figure 3 performs the same function but on a VisionX file of arbitrary complexity and length. Files may contain many different types of data, the new program will just replace the byte images with short images all other data elements will be maintained without modification. The revised program has the following features:

1.
The input file may contain multiple images; the file may also be organized in "frames" which will be read as a unit; files with a large number of images would overflow memory if they were read as a single unit with VXread.
2.
The new image replaces the old image in the data list then the list is written. In this way any non byte image information present in the file will be maintained.
3.
The image structures must be deallocated by VXresetimage to free memory associated with them before they are reused for the next image. The images in the file may have different dimensions.

Figure 3: Example program segment suitable for complex files  

    /*  Advanced vint program                     */
    /* initial code is same as that in Figure 2   */

VisXimage_t im;        /* input image structure  */
VisXimage_t xim;       /* output image structure */
int        i,j;        /* index counters         */
VisXelem_t *vptr;      /* data element pointer   */

    Vparse(&argc, &argv, par);     /* parse the command line       */
    VXin  = VXopen(IVAL, 0);       /* open input file              */
    VXout = VXopen(OVAL, 1);       /* open the output file         */

    while ((vptr = vxlist = VXreadframe(VXin)) != VXNIL){ /* read a frame   */ 
      VXfupdate(VXout, VXin);                    /* update global constants */
      while (VXNIL != (vptr = VXfind(vptr, VX_PBYTE))){ /*  each byte image */
         VXsetimage(&im, vptr, VXin);          /*initialize input structure */
         VXmakeimage(&xim, VX_PSHORT, im.bbx, im.chan); /* output structure */
         for (i = im.ylo; i <= im.yhi; i++)
            for (j = im.xlo; j <= im.xhi; j++)
                xim.s[i][j] = im.u[i][j];

         /* replace the old image data with the new image data */
         VXmovelem(vptr, xim.list->next);  /* just move data, bbx is same  */
         vptr = VXdelelem(vptr);
         VXresetimage(&im);             /* deallocate the image structures */
         VXresetimage(&xim);
      }
      VXwriteframe(VXout,vxlist);              /* write frame             */
      VXdellist(vxlist);                       /* delete the frame        */
    }
    VXclose(VXin);                 /* close files                  */
    VXclose(VXout);
    exit(0);
}


A. P. Reeves, © Copyright 1998-2012
11/12/2012