OpenCV计算机视觉实战(Python)| 14、项目实战:停车场车位识别

本文主要是介绍OpenCV计算机视觉实战(Python)| 14、项目实战:停车场车位识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 简介
  • 总结
    • 1、项目介绍
    • 2、步骤
    • 3、程序

简介

本节为《OpenCV计算机视觉实战(Python)》版第14讲,项目实战:停车场车位识别,的总结。

总结

1、项目介绍

统计:

  1. 有多少停车位
  2. 哪些个停车位被占据,哪些个停车位没有被占据
    在这里插入图片描述

2、步骤

  1. 选取区域:人工选择停车场所在的位置,只保存停车场所在的区域图像
  2. 预处理:灰度、边缘、霍夫
  3. 微调:针对实际的项目,由于背景是没变的,当结果不正确时,可以人为给定数据对结果进行微调
  4. 分类:以簇的形式,将每一列的停车场数据保存,保存每一列矩阵的坐标点
  5. 分割:以实际项目选取合适的值,将每一列分割成一个个小块,每一个小块代表一个停车场的位置
  6. 深度训练:以空停车位做分类训练,判断停车场某个停车位上有没有车;

3、程序

Parking.py:

class Parking:def cv_show(name, image):cv2.imshow(name, image)cv2.waitKey(0)cv2.destroyAllWindows()def select_rgb_white_yellow(self, 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 = cv2.inRange(image, lower, upper)self.cv_show('white_mask', white_mask)masked = cv2.bitwise_and(image, image, mask=white_mask)self.cv_show('masked', masked)return maskeddef convert_gray_scale(self, image):return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)def detect_edges(self, image, low_threshold=50, high_threshold=200):return cv2.Canny(image, low_threshold, high_threshold)def filter_region(self, image, vertices):"""剔除掉不需要的地方"""mask = np.zeros_like(image)if len(mask.shape)==2:cv2.fillPoly(mask, vertices, 255)self.cv_show('mask', mask)return cv2.bitwise_and(image, mask)def select_region(self, image):"""手动选择区域"""	# first, define the polygon by verticesrows, 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]vertices = np.array([[pt_1, pt_2, pt_3, pt_4, pt_5, pt_6]], dtype=np.int32)point_img = img.copy()point_img = cv2.cvtcolor(point_img, cv2.COLOR_GRAY2RGB)for point in vertices[0]:cv2.circle(point_img, (point[0], point[1]), 10, (0,0.255), 4)self.cv_show('point_img', point_img)return self.filter_region(image, vertices)def hough_lines(self, image):#阈值越大,直线越少return cv2.HoughLinesP(image, rho=0.1, theta=np.pi/10, threshold=15, minLineLength=0, maxLineGap=4)def draw_lines(self, image, lines, color=[255, 0, 0], thickness=2, make_cope=True):# 过滤霍夫变换坚持到到直线if make_copy:image = np.copy(image)cleaned = []for line in lines:for x1,y1,x2,y2 in line:if abs(y2-y1) <=1 and abs(x2-x1)>25 and abs(x2-x1)<=55:cleaned.append((x1, y1, x2, y2))cv2.line(image, (x1,y1), (x2,y2), color, thickness)print('No lines detected:', len(cleaned))return imagedef identify_blocks(self, image, lines, make_copy=TRUE):if make_copy:new_image = np.copy(image)# step1:过滤部分直线cleaned = []for line in lines:for x1, y1, x2, y2 in line:if abs(y2-y1)<=1 and abs(x2-x1)>=25 and abs(x2-x1)<=55:cleaned.append((x1,y1,x2,y2))# Step2:对直线按照x1进行排序import operatorlist1 = sorted(cleaned, key=operator.itemgetter(0,1))# Step3: 找到多个列,相当于每列是一排车clusters = {}dIndex = 0clus_dist = 10for 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# Step4:得到坐标rects = {}i = 0for key in clusters:all_list = clusters[key]cleaned = list(set(all_list))if len(cleaned) > 5:cleaned = sorted(cleaned, key = lambda tup:tup[1])avg_y1 = cleaned[0][1]avg_y2 = cleaned[-1][1]avg_x1 = 0avg_x2 = 0for tup in cleaned:avg_x1 += tup[0]avg_x2 += tup[2]avg_x1 = avg_x1/len(cleaned)avg_x2 = avg_x2/len(cleaned)rects[i] = (avg_x1, avg_y1, avg_x2, avg_y2)i +=1print('Num parking Lanes:', len(rects))# Step5:得到坐标rects = {}i = 0for key in clusters:all_list=cluseters[kye]cleaned = list(set(all_list))if len(cleaned) > 5:cleaned = sorted(cleaned, key=lambda tup:tup[1])avg_y1 = cleaned[0][1]avg_y2 = cleaned[-1][1]avg_x1 = 0avg_x2 = 0for tup in cleaned:avg_x1 += tup[0]avg_x2 += tup[2]avg_x1 = avg_x1/len(cleaned)avg_x2 = avg_x2/len(cleaned)rects[i] = (avg_x1, avg_y1, avg_x2, avg_y2)i+=1print('Num Parking Lanes:', len(rects))# Step5: 把列矩形给画出来buff = 7for key in rects:tup_topLeft = (int(rects[key][0] - buff), int(rects[key][1]))tup_botRight = (int(rects[key][2] + buff), int(rects[key][3]))cv2.rectangle(new_image, tup_topLeft, tup_botRight, (0,255,0),3)return new_image, rectsdef draw_parking(self, image, rects, make_copy=True,, color=[255,0,0], thickness=2,save=True):if make_copy:new_image = np.copy(image)gap = 15.5spot_dict = {} # 字典:一个车位对应一个位置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 = {}adj_x2 = {}for key in rects:tup = rects[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])cv2.rectangle(new_image, (x1,y1), (x2, y2), (0,255,0), 2)num_splits = int(abs(y2-y1)//gap)for in in range(0, num_splits +1):y = int(y1 + i*gap)cv2.line(new_image, (x1, y), (x2, y), color, thickness)if key>0 and key<len(rects)-1:# 竖直线x = int((x1+x2)/2cv.line(new_image, (x, y1), (x,y2), color, thickness)# 计算数量if key == 0 or key == (len(rects) -1):tot_spots += num_splits +1else:tot_spots += 2*(num_splits + 1)# 字典对应好if key ==9 or key == len(rects) -1):for i in range(0, num_splits +1):cur_len = len(spot_dict)y = int(y1 + i * gap)spot_dict[(x1, y, x2, y+gap)] = cur_len + 1else:for i in range(0, num_splits +1):cur_len  = len(spot_dict)y = int(y1 + i * gap)x = int((x1 + x2)/2)spot_dict[(x1, y, x, y+gap)] = cur_len + 1spot_dict[(x, y, x2, y+gap)] = cur_len + 2print('total parking spaces:', tot_spots, cur_len)if save:filename = 'with_parking.jpg'cv2.imwrite(filename, new_image)return new_image, splt_dictdef save_images_for_cnn(self, image, spot_dict, folder_name = 'cnn_data'):for spot in spot_dict.keys():(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 = cv2.resize(spot_img, (0,0), fx=2.0, fy=2.0)spot_id = spot_dict[spot]filename = 'spot' + str(spot_id) + '.jpg'print(spot_img.shape, filename, (x1,x2, y1, y2))cv2.imwrite(os.path.join(folder_name, filename), spot_img)

