opencv-- 停车场车位识别

停车场车位识别

停车场车位实时检测任务,是拿到停车场的一段视频video,主要完成两件事情:

  1. 检测整个停车场当中,当前一共有多少辆车,一共有多少个空余的车位
  2. 把空余的停车位标识出来,这样用户停车的时候,就可以直接去空余的停车位处, 为停车节省了很多时间
    遇到的问题
I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA

遇到了这个问题,意思是你的 CPU 支持AVX2 FMA(加速CPU计算),但安装的 TensorFlow 版本不支持

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

2.遇到的问题

forrtl: error (200): program aborting due to control-C event
Image PC Routine Line Source
libifcoremd.dll 00007FFD5FCA3B58 Unknown Unknown Unknown
KERNELBASE.dll 00007FFDC015B933 Unknown Unknown Unknown
KERNEL32.DLL 00007FFDC15D7034 Unknown Unknown Unknown
ntdll.dll 00007FFDC2762651 Unknown Unknown Unknown

解决方法:pip install --upgrade scipy
3.对图片进行测试,识别出空停车位位置及数量
在这里插入图片描述

4.具体代码:

import cv2 as cv
import numpy as np
import operator
import pickle
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from keras.models import Sequential
from keras.models import load_model
def cv_show(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)
    cv.destroyAllWindows()
image = cv.imread('D:/D/download/scene1410.jpg')
cv_show('src', image)
lower = np.uint8([120, 120, 120])
upper = np.uint8([255, 255, 255])
# lower_red和高于upper_red的部分分别变成0,lower_red~upper_red之间的值变成255,相当于过滤背景
white_mask = cv.inRange(image, lower, upper)
cv_show('white_mask',white_mask)
white_yellow_image = cv.bitwise_and(image, image, mask = white_mask)
cv_show('white_yellow_image', white_yellow_image)
# 转灰度图
gray_image = cv.cvtColor(white_yellow_image, cv.COLOR_BGR2GRAY)
cv_show('gray_image', gray_image)
edge_image = cv.Canny(gray_image, 50, 200)
cv_show('edge_image', edge_image)
# 手动选择区域
row, col = image.shape[:2]
pt_1 = [col*0.05, row*0.90]
pt_2 = [col*0.05, row*0.70]
pt_3 = [col*0.30, row*0.55]
pt_4 = [col*0.6, row*0.15]
pt_5 = [col*0.90, row*0.15]
pt_6 = [col*0.90, row*0.90]

vertices = np.array([[pt_1, pt_2, pt_3, pt_4, pt_5, pt_6]], dtype=np.int32)
point_img = edge_image.copy()
point_img = cv.cvtColor(point_img, cv.COLOR_GRAY2RGB)
for point in vertices[0]:
    cv.circle(point_img, (point[0], point[1]), 10, (0, 0, 255), 4)
cv_show('point_img', point_img)
mask = np.zeros_like(edge_image)
cv.fillPoly(mask, vertices, 255)
cv_show('mask', mask)
roi_image = cv.bitwise_and(edge_image, mask)
cv_show('roi_image', roi_image)
lines = cv.HoughLinesP(roi_image, rho=0.1, theta=np.pi/10, threshold=15, minLineLength=9, maxLineGap=4)
print(lines.shape)
# 挑出符合要求的直线并画出
line_image = np.copy(image)
cleaned = []
for line in lines:
    x1, y1, x2, y2 = line[0]
    if abs(y2-y1) <= 1 and abs(x2-x1) >=25 and abs(x2-x1) <= 55:
        cleaned.append((x1, y1, x2, y2))
        cv.line(line_image, (x1, y1), (x2, y2), [255, 0, 0], 2)
print("No lines detected: ", len(cleaned))
cv_show('line_image', line_image)
rect_image = np.copy(image)
list1 = sorted(cleaned, key=operator.itemgetter(0, 1))
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[i + 1])

    else:
        dIndex += 1
rect_coord = {}
i = 0
for key in clusters:
    all_list = clusters[key]
    list2 = list(set(all_list))
    if len(list2) > 5:
        list2 = sorted(list2, key=lambda tup: tup[1])
        avg_y1 = list2[0][1]
        avg_y2 = list2[-1][1]
        avg_x1 = 0
        avg_x2 = 0
        for tup in list2:
            avg_x1 += tup[0]
            avg_x2 += tup[2]
        avg_x1 = avg_x1/len(list2)
        avg_x2 = avg_x2/len(list2)
        rect_coord[i] = (avg_x1, avg_y1, avg_x2, avg_y2)
        i += 1
print("Num Parking Lanes: ", len(rect_coord))
buff = 7  # 微调
for key in rect_coord:
    tup_topLeft = (int(rect_coord[key][0] - buff), int(rect_coord[key][1]))
    tup_botRight = (int(rect_coord[key][2] + buff), int(rect_coord[key][3]))
    cv.rectangle(rect_image, tup_topLeft,tup_botRight,(0,255,0),3)
cv_show('rect_image', rect_image)
# 每个区域画出横线
delineated = np.copy(image)
gap = 15.5  # 同一列中相邻停车位之间的纵向距离
spot_pos = {}
tot_spots = 0
#微调
adj_y1 = {0: 20, 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: 30, 1: 50, 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:-15, 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: 15, 2:15, 3:15, 4:15, 5:15, 6:15, 7:15, 8:10, 9:10, 10:10, 11:0}

