Opencv实现停车位识别

本文介绍了一种基于计算机视觉的智能车位检测系统实现方法。通过摄像头捕捉图像并运用图像处理技术如高斯去噪、二值化及腐蚀操作等,识别车位占用情况。系统通过鼠标交互标注车位位置并保存坐标信息,方便后续调用。
PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

1.实现的思路

(1)首先使用一个处理画框的程序,将图片中的有车和无车的停车位给画出来,并且保存坐标(如果画错了,将鼠标移至要删除的框中,右击鼠标,即可删除);

#定义回调函数
def mouseClick(events,x,y,flags,params):
    #按下鼠标左键,将点击的坐标(x,y)保存到position列表中
    if (events&cv2.EVENT_LBUTTONDOWN==cv2.EVENT_LBUTTONDOWN):
        position.append((x,y))
    #按下鼠标右键时,移除选中的框
    if (events&cv2.EVENT_RBUTTONDOWN==cv2.EVENT_RBUTTONDOWN):
        for i,pos in enumerate(position):
            (x1,y1)=pos
            if (x1<x<x1+img_width and y1<y<y1+img_height):
                position.pop(i)

在这里插入图片描述
(2)画好之后,关闭窗口,即可看到已经保存好坐标的文件,下次再运行程序时,不用再画框;程序会读出当前文件,将之前保存好的坐标加载出画出框。

#首先查看文件是否已经包含了CarParkPos文件
try:
    with open('CarParkPos','rb') as fp:
        position=pickle.load(fp)
except:
    # 存储所有停车位的坐标列表
    position=[]

在这里插入图片描述
(3)主程序的思路
将摄像头读取的图片进行处理
Opencv基础知识点:
https://blog.youkuaiyun.com/Keep_Trying_Go/article/details/125351256
高斯去噪:
https://mydreamambitious.blog.youkuaiyun.com/article/details/125203273
局部二值化:
https://mydreamambitious.blog.youkuaiyun.com/article/details/125249121
中值滤波:
https://mydreamambitious.blog.youkuaiyun.com/article/details/125204641
Opencv中获取卷积核:
https://mydreamambitious.blog.youkuaiyun.com/article/details/125265838
腐蚀操作:
https://mydreamambitious.blog.youkuaiyun.com/article/details/125265431

#转换为灰度图
    gray=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2GRAY)
    #高斯去噪
    gauss=cv2.GaussianBlur(src=gray,ksize=(3,3),sigmaX=0)
    #图像二值化处理
    thresh=cv2.adaptiveThreshold(src=gauss,maxValue=255,adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
            thresholdType=cv2.THRESH_BINARY_INV,blockSize=21,C=16)
    # 中值滤波操作
    median=cv2.medianBlur(src=thresh,ksize=3)
    #腐蚀操作
    dilate=cv2.dilate(src=median,kernel=kernel,iterations=1)
    for pos in position:
        (x,y)=pos
        mask=dilate[y:y+img_height,x:x+img_width]
        # cv2.imshow(str(x*y),mask)
        #返回灰度值不为0的像素数,可用来判断图像是否全黑。
        count=cv2.countNonZero(mask)
        #当计算的count低于800,表示是一个空位
        if count<800:
            countBlackCar+=1
            color=(0,255,0)
            thickness=3
        else:
            color=(0,0,255)
            thickness=2

        cv2.rectangle(img=frame, pt1=(pos[0], pos[1]),
                      pt2=(pos[0] + img_width, pos[1] + img_height),
                      color=color, thickness=thickness)
        cvzone.putTextRect(img=frame, text=str(count), pos=(x + 3, y + img_height - 5),
                           scale=0.8, thickness=1, offset=0,colorR=color)

参考视频教程:https://www.bilibili.com/video/BV14Z4y1Q7au?t=3992.0(建议看懂视频中的思路)
注:代码不重要,主要是学会给出的链接中这位博主的思路。使用更加简单的方法解决问题,但是呢?这种方法我认为主要是为解决那种固定摄像头拍摄的停车位,因为我们标注的坐标是固定的(但是可以利用深度学习提取有车和无车的特征进行识别,定位的可以使用Opencv来解决)。


2.整体代码实战

在这里插入图片描述

(1)ParkingSpacePicker.py

import os
import cv2
import pickle

