File: morphology.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (154 lines) | stat: -rw-r--r-- 6,009 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// 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 at least 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{});
    }
}