![]() |
IPSDK
4_1_0_2
IPSDK : Image Processing Software Development Kit
|
Application used to match shapes on a 2d grey level images. More...
Application used to match shapes on a 2d grey level images.
This application matches the objects in an input image with input templates (both input and template images are loaded from TIFF image files).
To proceed, the application extracts the shapes from each image (see Label shape extraction 2d) and computes for each shape in the image its distance with all the template's shapes. The template yielding the minimum distance is assigned as the best match.
The user can specify a minimum distance. If the matched template has a higher distance than the given threshold, no template is close enough to match the shape.
The application also allows to blur the image to smooth the edges in the input image. It can be useful to deblur noise on the input images, or in the case of default images which only two intensities (one for the background and one for the foreground), it generates a shaded contour. If the user specifies a value
0, the smoothing step is skipped.
Finally, the user can specify the binarization threshold used for the shape extraction (see Label shape extraction 2d for more details about the shape extraction).
The application's ouput are a label image, where each shape is labelled with the matched template's index, and a CSV file summarizing the matches for each shape.
The application can be called through a command line as follows:
<application_exe_filename> [--inputImgFilePath <input_image_file_path>] [--inTemplatePathList <input_template_file_path_list>]
[--inThresholdBinarization <input_binarization_threshold>] [--inThresholdDistance <input_distance_threshold>]
[--inStdDev <input_blur_standard_deviation>]
[--outputImgFilePath <output_image_file_path>] [--outputCsvResultPath <output_csv_file_path>]
Arguments:
--inputImgFilePath optional; specifies the name of the TIFF file, from
which the 2d input image will be loaded; if not
specified by the user, the input image is loaded from
file <DEV_ROOT>/data/Sample/images/shapes.tif
--inTemplatePathList optional; specifies the names of the TIFF files, from
which the 2d input template images will be loaded; if not
specified by the user, 4 images are loaded from
file <DEV_ROOT>/data/Sample/images/Templates.
To specify a list, the syntax is:
--inTemplatePathList path_template1 path_template2 ...
--inThresholdBinarization optional; binarization threshold used by the
shape extraction;
if not specified by the user, this value equals 15
--inThresholdDistance optional; distance threshold used by the
shape extraction;
if not specified by the user, this value equals 0.2
--inStdDev optional; deviation used to blur the image;
if the user specifies a value <= 0, this step is skipped by
the application (i.e. the input image is not blurred)
if not specified by the user, this value equals 1
--outputImgFilePath optional; specifies the name of the TIFF file, in
which the 2d output image resulting from the
shape matching will be saved;
if not specified by the user, the output image is
saved in file <TEMPORARY_IPSDK_DIR>/Sample/shapeMatch.tif
--outputCsvResultPath optional; specifies the name of the CSV file containing the
summary of the shape matching;
if not specified by the user, the output file is
saved in the same directory than outputImgFilePath
and is named shapeMatch.csvHere is a snapshot of default input image used by the application with the desired templates (on the left). On the right of the image, the output match image and the CSV result are shown. All the parameters are set to their default values:
We start by including all the necessary header files:
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:
Next, we initialize the IPSDK environment by invoking "ipsdk::core::LibraryInitializer::getInstance().init()". This method must be called before using any entity or function of IPSDK libraries. It returns an object of type ipsdk::core::LibInitResult, that tells us whether the initialization was OK or not. If the initialization failed (because the IPSDK license file was not found, for instance), we notify the user with an appropriate log message, and we close the application.
We then declare the variables where the input arguments will be stored. First, we declare the paths of the input and output images, the path of the output CSV file and also the collection of the paths for the templates.
We declare variables for the scalar parameters as well.
All these variables are initialized through the call of the "readCmdArguments" function. As its name suggests, it parses the command line to initialize the input and output images files paths, depending on the options specified by the user. The definition of this function is not explained here, because it mainly uses boost functions, and no IPSDK code.
Once the IPSDK environment correctly initialized, we load our input image from the associated TIFF file, by calling the function ipsdk::image::file::loadTiffImageFile. This function takes our object 'inImgFilePath" (of type boost::filesystem::path) as argument and returns an object of type ipsdk::image::ImagePtr, that contains our input image. We store it in "pInImg" variable.
The call of "loadTiffImageFile is enclosed in a try/catch block, to handle the case where an exception is thrown by loadTiffImageFile (if the file is not found or corrupted, for instance). 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.
In the same way, we load the template images. The paths are stored in a std::vector and we declare another std::vector containing the ipsdk ImagePtr objects.
Since the default images only have two different intensities (the background intensity is 0 and the geometric shapes pixels have an intensity of 255), the application allows to blur the input image and the template images to smooth the edges. This step can also be used to smooth the noise. To skip this step, the user can set the Gaussian standard deviation to a value lower or equal than 0.
Now the images are ready to be processed. We extract the shapes from the input image and from the template images. The shape templates are stored in a std::vector juste like for the ipsdk::image::ImagePtr template images.
We can now use the extracted shapes to compute the matching by calling the function ipsdk::geom::matchShapes. This function takes a reference (i.e. template) shape and a shape collection (for instance, the one extracted from the input image) and computes for each of these shapes its distance to the template shape. Hence, the application have to loop over all the templates to know the closest template for each shape.
Once this step done, we know the distance for each shape with every template. The next step involves determining the closest distance to be able to match a template. The result is stored in the bestMatches variable, which contains two collections with the same size as the number of shapes extracted from the input image (excluding the background). The first collection stores the closest shape indices whereas the second one contains their distances.
The user can define a threshold, whose default value is 0.2. If the minimum distance is higher than this threshold, the application considers that the shape could not be matched with any template and the index is set to the numeric limit of the ipsdk::ipUInt32 type.
Now, we know for each shape of the image its closest template. We use this information to generate the ouput image, by transforming the LUT of the previously calculated label image.
If all the previous operations were successfully completed, we save the image resulting from the matching operation to the TIFF file specified by the user (or to a default TIFF file, if the user did not specify anything):
We also save the result of the matching in a CSV file. This file contains for each shape of the input image its index, the index of the correspponding template if its distances is lower than the distance threshold criterion (an error message is written otherwise) and its distance in question.
The content of the writeToCsvFile function is :
The final action consists in cleaning the IPSDK environment before exiting. This cleaning operation (call to "ipsdk::core::LibraryInitializer::getInstance().clear()") must be the last call to IPSDK environment. It guarantees in particular that all threads created by IPSDK libraries are complete.
See the full source listing
1.8.14