import cv2
import matplotlib.pyplot as plt
import os, glob
from Parking import Parking
def img_process(test_images, park):
# 1.使用cv2.iRange进行第一步过滤,并转化为GRAY图像
first_step_images = list(map(park.filter_RGB, test_images)) # 使用map可以将函数作用到list的每一个成员
park.show_images(first_step_images)
# 2.基于一些先验坐标进行二次过滤
second_step_images = list(map(park.select_ROI, first_step_images))
park.show_images(second_step_images)
# 3.保留符合要求的直线信息,进行第三次过滤
LineInfo = list(map(park.LineInfo, second_step_images))
third_step_images = []
Lines = []
test_image_copy = test_images.copy()
for (image, lines) in zip(test_image_copy, LineInfo):
for line in lines:
for x1, y1, x2, y2 in line:
# image = cv2.line(image, (x1, y1), (x2, y2), (0, 255, 0))
Lines.append((x1, y1, x2, y2)) # 列表不可哈希,元组却可以
third_step_images.append(image)
park.show_images(third_step_images)
# 4.对这些直线数据排序,大致给出每个车位的位置,第四次过滤
image_copy = test_images.copy()
(car_pos0, fourst_step_images0) = park.ComputerParkingPos(Lines, image_copy[0])
(car_pos1, fourst_step_images1) = park.ComputerParkingPos(Lines, image_copy[1])
(car_pos, fourst_step_images) = list(zip((car_pos0, fourst_step_images0),(car_pos1, fourst_step_images1)))
park.show_images(fourst_step_images)
if __name__ == '__main__':
test_images = [plt.imread(path) for path in glob.glob('./images/*.jpg')]
park = Parking()
park.show_images(test_images)
img_process(test_images, park)
% parking
import cv2
import numpy as np
import matplotlib.pyplot as plt
class Parking:
def show_images(self, images, cmap=None):
cols = 2
rows = (len(images)+1) // 2
plt.figure(figsize=(15, 12))
for (i, image) in enumerate(images):
plt.subplot(rows, cols, i+1) # 注意子图的id是从1开始
cmap = 'gray' if len(image.shape) == 2 else cmap # if判断还可以这样用!
plt.imshow(image, cmap=cmap)
plt.xticks([]) # 不设置图像的x刻度
plt.yticks([]) # 不设置图像的y刻度
plt.tight_layout(pad=0, h_pad=0, w_pad=0) # 自适应调整子图,边距为0
plt.show()
def cv_imshow(self, name, image):
cv2.imshow(name, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def filter_RGB(self,image):
lower = np.uint8([120, 120, 120]) # 注意np.uint8类型
upper = np.uint8([255, 255, 255])
mask_bin = cv2.inRange(image, lower, upper)
image = cv2.bitwise_and(image, image, mask=mask_bin) # mask_val = 255 的地方才考虑
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
return image
def select_ROI(self, image):
image = cv2.Canny(image, 50, 200)
draw_img = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
# 指定多边形坐标
rows, cols = image.shape[:2]
pt_1 = [cols*0.05, rows*0.90]
pt_2 = [cols*0.05, rows*0.70]
pt_3 = [cols*0.30, rows*0.55]
pt_4 = [cols*0.6, rows*0.15]
pt_5 = [cols*0.90, rows*0.15]
pt_6 = [cols*0.90, rows*0.90]
pts = np.int32([[pt_1, pt_2, pt_3, pt_4, pt_5, pt_6]]) # 注意pts的数据结构
draw_img = cv2.polylines(draw_img, pts, True, (0, 0, 255))
# self.cv_imshow("draw", draw_img)
# 制作mask, 提取ROI
mask = np.zeros_like(image) # 注意zeros_like的使用
mask = cv2.fillPoly(mask, pts, 255)
image = cv2.bitwise_and(image, mask)
return image
def LineInfo(self, image):
lines = cv2.HoughLinesP(image, rho=0.1, theta=np.pi/10, threshold=15, minLineLength=9, maxLineGap=4)
lines_selected = []
for line in lines:
for x1, y1, x2, y2 in line:
if abs(y2 - y1) <= 1 and 25 <= abs(x2 - x1) <= 55:
lines_selected.append(line)
return lines_selected
def ComputerParkingPos(self, lines, image):
import operator
lines = sorted(lines, key=operator.itemgetter(0, 1)) # 根据(x1, y1)进行升序排列 itemgetter
clusters = {}
index = 0
for i in range(len(lines)-1):
if lines[i+1][0] - lines[i][0] < 10:
if index not in clusters.keys():
clusters[index] = []
clusters[index].append(lines[i])
clusters[index].append(lines[i+1])
else:
index += 1
# 计算矩形
rect = {}
i = 0
for key in clusters:
all_list = list(set(clusters[key]))
if len(all_list) > 15:
all_list = sorted(all_list, key=lambda tup: tup[1])
avg_y1 = all_list[0][1]
avg_y2 = all_list[-1][1]
avg_x1 = 0
avg_x2 = 0
for k in all_list:
avg_x1 += k[0]
avg_x2 += k[2]
avg_x1 /= len(all_list)
avg_x2 /= len(all_list)
rect[i] = [avg_x1, avg_y1, avg_x2, avg_y2] # 7是一个缓冲量
i += 1
# 微调
adj_y1 = {0: 0, 1: -10, 2: 0, 3: -11, 4: 28, 5: 5, 6: -15, 7: -15, 8: -10, 9: -30, 10: 9, 11: -32}
adj_y2 = {0: 10, 1: 0, 2: 15, 3: 10, 4: -15, 5: 15, 6: 15, 7: -20, 8: 15, 9: 15, 10: 0, 11: 30}
adj_x1 = {0: -8, 1: -5, 2: -15, 3: -15, 4: -15, 5: -15, 6: -15, 7: -15, 8: -10, 9: -10, 10: -10, 11: 0}
adj_x2 = {0: 0, 1: 20, 2: 15, 3: 15, 4: 15, 5: 15, 6: 15, 7: 15, 8: 10, 9: 10, 10: 10, 11: 0}
for key in rect.keys():
rect[key][0] += adj_x1[key]
rect[key][1] += adj_y1[key]
rect[key][2] += adj_x2[key]
rect[key][3] += adj_y2[key]
# 单独拆分每一个车辆区域
gap = 15.5
rect_cars = {}
index_col = 0
for key in rect:
(x1, y1, x2, y2) = rect[key]
mid_x = (x1 + x2)/2
step = int((y2 - y1)/gap)
if index_col not in rect_cars.keys():
rect_cars[index_col] = []
for i in range(0, step):
(x1_carL, y1_carL, x2_carL, y2_carL) = (int(x1), int(y1+i*gap), int(mid_x), int(y1+(i+1)*gap))
(x1_carR, y1_carR, x2_carR, y2_carR) = (int(mid_x), int(y1 + i * gap), int(x2), int(y1 + (i+1) * gap))
rect_cars[index_col].append((x1_carL, y1_carL, x2_carL, y2_carL))
rect_cars[index_col].append((x1_carR, y1_carR, x2_carR, y2_carR))
index_col += 1
# 绘制所有车位
for key in rect_cars:
for car in rect_cars[key]:
cv2.rectangle(image,(car[0],car[1]),(car[2],car[3]),(0,0,255))
return (rect_cars, image)