功能实现:利用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 ==
,其中,第一个参数表示图像原点距离直线的长度,第二个参数表示沿着x轴的角度大小。
如下图所示,首先通过 cv.HoughLines 得到 line ,此时已经确定了直线的位置,然后需要确定直线上的两个坐标点来充当 cv.line 的输入参数,最后,在源图像上通过 cv.line 来绘制红色直线。

图4 图解cv2.HoughLines的返回参数
- # 延长直线的长度,保证在整幅图像上绘制直线
- x1 = int(x0 + 2000 * (-b))
- y1 = int(y0 + 2000 * (a))
- x2 = int(x0 - 2000 * (-b))
- y2 = int(y0 - 2000 * (a))
前面讲到, 霍夫直线值仅仅返回两个参数,并不会直接返回直线上的坐标点,我们在选取直线坐标点的时候,需要尽量选取图像外部的点(即负数),这样才会过整幅图像绘制直线。
- import cv2
- import numpy as np
- from numpy import mean
-
-
- # 读取图像以及图像的宽和高
- img = cv2.imread('./img.png')
- h = img.shape[0]
- w = img.shape[1]
-
- # 求取图像的平均灰度值
- img_gray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)
- all_gray = []
- for i in range(h):
- for j in range(w):
- all_gray.append(img_gray[i, j])
- print('图像的平均灰度值:', mean(all_gray))
-
- # Canny算子寻找图像的边缘
- image_edge = cv2.Canny(img, 200, 200)
-
- # 寻找霍夫直线
- lines = cv2.HoughLines(image_edge, 1, np.pi/180, 180)
-
- # 绘画霍夫直线
- if lines is not None:
- for n, line in enumerate(lines):
- # 沿着左上角的原点,作目标直线的垂线得到长度和角度
- rho = line[0][0]
- theta = line[0][1]
- # if np.pi / 3 < theta < np.pi * (3 / 4):
- a = np.cos(theta)
- b = np.sin(theta)
- # 得到目标直线上的点
- x0 = a * rho
- y0 = b * rho
-
- # 延长直线的长度,保证在整幅图像上绘制直线
- x1 = int(x0 + 2000 * (-b))
- y1 = int(y0 + 2000 * (a))
- x2 = int(x0 - 2000 * (-b))
- y2 = int(y0 - 2000 * (a))
-
- # 连接两点画直线
- # print((x1, y1), (x2, y2)) # (-148, 993) (335, -947)
- cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1)
-
- # ===============================CAB================================ #
- xDis = x2 - x1 # x的增量
- yDis = y2 - y1 # y的增量
- if (abs(xDis) > abs(yDis)):
- maxstep = abs(xDis)
- else:
- maxstep = abs(yDis)
- xUnitstep = xDis / maxstep # x每步骤增量
- yUnitstep = yDis / maxstep # y的每步增量
- x = x1
- y = y1
- average_gray = []
- for k in range(maxstep):
- x = x + xUnitstep
- y = y + yUnitstep
- # print("x: %d, y:%d" % (x, y))
- if 0 < x < h and 0 < y < w:
- # print(img_gray[int(x), int(y)])
- average_gray.append(img[int(x), int(y)])
- print('第{}霍夫直线的平均灰度值:'.format(n), mean(average_gray)) # 平均115,阴影的边界在125以上,堵料的边界在105左右
- # ================================================================== #
-
- print('直线的数量:', len(lines))
- else:
- print('直线的数量:', 0)
-
- # 可视化图像
- cv2.imshow('0', img)
- cv2.imshow('1', image_edge)
- cv2.waitKey(0)
因项目的需求,需要比对霍夫直线和整幅图像的平均灰度值的大小关系,所以在上面的源码中,我把此项功能加入到其中,希望对你有所帮助。
>>> 如有疑问,欢迎评论区一起探讨。