for key in rect_coord:
    tup = rect_coord[key]
    x1 = int(tup[0] + adj_x1[key])
    x2 = int(tup[2] + adj_x2[key])
    y1 = int(tup[1] + adj_y1[key])
    y2 = int(tup[3] + adj_y2[key])
    cv.rectangle(delineated, (x1, y1), (x2, y2), (0, 255, 0), 2)
    num_splits = int(abs(y2-y1) // gap)
    for i in range(num_splits + 1):
        y = int(y1 + i * gap)
        cv.line(delineated, (x1, y), (x2, y), [255, 0, 0], 2)
    if key > 0 and key < len(rect_coord) - 1:
        x = int((x1 + x2) / 2)
        cv.line(delineated, (x, y1), (x, y2), [255, 0, 0], 2)
    if key == 0 or key == (len(rect_coord) - 1):
        tot_spots += num_splits + 1
    else:
        tot_spots += 2 * (num_splits + 1)
    if key == 0 or key == (len(rect_coord) - 1):
        for i in range(num_splits + 1):
            cur_len = len(spot_pos)
            y = int(y1 + i * gap)
            spot_pos[(x1, y, x2, y+gap)] = cur_len + 1
    else:
        for i in range(num_splits + 1):
            cur_len = len(spot_pos)
            y = int(y1 + i * gap)
            x = int((x1 + x2) / 2)
            spot_pos[(x1, y, x, y+gap)] = cur_len +1
            spot_pos[(x, y, x2, y+gap)] = cur_len +2
print("total parking spaces: ", tot_spots, cur_len)
cv_show('delineated', delineated)
with open('spot_dict.pickle', 'wb') as handle:
    pickle.dump(spot_pos, handle, protocol=pickle.HIGHEST_PROTOCOL)
for spot in spot_pos:
    (x1, y1, x2, y2) = spot
    (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))
    #裁剪
    spot_img = image[y1:y2, x1:x2]
    spot_img = cv.resize(spot_img, (0,0), fx=2.0, fy=2.0)
    spot_id = spot_pos[spot]
    filename = 'spot' + str(spot_id) +'.jpg'
    print(spot_img.shape, filename, (x1,x2,y1,y2))
    cv.imwrite(os.path.join('cnn_data', filename), spot_img)
weights_path = 'D:/D/download/car1.h5'
model = load_model(weights_path)
class_dictionary = {}
class_dictionary[0] = 'empty'
class_dictionary[1] = 'occupied'
predicted_images = np.copy(image)
overlay = np.copy(image)
# cv_show('predicted_images', predicted_images)
cnt_empty = 0
all_spots = 0
for spot in spot_pos.keys():
    all_spots += 1
    (x1, y1, x2, y2) = spot
    (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))
    spot_img = image[y1:y2, x1:x2]
    spot_img = cv.resize(spot_img, (48, 48))

    # 预处理
    img = spot_img / 255.

    # 转换成4D tensor
    spot_img = np.expand_dims(img, axis=0)

    # 用训练好的模型进行训练
    class_predicted = model.predict(spot_img)
    inID = np.argmax(class_predicted[0])
    label = class_dictionary[inID]

    if label == 'empty':
        cv.rectangle(overlay, (int(x1), int(y1)), (int(x2), int(y2)), [0, 255, 0], -1)
        cnt_empty += 1
alpha = 0.5
cv.addWeighted(overlay, alpha, predicted_images, 1 - alpha, 0, predicted_images)
cv.putText(predicted_images, "Available: %d spots" % cnt_empty, (30, 95),
           cv.FONT_HERSHEY_SIMPLEX,
           0.7, (255, 255, 255), 2)
cv.putText(predicted_images, "Total: %d spots" % all_spots, (30, 125),
           cv.FONT_HERSHEY_SIMPLEX,
           0.7, (255, 255, 255), 2)
cv_show('predicted_images', predicted_images)
video_name = 'D:/D/download/parking_video.mp4'
cap = cv.VideoCapture(video_name)
count = 0
while 1:
    ret, image = cap.read()
    count += 1
    if count == 5:
        count = 0

        new_image = np.copy(image)
        overlay = np.copy(image)
        cnt_empty = 0
        all_spots = 0
        color = [0, 255, 0]
        alpha = 0.5
        for spot in spot_pos.keys():
            all_spots += 1
            (x1, y1, x2, y2) = spot
            (x1, y1, x2, y2) = (int(x1), int(y1), int(x2), int(y2))
            spot_img = image[y1:y2, x1:x2]
            spot_img = cv.resize(spot_img, (48, 48))

            # 预处理
            img = spot_img / 255.

            # 转换成4D tensor
            spot_img = np.expand_dims(img, axis=0)

            # 用训练好的模型进行训练
            class_predicted = model.predict(spot_img)
            inID = np.argmax(class_predicted[0])
            label = class_dictionary[inID]

            if label == 'empty':
                cv.rectangle(overlay, (int(x1), int(y1)), (int(x2), int(y2)), color, -1)
                cnt_empty += 1

        cv.addWeighted(overlay, alpha, new_image, 1 - alpha, 0, new_image)

        cv.putText(new_image, "Available: %d spots" % cnt_empty, (30, 95),
                   cv.FONT_HERSHEY_SIMPLEX,
                   0.7, (255, 255, 255), 2)

        cv.putText(new_image, "Total: %d spots" % all_spots, (30, 125),
                   cv.FONT_HERSHEY_SIMPLEX,
                   0.7, (255, 255, 255), 2)
        cv.imshow('frame', new_image)
        if cv.waitKey(10) & 0xFF == ord('q'):
            break

cv.destroyAllWindows()
cap.release()

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Unicornlyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值