• 图像练习-计算平行线距离opencv(03)


    原图 

     

    1. //对输入图像进行细化
    2. cv::Mat ThinLine(const cv::Mat& matsrc, const int& iterations)
    3. {
    4. //CvSize size = cvGetSize(src);
    5. cv::Mat dst = matsrc.clone();//拷贝一个数组给另一个数组
    6. int _iwidth = dst.cols;
    7. int _iheight = dst.rows;
    8. int n = 0, i = 0, j = 0;
    9. for (n = 0; n < iterations; n++)
    10. {
    11. cv::Mat temp = dst.clone();
    12. for (i = 0; i < temp.rows; i++)
    13. {
    14. for (int j = 0; j < temp.cols; j++)
    15. {
    16. if ((*temp.ptr(i, j)) == 1)
    17. {
    18. int ap = 0;
    19. int p2 = (i == 0) ? 0 : (*temp.ptr(i - 1, j));
    20. int p3 = (i == 0 || j == _iwidth - 1) ? 0 : (*temp.ptr(i - 1, j + 1));
    21. if (p2 == 0 && p3 == 1)
    22. {
    23. ap++;
    24. }
    25. int p4 = (j == _iwidth - 1) ? 0 : (*temp.ptr(i, j + 1));
    26. if (p3 == 0 && p4 == 1)
    27. {
    28. ap++;
    29. }
    30. int p5 = (i == _iwidth - 1 || j == _iwidth - 1) ? 0 : (*temp.ptr(i + 1, j + 1));
    31. if (p4 == 0 && p5 == 1)
    32. {
    33. ap++;
    34. }
    35. int p6 = (i == _iwidth - 1) ? 0 : (*temp.ptr(i + 1, j));
    36. if (p5 == 0 && p6 == 1)
    37. {
    38. ap++;
    39. }
    40. int p7 = (i == _iwidth - 1 || j == 0) ? 0 : (*temp.ptr(i + 1, j - 1));
    41. if (p6 == 0 && p7 == 1)
    42. {
    43. ap++;
    44. }
    45. int p8 = (j == 0) ? 0 : (*temp.ptr(i, j - 1));
    46. if (p7 == 0 && p8 == 1)
    47. {
    48. ap++;
    49. }
    50. int p9 = (i == 0 || j == 0) ? 0 : (*temp.ptr(i - 1, j - 1));
    51. if (p8 == 0 && p9 == 1)
    52. {
    53. ap++;
    54. }
    55. if (p9 == 0 && p2 == 1)
    56. {
    57. ap++;
    58. }
    59. if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) > 1 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) < 7)
    60. {
    61. if (ap == 1)
    62. {
    63. if (p2 * p4 * p8 == 0)
    64. {
    65. if (p2 * p6 * p8 == 0)
    66. {
    67. (*dst.ptr(i, j)) = 0;
    68. }
    69. }
    70. }
    71. }
    72. }
    73. }
    74. }
    75. }
    76. //将二值图像转换成灰度,以便显示
    77. for (i = 0; i < dst.rows; i++)
    78. {
    79. for (j = 0; j < dst.cols; j++)
    80. {
    81. if ((*dst.ptr(i, j)) == 1)
    82. {
    83. (*dst.ptr(i, j)) = 255;
    84. }
    85. else
    86. {
    87. (*dst.ptr(i, j)) = 0;
    88. }
    89. }
    90. }
    91. return dst;
    92. }
    93. void LineDistance()
    94. {
    95. cv::Mat src = cv::imread("平行线求距离.png", cv::IMREAD_COLOR);
    96. cv::Mat gray;
    97. cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
    98. cv::Mat thre;
    99. cv::threshold(gray, thre, 128, 1, cv::THRESH_BINARY_INV);
    100. //第一步 对图像中的直线进行细化
    101. cv::Mat line = ThinLine(thre, 50);
    102. //第二步 提取直线的轮廓坐标
    103. std::vector> contours;
    104. cv::findContours(line, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
    105. cv::Mat show = src.clone();
    106. cv::drawContours(show, contours, -1, cv::Scalar(255));
    107. //直线拟合
    108. //拟合结果为一个四元素的容器,比如Vec4f - (vx, vy, x0, y0)
    109. //其中(vx, vy) 是直线的方向向量 (x0, y0) 是直线上的一个点
    110. cv::Vec4d l0;
    111. cv::fitLine(contours[0], l0, cv::DIST_L2, 0, 0.01, 0.01);//拟合方法采用最小二乘法
    112. double cos_theta0 = l0[0];
    113. double sin_theta0 = l0[1];
    114. double x0 = l0[2], y0 = l0[3];
    115. double k0 = sin_theta0 / cos_theta0;
    116. double b0 = y0 - k0 * x0;
    117. printf("line0: y = %f * x + %f \n", k0 * 180.0 / CV_PI, b0);
    118. double x = 0;
    119. double y = k0 * x + b0;
    120. cv::Vec4d l1;
    121. //拟合方法采用最小二乘法
    122. cv::fitLine(contours[1], l1, cv::DIST_L2, 0, 0.01, 0.01);
    123. double cos_theta1 = l1[0];
    124. double sin_theta1 = l1[1];
    125. double x1 = l1[2], y1 = l1[3];
    126. double k1 = sin_theta1 / cos_theta1;
    127. double b1 = y1 - k1 * x1;
    128. printf("line1: y = %f * x + %f \n", k1 * 180.0 / CV_PI, b1);
    129. //第四部 计算两条直线之间的距离 公式是: |b1 - b0| / sqrt(A * A + B * B)
    130. double A = k0;
    131. double B = 1.0;
    132. double dis = abs(b1 - b0) / sqrt(A * A + B * B);
    133. printf("dis is %f \n", dis);
    134. }

  • 相关阅读:
    中间件 | Redis - [分布式锁 & 事务]
    Tomcat颁布自定义SSL(Https)证书
    统计学入门:时间序列分析基础知识详解
    戴尔笔记本重装系统硬盘加密怎么解除
    『亚马逊云科技产品测评』活动征文|基于next.js搭建一个企业官网
    Bit, byte, KB, GB, MG
    剑指offer全集系列Java版本(2)
    CV目标检测模型小抄(2)
    jquery之Dom操作
    项目管理工具禅道
  • 原文地址:https://blog.csdn.net/qq_30460949/article/details/133276091