AimRT/_deps/boost-src/libs/gil/example/morphology.cpp
2025-01-12 20:40:08 +08:00

155 lines
5.9 KiB
C++

//
// Copyright 2021 Prathamesh Tagore <prathameshtagore@gmail.com>
//
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/gil.hpp>
#include <boost/gil/extension/io/png.hpp>
#include <iostream>
#include <map>
#include <string>
#include <vector>
// Demonstrates a number of morphological operations
// The structuring element is defined as an instance of a kernel_2d<float>:
// Default structuring element is SE = [1,1,1]
// |1,1,1|
// [1,1,1]
// SE(1,1)(center pixel) is the one which coincides with the currently
// considered pixel of the image to be convolved. The structuring element can be
// easily changed by the user.
// The example demonstrates the following morphological operations:
// - black_hat
// - top_hat
// - morphological_gradient
// - dilation
// - erosion
// - opening
// - closing
// - binary
// These operations are defined in include/boost/gil/image_processing/morphology.hpp
namespace gil = boost::gil;
int main(int argc, char** argv)
{
std::map<std::string, bool> operations;
if (argc < 4 || argc > 11)
{
throw std::invalid_argument(
"Wrong format of command line arguments.\n"
"Correct format is <Input_image.png> <Output_image_template>"
" <operation1> <operation2> <operation3> <operation4> <operation5> "
"<operation6>"
" <operation7> <operation8>\n");
// User has to enter atleast one operation and they can enter maximum 8
// operations considering binary conversion to be an
// operation.Output_image_template argument is the common component which
// will be added in names of all output images followed by a hyphen and
// the operation name.
// Example :
// ./example_morphology morphology_original.png out black_hat top_hat
// morphological_gradient dilation erosion opening closing binary
// Order of arguments entered will not matter with the exception of binary
// operation used for binary morphological operations.If binary is entered
// through the command line, it will always be the first operation to be
// applied.
return -1;
}
else
{
for (int i = 3; i < argc; ++i)
operations[argv[i]] = true;
}
gil::gray8_image_t img;
gil::read_image(argv[1], img, gil::png_tag{});
// Image can be converted to a binary format with high value as 255 and low
// value as 0 by using the threshold operator . This can be used for binary
// morphological operations . Convenient threshold for binary conversion may
// be chosen by the user.
if (operations["binary"])
{
threshold_binary(view(img), view(img), 170, 255);
std::string name = argv[2];
name += "-binary.png";
gil::write_view(name, view(img), gil::png_tag{});
}
std::vector<float> ker_vec(9, 1.0f); // Structuring element
gil::detail::kernel_2d<float> ker_mat(ker_vec.begin(), ker_vec.size(), 1, 1);
gil::gray8_image_t img_out_dilation(img.dimensions()), img_out_erosion(img.dimensions()),
img_out_opening(img.dimensions());
gil::gray8_image_t img_out_closing(img.dimensions()), img_out_mg(img.dimensions()),
img_out_top_hat(img.dimensions());
gil::gray8_image_t img_out_black_hat(img.dimensions());
// Do not pass empty input image views in functions defined below for
// morphological operations to avoid errors.
if (operations["dilation"])
{
// dilate(input_image_view,output_image_view,structuring_element,iterations)
dilate(view(img), view(img_out_dilation), ker_mat, 1);
std::string name = argv[2];
name += "-dilation.png";
gil::write_view(name, view(img_out_dilation), gil::png_tag{});
}
if (operations["erosion"])
{
// erode(input_image_view,output_image_view,structuring_element,iterations)
erode(view(img), view(img_out_erosion), ker_mat, 1);
std::string name = argv[2];
name += "-erosion.png";
gil::write_view(name, view(img_out_erosion), gil::png_tag{});
}
if (operations["opening"])
{
// opening(input_image_view,output_image_view,structuring_element)
opening(view(img), view(img_out_opening), ker_mat);
std::string name = argv[2];
name += "-opening.png";
gil::write_view(name, view(img_out_opening), gil::png_tag{});
}
if (operations["closing"])
{
// closing(input_image_view,output_image_view,structuring_element)
closing(view(img), view(img_out_closing), ker_mat);
std::string name = argv[2];
name += "-closing.png";
gil::write_view(name, view(img_out_closing), gil::png_tag{});
}
if (operations["morphological_gradient"])
{
// morphological_gradient(input_image_view,output_image_view,structuring_element)
morphological_gradient(view(img), view(img_out_mg), ker_mat);
std::string name = argv[2];
name += "-morphological_gradient.png";
gil::write_view(name, view(img_out_mg), gil::png_tag{});
}
if (operations["top_hat"])
{
// top_hat(input_image_view,output_image_view,structuring_element)
top_hat(view(img), view(img_out_top_hat), ker_mat);
std::string name = argv[2];
name += "-top_hat.png";
gil::write_view(name, view(img_out_top_hat), gil::png_tag{});
}
if (operations["black_hat"])
{
// black_hat(input_image_view,output_image_view,structuring_element)
black_hat(view(img), view(img_out_black_hat), ker_mat);
std::string name = argv[2];
name += "-black_hat.png";
gil::write_view(name, view(img_out_black_hat), gil::png_tag{});
}
}