train.py:(神经网络训练文件,此处略去)

import numpy as np
...

main.py:(主程序)

from __future__ import division
import matplotlib.pyplot as plt
import cv2
import os,glob
import numpy as np
from PIL import Image
from keras.applications.imagenet_utils import preprocess_input
from keras.models import image
from keras.preprocessing import image
from Parking import Parking
import picklecwd = os.getcwd()def img_process(test_images, park):white_yellow_images = list(map(park.select_rgb_white_yellow, test_images))park.show_images(white_yellow_images)gray_images = list(map(park.convert_gray_scale, white_yellow_images))park.show_images(gray_images)edge_images = list(map(lambda image:park.detect_edges(image), gray_images))park.show_images(edge_images)roi_images = list(map(park.select_region, edge_images))park.show_images(roi_images)list_of_lines = list(map(park.hough_lines, roi_images))line_images = []for image, lines in zip(test_images, list_of_lines):line_images.append(park.draw_lines(image, lines))park.show_images(lien_images)rect_images = []rect_coords = []for image, lines in zip(test_images, list_of_lines):new_image, rects = park.identify_blocks(image, lines)rect_images.append(new_image)rect_coords.append(rects)park.show_images(rect_images)delineated = []spot_pos = []for image, rects in zip(test_images, rect_coords):new_image, spot_dict = park.draw_parking(image, rects)delineated.append(new_image)spot_pos.append(spot_dict)park.show_images(delineated)final_spot_dict = spot_pos[1]print(len(final_spot_dict)with open('spot_dict.pickle', 'wb') as handle:pickle.dump(final_spot_dict, handle, protocol=pickle.HIGHEST_PROTOCOL)park.save_images_for_cnn(test_images[0], final_spot_dict)return final_spot_dict
def keras_model(weights_path):model = load_model(weights_path)return model
def img_test(test_images, final_spot_dict, model, class_dictionary):for i in range(len(test_images)):predicted_images = park.predict_on_image(test_images[i], final_spot_dict, class_dictionary)if __name__ == '__main__':test_images = [plt.imread(path) for path in glob.glob('test_images/*.jpg')]weights_path = 'car1.h5'video_name = 'parking_video.mp4'class_dictionary[0] = 'empty'class_dictionary[1] = 'occupied'park = Parking()park.show_images(test_images)final_spot_dict = img_process(test_images, park)# 本文所附录出的程序代码仅到img_process处,往下的这些代码没有给出,感兴趣的可以自行看课程model = keras_model(weights_path)img_test(test_images, final_spot_dict, model, class_dictionary)video_test(video_name, final_spot_dict, model, class_dictionary)

这篇关于OpenCV计算机视觉实战(Python)| 14、项目实战:停车场车位识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760977

相关文章

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa