当前位置:首页 > 通信资讯 > 正文

opencv边缘提取与直线检测(opencv 识别直线)

本文实例为大家分享了OpenCV识别提取图像中的水平线与垂直线,供大家参考,具体内容如下

1).原理

图像形态学操作时候,可以通过自定义的结构元素实现结构元素 对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏感的对象改变而不敏感的对象保留输出。通过使用两个最基本的形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像的操作、得到想要的结果。

-膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值

opencv边缘提取与直线检测(opencv 识别直线)

-腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

opencv边缘提取与直线检测(opencv 识别直线)

常见的形状:矩形、园、直线、磁盘形状、砖石形状等各种自定义形状。

2).步骤

1.输入图像彩色图像 imread
2.转换为灰度图像 – cvtColor
3.转换为二值图像 – adaptiveThreshold
4.定义结构元素
5.开操作 (腐蚀+膨胀)提取 水平与垂直线

3).完整代码

(本人的运行环境是:vs2017+OpenCV3.4)

  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. #include <math.h>
  4. using namespace std;
  5. using namespace cv;
  6. //灰度化图像
  7. Mat gray_Img(Mat src)
  8. {
  9. Mat dst = Mat::zeros(src.size(), src.type());
  10. cvtColor(src, dst, CV_BGR2GRAY);
  11. return dst;
  12. }
  13. //自适应阈值(二值化图像)
  14. Mat threshold_Img(Mat src)
  15. {
  16. Mat dst = Mat::zeros(src.size(), src.type());
  17. //参数:输入, 输出, 二值图像的最大值 , 在一个邻域内计算阈值所采用的算法,有两个取值分别为 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C , 阈值类型只有两个取值,分别为 THRESH_BINARY 和THRESH_BINARY_INV,(blockSize)adaptiveThreshold的计算单位是像素的邻域块,邻域块取多大就由这个值作决定, 偏移值调整量
  18. adaptiveThreshold(~src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
  19. return dst;
  20. }
  21. //结构元素(获取垂直算子)
  22. Mat get_Vertical(Mat src)
  23. {
  24. Mat dst = Mat::zeros(src.size(), src.type());
  25. return getStructuringElement(MORPH_RECT,Size(src.cols/16,1),Point(-1,-1));
  26. }
  27. //结构元素(获取水平算子)
  28. Mat get_Horizontal(Mat src)
  29. {
  30. Mat dst = Mat::zeros(src.size(), src.type());
  31. return getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));
  32. }
  33. //腐蚀
  34. Mat erode_Img(Mat src,Mat kernel)
  35. {
  36. Mat dst = Mat::zeros(src.size(), src.type());
  37. erode(src, dst, kernel);
  38. return dst;
  39. }
  40. //膨胀
  41. Mat dilate_Img(Mat src, Mat kernel)
  42. {
  43. Mat dst = Mat::zeros(src.size(), src.type());
  44. dilate(src, dst, kernel);
  45. return dst;
  46. }
  47. int main()
  48. {
  49. Mat src = imread("001.png");
  50. if (src.empty())
  51. {
  52. cout << "fail to load image" << endl;
  53. return -1;
  54. }
  55. namedWindow("input_Img", 0);
  56. imshow("input_Img", src);
  57. //输入图像转灰度
  58. Mat grayImg = gray_Img(src);
  59. namedWindow("input_Img_gray", 0);
  60. imshow("input_Img_gray", grayImg);
  61. //二值化图像
  62. Mat thresholdImg = threshold_Img(grayImg);
  63. namedWindow("input_Img_threshold", 0);
  64. imshow("input_Img_threshold", thresholdImg);
  65. Mat verticalLine = get_Vertical(src);
  66. Mat horizontalLine = get_Horizontal(src);
  67. //先腐蚀再膨胀
  68. Mat vertical_Line_erode = erode_Img(thresholdImg, verticalLine);
  69. Mat vertical_Line_dilate = dilate_Img(vertical_Line_erode, verticalLine);
  70. //显示图像中的垂直线
  71. namedWindow("verticalLine", 0);
  72. imshow("verticalLine", vertical_Line_dilate);
  73. Mat horizontal_Line_erode = erode_Img(thresholdImg, horizontalLine);
  74. Mat horizontal_Line_dilate = dilate_Img(horizontal_Line_erode, horizontalLine);
  75. //显示图像中的垂直线
  76. namedWindow("horizontalLine", 0);
  77. imshow("horizontalLine", horizontal_Line_dilate);
  78. waitKey();
  79. return 0;
  80. }

4).我的运行结果

1.灰度化结果

opencv边缘提取与直线检测(opencv 识别直线)

2.二值化

opencv边缘提取与直线检测(opencv 识别直线)

3.提取的垂直线

opencv边缘提取与直线检测(opencv 识别直线)

4.提取的水平线

opencv边缘提取与直线检测(opencv 识别直线)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/MnisRain/article/details/81987578

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。