赞
踩
5. Morphology_3.cpp 提取图像中水平线和垂直线的opencv示例
原图notes.png
二值化
提取水平线
提取垂直线
对垂直图像取反
提取边缘
使用膨胀操作处理边缘
平滑处理:vertical.copyTo(smooth); blur(smooth, smooth, Size(2, 2)); smooth.copyTo(vertical, edges);
- /**
- * @file Morphology_3(Extract_Lines).cpp
- * @brief 使用形态变换提取图片中的水平线和垂直线的示例代码
- * @author OpenCV team
- */
-
-
- // 引入所需的库
- #include <opencv2/core.hpp> // 查找、修改和复制矩阵
- #include <opencv2/imgproc.hpp> // 图像处理
- #include <opencv2/highgui.hpp> // 高级图像展示
- #include <iostream> // 标准输入输出库
-
-
- void show_wait_destroy(const char* winname, cv::Mat img); // 创建一个函数,用于显示图像并在按键后销毁窗口
-
-
- // 使用标准库和OpenCV库
- using namespace std;
- using namespace cv;
-
-
- int main(int argc, char** argv)
- {
- //! [load_image]
- CommandLineParser parser(argc, argv, "{@input | notes.png | 输入图片}");
- // 读取输入图像
- Mat src = imread( samples::findFile( parser.get<String>("@input") ), IMREAD_COLOR);
- if (src.empty())
- {
- // 若图像无法读取或无法找到,则打印出错误信息
- cout << "无法打开或找到图片!\n" << endl;
- cout << "用法: " << argv[0] << " < 输入图片 >" << endl;
- return -1;
- }
-
-
- // 展示原图像
- imshow("src", src);
- //! [加载图片]
-
-
- //! [灰度化]
- // 若原图像不是灰度图,将之转为灰度图
- Mat gray;
-
-
- if (src.channels() == 3)
- {
- cvtColor(src, gray, COLOR_BGR2GRAY);
- }
- else
- {
- gray = src;
- }
-
-
- // 展示灰度图像
- show_wait_destroy("gray", gray);
- //! [灰度化]
-
-
- //! [二值化]
- // 在灰度图的反向图上应用自适应阈值化处理,注意此处需要用到~符号
- Mat bw;
- adaptiveThreshold(~gray, bw, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
-
-
- // 展示二值化图像
- show_wait_destroy("binary", bw);
- //! [二值化]
-
-
- //! [初始化]
- // 创建两张图片,分别用于提取水平线和垂直线
- Mat horizontal = bw.clone();
- Mat vertical = bw.clone();
- //! [初始化]
-
-
- //! [提取水平线]
- // 指定水平轴上的大小
- int horizontal_size = horizontal.cols / 30;
-
-
- // 创建结构元素,通过形态操作来提取水平线
- Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontal_size, 1));
-
-
- // 应用形态操作
- erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
- dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
-
-
- // 展示提取出的水平线
- show_wait_destroy("horizontal", horizontal);
- //! [提取水平线]
-
-
- //! [提取垂直线]
- // 指定垂直轴上的大小
- int vertical_size = vertical.rows / 30;
-
-
- // 创建结构元素,通过形态操作来提取垂直线
- Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1, vertical_size));
-
-
- // 应用形态操作
- erode(vertical, vertical, verticalStructure, Point(-1, -1));
- dilate(vertical, vertical, verticalStructure, Point(-1, -1));
-
-
- // 展示提取出的垂直线
- show_wait_destroy("vertical", vertical);
- //! [提取垂直线]
-
-
- //! [平滑处理]
- // 对垂直图像取反
- bitwise_not(vertical, vertical);
- show_wait_destroy("vertical_bit", vertical);
-
-
- // 根据逻辑提取边缘和平滑图像
- // 1. 提取边缘
- // 2. 使用膨胀操作处理边缘
- // 3. 将原图像复制至平滑图像
- // 4. 对平滑图像进行模糊处理
- // 5. 将平滑图像复制至源图像,覆盖边缘部分
-
-
- // 步骤1
- Mat edges;
- adaptiveThreshold(vertical, edges, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, -2);
- show_wait_destroy("edges", edges);
-
-
- // 步骤2
- Mat kernel = Mat::ones(2, 2, CV_8UC1);
- dilate(edges, edges, kernel);
- show_wait_destroy("dilate", edges);
-
-
- // 步骤3
- Mat smooth;
- vertical.copyTo(smooth);
-
-
- // 步骤4
- blur(smooth, smooth, Size(2, 2));
-
-
- // 步骤5
- smooth.copyTo(vertical, edges);
-
-
- // 展示最终结果
- show_wait_destroy("smooth - final", vertical);
- //! [平滑处理]
-
-
- return 0;
- }
-
-
- // 创建一个函数,用于显示图像并在按键后销毁窗口
- void show_wait_destroy(const char* winname, cv::Mat img) {
- imshow(winname, img);
- moveWindow(winname, 500, 0);
- waitKey(0);
- destroyWindow(winname);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。