#首先查看文件是否已经包含了CarParkPos文件
try:
    with open('CarParkPos','rb') as fp:
        position=pickle.load(fp)
except:
    # 存储所有停车位的坐标列表
    position=[]

#停车位的高宽
img_width,img_height=47,88
#定义回调函数
def mouseClick(events,x,y,flags,params):
    #按下鼠标左键,将点击的坐标(x,y)保存到position列表中
    if (events&cv2.EVENT_LBUTTONDOWN==cv2.EVENT_LBUTTONDOWN):
        position.append((x,y))
    #按下鼠标右键时,移除选中的框
    if (events&cv2.EVENT_RBUTTONDOWN==cv2.EVENT_RBUTTONDOWN):
        for i,pos in enumerate(position):
            (x1,y1)=pos
            if (x1<x<x1+img_width and y1<y<y1+img_height):
                position.pop(i)

    with open('CarParkPos','wb') as fp:
        pickle.dump(position,fp)


while True:
    img=cv2.imread('images/packing.png')
    for pos in position:
        cv2.rectangle(img=img,pt1=(pos[0],pos[1]),
                      pt2=(pos[0]+img_width,pos[1]+img_height),
                      color=(0,255,0),thickness=2)

    cv2.imshow('Packing',img)
    #设置鼠标事件
    cv2.setMouseCallback('Packing',mouseClick)
    key=cv2.waitKey(1)
    if key==27:
        break

cv2.destroyAllWindows()

if __name__ == '__main__':
    print('Pycharm')

(2)main.py

import os
import cv2
import pickle
import cvzone

with open('CarParkPos', 'rb') as fp:
    position = pickle.load(fp)

#停车位的高宽
img_width,img_height=47,88

cap=cv2.VideoCapture('video/packing-3.mp4')

def checkParkingSpace(dilate):
    countBlackCar=0
    for pos in position:
        (x,y)=pos
        mask=dilate[y:y+img_height,x:x+img_width]
        # cv2.imshow(str(x*y),mask)
        #返回灰度值不为0的像素数,可用来判断图像是否全黑。
        count=cv2.countNonZero(mask)
        #当计算的count低于800,表示是一个空位
        if count<800:
            countBlackCar+=1
            color=(0,255,0)
            thickness=3
        else:
            color=(0,0,255)
            thickness=2

        cv2.rectangle(img=frame, pt1=(pos[0], pos[1]),
                      pt2=(pos[0] + img_width, pos[1] + img_height),
                      color=color, thickness=thickness)
        cvzone.putTextRect(img=frame, text=str(count), pos=(x + 3, y + img_height - 5),
                           scale=0.8, thickness=1, offset=0,colorR=color)
    return countBlackCar

#获取卷积核
kernel=cv2.getStructuringElement(shape=cv2.MORPH_RECT,ksize=(3,3))

while cap.isOpened():
    #循环播放视频文件
    if cap.get(cv2.CAP_PROP_POS_FRAMES)==cap.get(cv2.CAP_PROP_FRAME_COUNT):
        cap.set(cv2.CAP_PROP_POS_FRAMES,0)

    ret,frame=cap.read()
    # frame=cv2.resize(src=frame,dsize=(750,600))
    height,width,channel=frame.shape
    if not ret:
        break

    #转换为灰度图
    gray=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2GRAY)
    #高斯去噪
    gauss=cv2.GaussianBlur(src=gray,ksize=(3,3),sigmaX=0)
    #图像二值化处理
    thresh=cv2.adaptiveThreshold(src=gauss,maxValue=255,adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
            thresholdType=cv2.THRESH_BINARY_INV,blockSize=21,C=16)
    # 中值滤波操作
    median=cv2.medianBlur(src=thresh,ksize=3)
    #腐蚀操作
    dilate=cv2.dilate(src=median,kernel=kernel,iterations=1)

    cntCar=checkParkingSpace(dilate)

    cvzone.putTextRect(img=frame,text="BlackPosition: "+str(cntCar),
                       pos=(20,height-80),scale=1.0,thickness=2)
    cv2.imshow('img',frame)
    # cv2.imshow('thresh',thresh)
    # cv2.imshow('median',median)
    # cv2.imshow('dilate',dilate)
    key=cv2.waitKey(30)
    if key==27:
        break
