1/**
2 * @file Morphology_3(Extract_Lines).cpp
3 * @brief Use morphology transformations for extracting horizontal and vertical lines sample code
4 * @author OpenCV team
5 */
6
7#include <iostream>
8#include <opencv2/opencv.hpp>
9
10using namespace std;
11using namespace cv;
12
13int main(int, char** argv)
14{
15//! [load_image]
16    // Load the image
17    Mat src = imread(argv[1]);
18
19    // Check if image is loaded fine
20    if(!src.data)
21        cerr << "Problem loading image!!!" << endl;
22
23    // Show source image
24    imshow("src", src);
25//! [load_image]
26
27//! [gray]
28    // Transform source image to gray if it is not
29    Mat gray;
30
31    if (src.channels() == 3)
32    {
33        cvtColor(src, gray, CV_BGR2GRAY);
34    }
35    else
36    {
37        gray = src;
38    }
39
40    // Show gray image
41    imshow("gray", gray);
42//! [gray]
43
44//! [bin]
45    // Apply adaptiveThreshold at the bitwise_not of gray, notice the ~ symbol
46    Mat bw;
47    adaptiveThreshold(~gray, bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
48
49    // Show binary image
50    imshow("binary", bw);
51//! [bin]
52
53//! [init]
54    // Create the images that will use to extract the horizontal and vertical lines
55    Mat horizontal = bw.clone();
56    Mat vertical = bw.clone();
57//! [init]
58
59//! [horiz]
60    // Specify size on horizontal axis
61    int horizontalsize = horizontal.cols / 30;
62
63    // Create structure element for extracting horizontal lines through morphology operations
64    Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize,1));
65
66    // Apply morphology operations
67    erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
68    dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
69
70    // Show extracted horizontal lines
71    imshow("horizontal", horizontal);
72//! [horiz]
73
74//! [vert]
75    // Specify size on vertical axis
76    int verticalsize = vertical.rows / 30;
77
78    // Create structure element for extracting vertical lines through morphology operations
79    Mat verticalStructure = getStructuringElement(MORPH_RECT, Size( 1,verticalsize));
80
81    // Apply morphology operations
82    erode(vertical, vertical, verticalStructure, Point(-1, -1));
83    dilate(vertical, vertical, verticalStructure, Point(-1, -1));
84
85    // Show extracted vertical lines
86    imshow("vertical", vertical);
87//! [vert]
88
89//! [smooth]
90    // Inverse vertical image
91    bitwise_not(vertical, vertical);
92    imshow("vertical_bit", vertical);
93
94    // Extract edges and smooth image according to the logic
95    // 1. extract edges
96    // 2. dilate(edges)
97    // 3. src.copyTo(smooth)
98    // 4. blur smooth img
99    // 5. smooth.copyTo(src, edges)
100
101    // Step 1
102    Mat edges;
103    adaptiveThreshold(vertical, edges, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, -2);
104    imshow("edges", edges);
105
106    // Step 2
107    Mat kernel = Mat::ones(2, 2, CV_8UC1);
108    dilate(edges, edges, kernel);
109    imshow("dilate", edges);
110
111    // Step 3
112    Mat smooth;
113    vertical.copyTo(smooth);
114
115    // Step 4
116    blur(smooth, smooth, Size(2, 2));
117
118    // Step 5
119    smooth.copyTo(vertical, edges);
120
121    // Show final result
122    imshow("smooth", vertical);
123//! [smooth]
124
125    waitKey(0);
126    return 0;
127}