Image Processing VisionX V4 ProgramsA 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:
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:
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:
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 |