• 图解 cv2.HoughLines & cv2.line 参数原理


    功能实现:利用cv.HoughLines寻找图像中霍夫直线,然后用cv2.line绘制红色的直线。

    拓展:计算整幅图像的平均灰度值,以及经过筛选的霍夫直线的平均灰度值,并进行比较。

    目录

    一、效果图以及参数讲解 

    二、图解霍夫直线的返回参数

    三、源码(包含注释)

    四、拓展


    一、效果图以及参数讲解 

     图1 原图

     图2 边缘处理后的图像

    图3 绘制红色霍夫直线的图像 

    lines = cv2.HoughLines(image_edge, 1, np.pi/180, 180)

    • image_edge:经过图像边缘处理后的图像
    • 1:像素之间的距离为1
    • np.pi/180:直线角度范围,2pi/(pi/180) = 360°
    • 180:一条预选直线上的最少像素点个数

    注意:

    如果距离是1,180个像素即可生成直线,如果距离是2,至少360个像素才可以生成直线。

    cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1) 

    • img:在图像img上绘制直线
    • (x1, y2)、(x2, y2):直线的两个端点,直接相连便可得到所需直线
    • (0, 0, 255):红色
    • 1:设置直线的宽度为1

    注意:

    直线的两个端点可以是负数。

    二、图解霍夫直线的返回参数

    cv2.HoughLines 的返回参数 line == [\rho ,\Theta ] ,其中,第一个参数表示图像原点距离直线的长度,第二个参数表示沿着x轴的角度大小。

    如下图所示,首先通过 cv.HoughLines 得到 line ,此时已经确定了直线的位置,然后需要确定直线上的两个坐标点来充当 cv.line 的输入参数,最后,在源图像上通过 cv.line 来绘制红色直线。

     图4 图解cv2.HoughLines的返回参数

    1. # 延长直线的长度,保证在整幅图像上绘制直线
    2. x1 = int(x0 + 2000 * (-b))
    3. y1 = int(y0 + 2000 * (a))
    4. x2 = int(x0 - 2000 * (-b))
    5. y2 = int(y0 - 2000 * (a))

    前面讲到, 霍夫直线值仅仅返回两个参数,并不会直接返回直线上的坐标点,我们在选取直线坐标点的时候,需要尽量选取图像外部的点(即负数),这样才会过整幅图像绘制直线。

    三、源码(包含注释)

    1. import cv2
    2. import numpy as np
    3. from numpy import mean
    4. # 读取图像以及图像的宽和高
    5. img = cv2.imread('./img.png')
    6. h = img.shape[0]
    7. w = img.shape[1]
    8. # 求取图像的平均灰度值
    9. img_gray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)
    10. all_gray = []
    11. for i in range(h):
    12. for j in range(w):
    13. all_gray.append(img_gray[i, j])
    14. print('图像的平均灰度值:', mean(all_gray))
    15. # Canny算子寻找图像的边缘
    16. image_edge = cv2.Canny(img, 200, 200)
    17. # 寻找霍夫直线
    18. lines = cv2.HoughLines(image_edge, 1, np.pi/180, 180)
    19. # 绘画霍夫直线
    20. if lines is not None:
    21. for n, line in enumerate(lines):
    22. # 沿着左上角的原点,作目标直线的垂线得到长度和角度
    23. rho = line[0][0]
    24. theta = line[0][1]
    25. # if np.pi / 3 < theta < np.pi * (3 / 4):
    26. a = np.cos(theta)
    27. b = np.sin(theta)
    28. # 得到目标直线上的点
    29. x0 = a * rho
    30. y0 = b * rho
    31. # 延长直线的长度,保证在整幅图像上绘制直线
    32. x1 = int(x0 + 2000 * (-b))
    33. y1 = int(y0 + 2000 * (a))
    34. x2 = int(x0 - 2000 * (-b))
    35. y2 = int(y0 - 2000 * (a))
    36. # 连接两点画直线
    37. # print((x1, y1), (x2, y2)) # (-148, 993) (335, -947)
    38. cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1)
    39. # ===============================CAB================================ #
    40. xDis = x2 - x1 # x的增量
    41. yDis = y2 - y1 # y的增量
    42. if (abs(xDis) > abs(yDis)):
    43. maxstep = abs(xDis)
    44. else:
    45. maxstep = abs(yDis)
    46. xUnitstep = xDis / maxstep # x每步骤增量
    47. yUnitstep = yDis / maxstep # y的每步增量
    48. x = x1
    49. y = y1
    50. average_gray = []
    51. for k in range(maxstep):
    52. x = x + xUnitstep
    53. y = y + yUnitstep
    54. # print("x: %d, y:%d" % (x, y))
    55. if 0 < x < h and 0 < y < w:
    56. # print(img_gray[int(x), int(y)])
    57. average_gray.append(img[int(x), int(y)])
    58. print('第{}霍夫直线的平均灰度值:'.format(n), mean(average_gray)) # 平均115,阴影的边界在125以上,堵料的边界在105左右
    59. # ================================================================== #
    60. print('直线的数量:', len(lines))
    61. else:
    62. print('直线的数量:', 0)
    63. # 可视化图像
    64. cv2.imshow('0', img)
    65. cv2.imshow('1', image_edge)
    66. cv2.waitKey(0)

    四、拓展

    因项目的需求,需要比对霍夫直线和整幅图像的平均灰度值的大小关系,所以在上面的源码中,我把此项功能加入到其中,希望对你有所帮助。


    >>> 如有疑问,欢迎评论区一起探讨。

  • 相关阅读:
    Google VS Facebook,哪个能带来更好的效果?
    只有steam启动的游戏会闪退蓝屏重启
    学SLAM的女生,很酷
    海外媒体发稿:海外汽车媒体推广9个方式解析
    【从互联网商业思维的角度分析商业模式在国内各大互联网产品的运用】
    hive从入门到放弃(六)——常用文件存储格式
    python学习-网络UDP 和网络TCP
    SpringBoot开发之SpringJDBC
    Github创建远程仓库(项目)
    Day768.大佬推荐的经典的Redis学习资料 -Redis 核心技术与实战
  • 原文地址:https://blog.csdn.net/qq_54185421/article/details/126661672