IPSDK  4_1_0_2
IPSDK : Image Processing Software Development Kit

module demonstrating the equalization of an image More...

module demonstrating the equalization of an image

Overview

This application equalizes an input image loaded from a given input TIFF file, and saves the result in a given TIFF file.

See also
2d equalization algorithm

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>] [--outImgMin <min_value>] [--outImgMax <max_value>]
     
   Arguments:
      --inputImgFilePath  optional; specifies the name of the TIFF file, from
                          which the input image will be loaded; if not 
                          specified by the user, the input image is loaded from
                          file 
                          <DEV_ROOT>/data/Sample/images/Lena_RGB_510x509_UInt8.tif
                          
      --outputImgFilePath optional; specifies the name of the TIFF file, in
                          which the output image resulting from the 
                          computation of the lightness will be saved;
                          if not specified by the user, the output image is 
                          saved in file
                          <TEMPORARY_IPSDK_DIR>/Sample/lightness.tif
                          
      --outImgMin         optional (default value=0.0); expected mininum of output
                          image
      
      --outImgMax         optional (default value = 255.0); expected maximum of
                          output image

Here is a snapshot of default input image used by the application and of corresponding output image when application is launched without any argument:

Sample_HistogramEqualization.png

Source code documentation

The sequence of operations executed in this application is very similar to what is done in Lightness sample application:

Start by including all the necessary header files:

// --- IPSDK includes
// ------------------
// used to initialize IPSDK environment
#include <IPSDKCore/Config/LibraryInitializer.h>
// used to equalize input image
// used to manage exceptions possibly thrown by algoritms functions
#include <IPSDKBaseProcessing/Logger/IPSDKBaseProcessingException.h>
// used to catch exceptions potentially thrown by functions loadTiffImageFile 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 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 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
% initRes.getMsg());
break;
case ipsdk::core::eLibInitStatus::eLIS_Failed:
// IPSDK library initialization; notify the user and exit
% initRes.getMsg());
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;

We also declare 2 variables, that will respectively store the expected minimal and maximal pixel values of output image:

// variable storing expected range of output image
ipsdk::ipReal64 fOutImgMin, fOutImgMax;

Paths and output image range values are updated from the command line, by calling function "readCmdArguments":

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

And we load our input image from the associated TIFF file:

// declare the variable that will contain the input image, loaded from
// TIFF file
try {
// read input image from specified path
pInImg = ipsdk::image::file::loadTiffImageFile(inImgFilePath);
} catch(const image::file::IPSDKImageFileException& e) {
// loadTiffImageFile 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;
}

Once our input image is loaded and the expected output image dynamic range is initialized, we equalize the input image by calling the function "ipsdk::imaproc::itrans::equalizeImg". "equalizeImg" function requires as arguments an input image, of type ImagePtr, and an expected output image dynamic range, of type RangePtr (that is a typedef for boost::shared_ptr<util::Range>). So we create a variable pInOutputRange, of type RangePtr, that we allocate through the call to "boost::make_shared<util::Range>()" and that we initialize thanks to the 2 successive calls to "pInOutputRange->setValue<util::Range::Min>(fOutImgMin);" and "pInOutputRange->setValue<util::Range::Max>(fOutImgMax);".

The call of the "equalizeImg" function is enclosed in a try/catch block, to handle the case where an exception is thrown. If an error occurs, a message is displayed to the user, IPSDK environment is cleaned by calling "ipsdk::core::LibraryInitializer::getInstance().clear()" and the application terminates.

// declare the variable that will contain the output image, resulting from
// the equalization
ImagePtr pOutImg;
try {
attr::RangePtr pInOutputRange(boost::make_shared<attr::Range>());
pInOutputRange->setValue<attr::Range::Min>(fOutImgMin);
pInOutputRange->setValue<attr::Range::Max>(fOutImgMax);
// equalize input image
pOutImg = ipsdk::imaproc::itrans::equalize2dImg(pInImg, pInOutputRange);
} 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;
}

The output image is then saved to the TIFF file specified in object "outImgFilePath":

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;
}

Finally, we clean IPSDK environment and exit:

return 0;
}

See the full source listing