cv2.destroyAllWindows()
if __name__ == '__main__':
    print('Pycharm')

(3)视频效果

停车位识别演示视频

注:视频自己做的比较差,建议读者最好自己尝试实现这个思路。


3.停车位视频下载

https://699pic.com/movie/295567.html

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

<think> 首先,用户的问题是基于OpenCV停车位识别检测方法和技术。我需要参考提供的引用内容,并确保回答结构清晰,使用中文,遵循系统级指令。 回顾系统级指令: - 行内数学表达式用$...$。 - 独立公式用$$...$$。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识如[^1]。 用户的问题是关于OpenCV停车位识别检测的方法和技术。 从引用中提取关键信息: - 引用[1]:提到使用YOLO和OpenCV进行实时检测,核心功能包括空位与占用车位识别。 - 引用[2]:涉及OpenCV和Keras的CNN网络,用于图像处理和分类,处理停车场图像。 - 引用[3]:Opencv实现停车位识别,建议看视频教程,强调思路和固定摄像头场景。 - 引用[4]:基于机器视觉的停车位识别,讨论手动操作和标记停车场边界。 - 引用[5]:使用Mask-RCNN检测汽车,基于Faster-RCNN。 综合这些,核心方法是: - 使用OpenCV进行图像预处理和处理。 - 结合深度学习模型如YOLO、CNN或Mask-RCNN进行目标检测(检测汽车或车位状态)。 - 处理固定摄像头拍摄的停车场景。 回答结构: 1. **介绍方法和技术**:基于OpenCV停车位识别检测通常包括图像预处理、车位检测和状态识别。 2. **详细步骤**: - 图像预处理:使用OpenCV进行灰度转换、滤波、边缘检测等。 - 车位检测:可能需要手动标记车位位置或使用自动方法(如轮廓检测)。 - 状态识别:使用分类模型判断车位是否空置,可能结合CNN或目标检测模型。 3. **代码示例**:提供一个简单的OpenCV和Python示例。 4. **生成相关问题**:在末尾添加相关问题。 确保内容真实可靠,基于引用。 大纲回答: - 开头:介绍基于OpenCV停车位识别方法。 - 主体: - 步骤1:图像预处理(OpenCV操作)。 - 步骤2:车位检测(固定位置或动态检测)。 - 步骤3:状态识别(使用分类或检测模型)。 - 代码示例:提供一个简单的OpenCV代码片段。 - 结尾:总结,并添加相关问题。 添加引用标识:在引用引用内容时添加。 生成相关问题: - 例如:如何优化OpenCV停车位检测的性能? - 基于深度学习的停车位检测有哪些方法? - OpenCV在固定摄像头场景下的应用? 最终回答用中文。 </think>### 基于OpenCV停车位识别检测方法和技术 基于OpenCV停车位识别检测是一种常见的计算机视觉应用,主要用于实时监控停车场车位状态(如空位或占用),帮助提升管理效率。该方法结合OpenCV的图像处理功能和深度学习模型(如CNN或目标检测算法),处理固定摄像头拍摄的停车场图像。以下是核心方法和技术步骤,参考了相关文献和实践案例[^2][^3][^4]。 #### 1. **方法概述** - **输入**:固定摄像头捕获的停车场图像或视频流。 - **输出**:车位状态(空位或占用)的可视化标记或数据。 - **核心流程**: - **图像预处理**:使用OpenCV增强图像质量。 - **车位检测**:定位停车位区域。 - **状态识别**:判断车位是否被占用。 - 整体流程基于OpenCV的实时处理能力,常结合深度学习模型提高精度[^1][^5]。 #### 2. **关键技术步骤** - **步骤1: 图像预处理(OpenCV操作)** - **目的**:减少噪声、增强特征,便于后续分析。 - **常用技术**: - **灰度转换**:将RGB图像转为灰度图,简化处理,公式:$I_{\text{gray}} = 0.299R + 0.587G + 0.114B$。 - **滤波降噪**:使用高斯滤波或中值滤波去除噪声,例如:`cv2.GaussianBlur()`。 - **边缘检测**:应用Canny算法检测车位边界线,公式:$\nabla I = \sqrt{ \left( \frac{\partial I}{\partial x} \right)^2 + \left( \frac{\partial I}{\partial y} \right)^2 }$。 - **透视变换**:校正图像畸变,确保车位区域平整(例如,使用`cv2.warpPerspective()`)。 - **引用说明**: 在固定摄像头场景中,预处理是关键步骤,能显著提升后续车位定位的准确性[^3][^4]。 - **步骤2: 车位检测** - **目的**:识别并定位图像中的停车位区域。 - **常用技术**: - **手动标记法**:对于固定停车场,预先标记车位坐标(如使用ROI区域)。OpenCV的`cv2.selectROI()`可交互式定义车位边界。 - **自动检测法**: - **轮廓检测**:使用`cv2.findContours()`提取车位轮廓(如直线组成的多边形)。 - **霍夫变换**:检测直线特征(如停车位分隔线),公式:$\rho = x \cos \theta + y \sin \theta$。 - **深度学习辅助**:结合YOLO或Mask-RCNN模型自动生成车位掩码[^1][^5]。 - **优势**:手动方法简单高效,适用于静态环境;自动方法更灵活,但需更多计算资源[^2][^3]。 - **步骤3: 状态识别** - **目的**:判断每个车位是否被车辆占用。 - **常用技术**: - **传统图像处理**: - **像素分析**:计算车位区域内像素变化(如颜色直方图对比),空车位通常更均匀。 - **运动检测**:使用背景减除(`cv2.createBackgroundSubtractorMOG2()`)检测车辆移动。 - **深度学习集成**: - **分类模型**:使用CNN(如Keras实现)训练车位图像分类器(二分类:空位/占用)。输入为裁剪的车位图像,输出概率值$P(\text{占用})$。 - **目标检测模型**:集成YOLO或Mask-RCNN直接检测车辆,判断是否覆盖车位区域[^1][^5]。 - **性能**:深度学习模型精度更高(可达90%以上),但依赖训练数据;传统方法实时性更强[^2][^4]。 #### 3. **代码示例(Python + OpenCV)** 以下是一个简化示例,展示基于OpenCV车位状态检测流程。注意:实际项目中需结合深度学习模型提升鲁棒性。 ```python import cv2 import numpy as np # 步骤1: 图像预处理 def preprocess_image(image_path): img = cv2.imread(image_path) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度转换 blur = cv2.GaussianBlur(gray, (5, 5), 0) # 高斯滤波 edges = cv2.Canny(blur, 50, 150) # Canny边缘检测 return edges # 步骤2: 车位检测(手动标记示例) def detect_parking_slots(edges): # 假设已预先标记车位坐标,实际中可用cv2.selectROI交互获取 slots = [(x1, y1, x2, y2), ...] # 车位坐标列表 return slots # 步骤3: 状态识别(简单像素分析) def check_slot_status(img, slot): x1, y1, x2, y2 = slot roi = img[y1:y2, x1:x2] # 裁剪车位区域 mean_pixel = np.mean(roi) # 计算平均像素值 if mean_pixel < 100: # 阈值判断:低值表示空位 return "Empty" else: return "Occupied" # 主流程 image_path = "parking_lot.jpg" edges = preprocess_image(image_path) slots = detect_parking_slots(edges) # 需预先定义 original_img = cv2.imread(image_path) for slot in slots: status = check_slot_status(original_img, slot) cv2.rectangle(original_img, (slot[0], slot[1]), (slot[2], slot[3]), (0, 255, 0), 2) # 绘制车位框 cv2.putText(original_img, status, (slot[0], slot[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) cv2.imshow("Parking Status", original_img) cv2.waitKey(0) ``` #### 4. **优化与挑战** - **优化方法**: - **多模型融合**:结合OpenCV预处理和YOLO检测,提升实时性与精度[^1]。 - **动态适应**:使用光流法(`cv2.calcOpticalFlowFarneback`)处理光照变化。 - **硬件加速**:部署在边缘设备(如Raspberry Pi)上,利用OpenCV的GPU支持。 - **挑战**: - **环境干扰**:雨雪或阴影可能导致误检,需增加滤波或数据增强。 - **计算资源**:深度学习模型需较高算力,可选用轻量级网络[^2][^5]。 总之,基于OpenCV停车位识别检测核心在于图像预处理和状态分类,结合深度学习可大幅提升准确性。实际应用中,建议从固定摄像头场景入手,逐步集成高级模型[^3][^4]。
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值