A set of classes to represent and manipulate 3D images
The core class is vil3d_image_view<T> which gives a view of an image in memory. The only way to get at the pixel data in an image is through a vil3d_image_view<T>.
The vil3d_image_view<T> represents a view of a multi-plane image of given type. A pointer is stored to the top-left pixel in the first plane of the image (top_left_ptr()) and integers indicating how to get to neighbours in the i (istep()), j (jstep()), k (kstep()) and plane (planestep()) directions.
Since the vil3d_image_view<T> is a `view' of the actual image data, copying one only copies the `view', not the image data itself - you get two views looking at the same chunk of memory. Some cunning smart pointer stuff is used to ensure that the actual data remains as long as a valid view is looking at it. (Note that this may not always be the case, since the view can be of a chunk of memory that the view does not have direct control of, such as a video buffer). This view copying will work between different types of view if it is possible to reconfigure the view very cheaply. If you wish to copy the image data itself, then use the vil3d_copy_deep(src_im) function. This copies the raw data into a newly created space, and returns a new view of it. Alternatively, use the method dest_im.deep_copy(src_im), or the function vil3d_copy_reformat(src_im, dest_im).
Example of loading, copying then processing:
vil3d_image_view<vxl_byte> image; image = vil3d_load("test_image.jpg"); vil3d_image_view<vxl_byte> image2 = vil3d_copy_deep(image); my_invert_image(image2); vil3d_save(image2,"output_image.jpg");
Example of creating an image in memory
unsigned ni=256; unsigned nj=256; unsigned nk=256; unsigned nplanes=3; vil3d_image_view<vxl_byte> image(ni,nj,nk,nplanes); for (unsigned p=0;p<nplanes;++p) for (unsigned k=0;k<nk;++k) for (unsigned j=0;j<nj;++j) for (unsigned i=0;i<ni;++i) image(i,j,k,p) = vxl_byte(i+j+k+p);
Example of creating an image in memory, using pointer arithmetic
unsigned ni=256; unsigned nj=256; unsigned nk=256; unsigned nplanes=3; vil3d_image_view<vxl_byte> image(ni,nj,nk,nplanes); vxl_byte* plane = image.top_left_ptr(); for (unsigned p=0;p<nplanes;++p,plane += image.planestep()) { vxl_byte* slice = plane; for (unsigned k=0;k<nk;++k,slice += image.kstep()) { vxl_byte* row = slice; for (unsigned j=0;j<nj;++j,row += image.jstep()) { vxl_byte* pixel = row; for (unsigned i=0;i<ni;++i,pixel+=image.istep()) *pixel = vxl_byte(i+10*j+3*k+100*p); } } }
When one resizes (using set_size) a vil3d_image_view<T> the view disconnects from the data (which may then be deleted if no other views are connected), allocates a new chunk of memory for the new image and sets the view to look at it.
Note that if the set_size does not change the image size, then nothing is done and the view remains unchanged.
There are a variety of ways one can view the same data, allowing one to appear to change the data simply by changing ones view of it.
For instance,
A variety of useful functions are provided:
Morphological functions (using vil3d_structuring_element)