import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2
# Read in and grayscale the image
image = mpimg.imread('exit-ramp.jpg') # 读取一张图
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) #将图片转化为灰度图
# Define a kernel size and apply Gaussian smoothing
kernel_size = 5 # 设置卷积核大小为5
# 高斯滤波
# 高斯滤波就是对整幅图像做加权平均,每一个像素点的值都由其本身和邻域内的其他像素值经过加权平均后得到
# 步骤:用一个卷积核扫描图像中的每一个像素,用卷积核确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值
# 函数参数:cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
# -gray:灰度图
# -kernel_size:卷积核大小
# -0:标准偏差
blur_gray = cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
# Define our parameters for Canny and apply
low_threshold = 50 # 低阈值
high_threshold = 150 # 高阈值
# Canny运算:边缘检测
# 参数说明: blur_gray表示输入的图片, low_threshold表示最小阈值,high_threshold表示最大阈值,用于进一步删选边缘信息
# 详细用法参考:https://www.cnblogs.com/my-love-is-python/p/10397482.html
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
# Next we'll create a masked edges image using cv2.fillPoly()
# 构造一个与edges维度一致的矩阵mask
mask = np.zeros_like(edges)
ignore_mask_color = 255
# This time we are defining a four sided polygon to mask
# 获取图像的shape
imshape = image.shape
# 生成多维数组
vertices = np.array([[(0,imshape[0]),(0, 0), (imshape[1], 0), (imshape[1],imshape[0])]], dtype=np.int32)
# 多边形填充
# -mask: 要填充的图
# -vertices:填充区域,
# -ignore_mask_color:填充颜色
cv2.fillPoly(mask, vertices, ignore_mask_color)
# 按位与运算,分离出canny检测出的边缘区域
masked_edges = cv2.bitwise_and(edges, mask)
# Define the Hough transform parameters
# Make a blank the same size as our image to draw on
rho = 2.0 # distance resolution in pixels of the Hough grid
theta = np.pi/180 # angular resolution in radians of the Hough grid
threshold = 100 # minimum number of votes (intersections in Hough grid cell)
min_line_length = 40 #minimum number of pixels making up a line
max_line_gap = 20 # maximum gap in pixels between connectable line segments
line_image = np.copy(image)*0 # creating a blank to draw lines on
# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
# 霍夫变换找直线
# masked_edges: 必须是二值图像,推荐使用canny边缘检测的结果图像;
# rho: 线段以像素为单位的距离精度,double类型的,推荐用1.0
# theta: 线段以弧度为单位的角度精度,推荐用numpy.pi/180
# threshod: 累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试
# np.array([]):这个参数的意义未知,发现不同的lines对结果没影响,但是不要忽略了它的存在
# min_line_length:线段以像素为单位的最小长度,根据应用场景设置
# max_line_gap:同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段
lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]),
min_line_length, max_line_gap)
# Iterate over the output "lines" and draw lines on a blank image
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
# Create a "color" binary image to combine with line image
color_edges = np.dstack((edges, edges, edges))
# Draw the lines on the edge image
lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0)
plt.imshow(lines_edges)
plt.show()