IPSDK  4_1_0_2
IPSDK : Image Processing Software Development Kit

Application used to demonstrate how to use a disk image. More...

Application used to demonstrate how to use a disk image.

Overview

This application demonstrates how to use a disk image during an IPSDK process toolchain. It uses an input TIFF file, copies the image in another disk image, automatically created by IPSDK , and saves the result in a given TIFF file.

Usage

The application can be called through a command line as follows:

   <application_exe_filename> [--inputImgFilePath <input_image_file_path>] [--outputImgFilePath <output_image_file_path>]
     
   Arguments:
      --inputImgFilePath  optional; specifies the name of the TIFF file, from
                          which the input image will be open; if not 
                          specified by the user, the input image is loaded from
                          file 
                          <DEV_ROOT>/data/Sample/images/Lena_510x509_UInt8.tif
                          
      --outputImgFilePath optional; specifies the name of the TIFF file, in
                          which the output image resulting from the 
                          calculation will be saved;
                          if not specified by the user, the output image is 
                          saved in file
                          <TEMPORARY_IPSDK_DIR>/Sample/copyFromDisk.tif

Source code documentation

The sequence of operations executed by this application is very similar to other samples.

We start by including all necessary header files:

// --- IPSDK includes
// ------------------
// used to initialize IPSDK environment
#include <IPSDKCore/Config/LibraryInitializer.h>
// used to extract the boundary from the input image
// used to manage exceptions possibly thrown by algoritms functions
#include <IPSDKBaseProcessing/Logger/IPSDKBaseProcessingException.h>
// used to catch exceptions potentially thrown by functions loadRTiffImageFile and saveTiffImageFile
#include <IPSDKImageFile/Logger/IPSDKImageFileException.h>
// used to read/write an image from/to a TIFF file:
// used to retrieve usual folders (IPSDK temporary folder, root development folder, etc.)
// used for disk image management
#include <IPSDKImage/Image/BaseImage.h>
#include <IPSDKImage/Image/Disk/DiskImage.h>
// used to display log messages
// --- third-party boost includes
// ------------------------------
// boost/filesystem/*: contains functions and classes providing facilities to
// manipulate files and directories, and associated paths
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
// boost/program_options/*: contains functions and classes used to manage and
// interpret arguments of command line
#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
// --- third-party log4cplus include
// ---------------------------------
// used to add console as output support of logs
#include <log4cplus/consoleappender.h>
// --- STL include
// ---------------
// for std::cout
#include <iostream>

In the main function body, we start by asking to display all the log messages generated by IPSDK libraries and by our application itself to the application console:

int
main(int argc, char* argv[])
{
// add console appender for application logs
log4cplus::SharedAppenderPtr pConsole(new log4cplus::ConsoleAppender);
log4cplus::Logger::getRoot().addAppender(pConsole);
log4cplus::Logger::getRoot().setLogLevel(log4cplus::INFO_LOG_LEVEL);

Next, we initialize the IPSDK environment:

// initialize IPSDK environment (first call to be done before calling any
// function or using any entity of IPSDK environment)
switch (initRes.getResult().value()) {
case ipsdk::core::eLibInitStatus::eLIS_Warn:
// IPSDK library is initialized but there were warnings;
// notify the user by displaying a message
break;
case ipsdk::core::eLibInitStatus::eLIS_Failed:
// IPSDK library initialization; notify the user and exit
return -1;
break;
default:
break;
}

Then we declare objects 'inImgFilePath' and 'outImgFilePath'.

// boost objects, used to store input and output images files paths
boost::filesystem::path inImgFilePath, outImgFilePath;

Paths are initialized from the command line thanks to the call of the "readCmdArguments" function:

// read program options from command line, and, if appropriate,
// initialize input and output images files paths
if(!readCmdArguments(argc, argv, inImgFilePath, outImgFilePath))
return -1;

By definition, a disk image is not loaded but only open. Once the IPSDK environment is correctly initialized, we open our input image from the associated TIFF file, by calling the function ipsdk::image::file::openTiffImageFile instead of ipsdk::image::file::loadTiffImageFile.

// declare the variable that will contain the input image, loaded from
// RAW file
try {
// read input image from specified path
pInImg = openTiffImageFile(inImgFilePath);
} catch(const image::file::IPSDKImageFileException& e) {
// loadRawImageFile function threw an exception; display error log
// message
% inImgFilePath.string() % e.getMsg());
// clear IPSDK environment features; should be called before exiting
// program
// quit the application with an exit code indicating an error
return -1;
}

Please, note that it is also possible to open a RAW image with ipsdk::image::file::openRawImageFile

The image can then be processed as a classical image :

// declare the variable that will contain the output image, resulting from
// boundary extraction
ImagePtr pOutImg;
try {
// compute boundary image
pOutImg = ipsdk::imaproc::util::copyImg(pInImg);
} catch(const processor::IPSDKBaseProcessingException& e) {
// one of the 2 previous function calls
% e.getMsg());
// clear IPSDK environment features; should be called before exiting
// program
// quit the application with an exit code indicating an error
return -1;
}

We enclose the function call by a try/catch statement to properly manage the failures.

It is possible to check if the output image is a disk image or not :

const ipBool bIsDiskImage = pOutImg->isDiskImage();

It is also possible to modify a single value directly in the file. In the following example, we set the intensity of the very first pixel (x = y = z = c = t = 0) to 255 :

if (bIsDiskImage) {
DiskImage* pDiskImage = static_cast<DiskImage*>(pOutImg.get());
BoolResult bRes = pDiskImage->writePixel(255, 0, 0);
if (!bRes.getResult()) {
% bRes.getMsg());
// clear IPSDK environment features; should be called before exiting
// program
// quit the application with an exit code indicating an error
return -1;
}
}

It can be usefull to extract a slice, a channel or a frame from the disk image, or at least a subsample of this slice. It is required for instance for vizualization purpose. In that case, the extracted data is stored as a classical memory image, since it is supposed to contain much less data and therefore fit in memory. The slice coordinate (z, c, t), the size of the new memory image, its offset and the stride (i.e. the step between 2 extracted pixels) must be provided:

ImagePtr pPlanImg;
try {
pPlanImg = pInImg->loadPlan(z, 0, 0, outSizeX, outSizeY, offsetX, offsetY, stride, stride);
}
catch (const processor::IPSDKBaseProcessingException& e) {
// one of the 2 previous function calls
% e.getMsg());
// clear IPSDK environment features; should be called before exiting
// program
// quit the application with an exit code indicating an error
return -1;
}

Finally, keep in mind that the file is removed when the program exits the image scope, such as the end of the function or terminating the program. This means that the image still need to be saved in a RAW or TIFF file.

try {
// save the resulting image in specified path
ipsdk::image::file::saveTiffImageFile(outImgFilePath, pOutImg);
} catch(const image::file::IPSDKImageFileException& e) {
% outImgFilePath % e.getMsg());
// clear IPSDK environment features; should be called before exiting
// program
// quit the application with an exit code indicating an error
return -1;
}

To manually remove the disk file, simply set the variable to none: pOutImg = 0.

Finally, the program cleans the IPSDK environment and exitings:

// clearing IPSDK environment features; should be called before exiting
// program

See the full source listing