前言
最近在bi站学习opencv的时候看到了一个比较有意思的项目,用opencv+tensorflow实现视频中的车位检测,里面涉及了大量的图像处理操作,还有用tensorflow进行模型训练,但是缺乏深度学习这部分的知识,所有模型训练这一部分的例程只是初略看过和运行。下面的内容只是我对这个项目图像处理方面操作的记录,供以后学习使用。
车位识别实现思路

对视频的识别其实和图像是差不多的,因为视频其实是由一帧一帧的图像构成的,首先就是要从视频中截取几张图像勇于图像处理。图像处理:
第一步:通过手动设置一个区域,过滤掉背景,只保留停车场。
第二步:边缘检测,提取停车场的大致轮廓。
第三步:进行霍夫检测,检测停车场中的直线。
第四步:对画好的线进行过滤,并在画好线的图像中进行分割,分割出每一个停车位,给每一个停车位编号。
第五步:截取出每个停车位的图像,作为训练模型的数据。
图像处理实现代码
原图:

手动设置一个区域,并且删除掉不需要的地方,在这之前先进行边缘检测。原理就是在图像外围点几个点,这里点了五个点,然后用线将点连起来就得到了一个mask,将mask内的区域设为1,外围设为0,将mask与图像想与就得到了去掉外围的图像。
#边缘检测
def detect_edges(image,low_threshold,high_threshold):
return cv2.Canny(image,low_threshold,high_threshold)
#手动选择一个区域
def select_region(image):
#设置多边形的顶点
row, cols = image.shape[:2]
spot1 = [cols * 0.05, row * 0.92]
spot2 = [cols * 0.05, row * 0.70]
spot3 = [cols * 0.30, row * 0.55]
spot4 = [cols * 0.60, row * 0.12]
spot5 = [cols * 0.90, row * 0.12]
spot6 = [cols * 0.90, row * 0.92]
vertices = np.array([[spot1,spot2,spot3,spot4,spot5,spot6]],dtype=np.int32)
print(vertices)
spot_img = image.copy()
#将灰度图转为RGB图像
spot_img = cv2.cvtColor(spot_img, cv2.COLOR_RGB2BGR)
for spot in vertices[0]:
#画点
cv2.circle(spot_img, (spot[0],spot[1]), 10, (200,100,200), -1)
#show('spot_img',spot_img)
return (spot_img,vertices)
#删掉不需要的地方
def filter_region(image, vertices):
mask = np.zeros_like(image)
if len(mask.shape) == 2:
cv2.fillPoly(mask, vertices, 255) # 多边形填充
show('mask', mask)
return cv2.bitwise_and(image, mask)
效果:

进行霍夫检测,检测停车场中的直线。
#HoughLinesP函数是统计概率霍夫线变换函数
def hough_lines(image):
#输入的图像需要是边缘检测后的结果
#minLineLengh(线的最短长度,比这个短的都被忽略)和MaxLineCap(两条直线之间的最大间隔,小于此值,认为是一条直线)
#rho距离精度,theta角度精度,threshod超过设定阈值才被检测出线段
return cv2.HoughLinesP(image, rho=0.1, theta=np.pi/10, threshold=15, minLineLength=8, maxLineGap=1)
对画好的线进行过滤,并在画好线的图像中进行分割,分割出每一个停车位,给每一个停车位编号。大致操作也分为5步,首先对检测后得到的直线进行过滤,过滤方法是比如一条直线的长度大于20小于50,水平差小于1的则认识是车位线;然后将过滤后的线安装x1,y1 进行排序;然后将车位线安列来分类,图像中有12列车位,就分为12簇;然后得到每条线的坐标;最后就是将车位画出。分割出每一个停车位,给每一个停车位编号。
#用方框画出车位
def detected_blocks(image,lines):
#Step 1: 过滤部分直线
img = image.copy()
cleaned = []
for line in lines:
for x1,y1,x2,y2 in line:
if abs(y2-y1) <= 1 and abs(x2-x1) >= 20 and abs(x2-x1) <= 57:
cleaned.append((x1,y1,x2,y2))
#Step 2: 对直线按照x1,y1进行排序
list1 =sorted(cleaned,key=operator.itemgetter(0,1))
#Step 3: 找到多个列,相当于每列是一排车
#每一列的车位
clusters = {
}
#列数
dIndex = 0
#行与行之间的最小距离
clus_dist = 20
for i in range(len(list1)-1):
distance = abs(list1[i+1][0] - list1[i][0])
if distance <= clus_dist:
if not dIndex in clusters.keys(): clusters[dIndex] = []
clusters[dIndex].append(list1[i])
clusters[dIndex].append(list1

本文介绍了如何通过图像处理和深度学习技术,利用OpenCV进行边缘检测、霍夫变换和车位分割,结合TensorFlow训练模型,实现在视频中自动识别和标记车位的过程。

1260

被折叠的 条评论
为什么被折叠?



