基于OpenCV构建停车场车位识别项目

2023-05-16

OpenCV是一个基于(开源)发行的跨平台计算机视觉库,能实现图像处理和计算机视觉方面的很多通用算法。车位识别的图像处理过程如图所示。

在python中设置完所有内容后, 最重要的依赖关系将是OpenCV库。通过pip将其添加到虚拟环境中,可以运行pip install opencv-python
要检查所有设置是否正确,我们可以使用以下cv2.__version__命令打印环境中可用的当前OpenCV版本。


首先处理旋转矩形

从图中可以看到,由于视频拍摄角度的问题,车位不是横平竖直的,并且车位在屏幕上的大小和角度也是不相同的。需要用到旋转矩形的操作,并调整单个矩形框使其能够用于所有车位。

假设对图片上任意点( x , y x,y x,y),绕一个坐标点( r x 0 , r y 0 r_{x0},r_{y0} rx0,ry0)顺时针旋转a角度后的新的坐标设为 ( x 0 , y 0 ) (x_0, y_0) (x0,y0),则有公式:
x 0 = ( x − r x 0 ) c o s a − ( y − r y 0 ) s i n a + r x 0 x_0=(x-r_{x_0})cosa-(y-r_{y_0})sina+r_{x_0} x0=(xrx0)cosa(yry0)sina+rx0
y 0 = ( x − r x 0 ) s i n a + ( y − r y 0 ) c o s a + r y 0 , y_0=(x-r_{x_0})sina+(y-r_{y_0})cosa+r_{y_0}, y0=(xrx0)sina+(yry0)cosa+ry0,
根据此公式,创建函数完成矩阵旋转操作。

下面是实现的代码:

# 矩形框顺时针旋转
import cv2
import math


# 传入旋转的参考点坐标,矩形框左上角坐标(x,y),框的宽w和高h,旋转角度a
def angleRota(center_x, center_y, x, y, w, h, a):
    # 角度转弧度
    a = (math.pi / 180) * a
    # 旋转前左上角坐标
    x1, y1 = x, y
    # 右上角坐标
    x2, y2 = x + w, y
    # 右下角坐标
    x3, y3 = x + w, y + h
    # 左下角坐标
    x4, y4 = x, y + h

    # 旋转后的左上角坐标,像素坐标是整数
    px1 = int((x1 - center_x) * math.cos(a) - (y1 - center_y) * math.sin(a) + center_x)
    py1 = int((x1 - center_x) * math.sin(a) + (y1 - center_y) * math.cos(a) + center_y)
    # 右上角坐标
    px2 = int((x2 - center_x) * math.cos(a) - (y2 - center_y) * math.sin(a) + center_x)
    py2 = int((x2 - center_x) * math.sin(a) + (y2 - center_y) * math.cos(a) + center_y)
    # 右下角坐标
    px3 = int((x3 - center_x) * math.cos(a) - (y3 - center_y) * math.sin(a) + center_x)
    py3 = int((x3 - center_x) * math.sin(a) + (y3 - center_y) * math.cos(a) + center_y)
    # 左下角坐标
    px4 = int((x4 - center_x) * math.cos(a) - (y4 - center_y) * math.sin(a) + center_x)
    py4 = int((x4 - center_x) * math.sin(a) + (y4 - center_y) * math.cos(a) + center_y)

    # 保存每一个角的坐标
    pt1 = (px1, py1)
    pt2 = (px2, py2)
    pt3 = (px3, py3)
    pt4 = (px4, py4)

    # 存储每个角的坐标
    angle = [pt1, pt2, pt3, pt4]

    # 返回调整后的坐标
    return angle


# 绘制旋转后的矩形框
def drawLine(img, angle, color, thickness):
    # 分别绘制四条边
    cv2.line(img, angle[0], angle[1], color, thickness)
    cv2.line(img, angle[1], angle[2], color, thickness)
    cv2.line(img, angle[2], angle[3], color, thickness)
    cv2.line(img, angle[3], angle[0], color, thickness)

    # 返回绘制好旋转矩形的图像
    return img


# 矩形旋转
def recRota(img, center_x, center_y, x1, y1, w, h, rota, draw=True):
    '''
    img: 原图像
    (center_X, center_y): 旋转参考点的坐标
    (x1, y1): 矩形框左上角坐标
    w: 矩形框的宽
    h: 矩形框的高
    rota: 顺时针的旋转角度,如:30°
    '''

    color = (255, 255, 0)  # 绘制停车线的线条颜色
    thickness = 2  # 停车线线条宽度

    # (1)计算旋转一定角度后的四个角的坐标
    angle = angleRota(x1, y1, x1, y1, w, h, rota)

    # (2)绘制旋转后的矩形
    if draw == True:
        img = drawLine(img, angle, color, thickness)

        # 返回绘制后的图像,以及矩形框的四个角的坐标
        return img, angle

    else:
        return angle

处理单帧图像,划分车位

绘制后的单帧图像如图所示

import cv2

video = cv2.VideoCapture('./input.mp4')

ret, cap = video.read()

cv2.imwrite('./first.jpg', cap)

处理视频,分割出所有车位

在对单帧图像处理时,已将所有车位分割出来,并记录下左上角坐标。由于每个车位框是倾斜的,如果要分割出每个车位,必须使用切片方法,但切片出来的图像是横平竖直的。因此针对每一个车位框,都以该框的左上角为旋转参考,旋转整张帧图像,将车位框摆正之后再进行切片。

下面是实现的代码:

# w, h = 90, 160  # 矩形框的宽和高
    # w, h = 70, 130
    w, h = 90, 160
    # 遍历所有的矩形框坐标
    for pos in posList:
        # 得到旋转后的矩形的四个角坐标,传入原图,旋转参考点坐标,矩形框左上角坐标,框的宽w和高h,逆时针转4°
        angle = recRota(imgDilate, pos[0], pos[1], pos[0], pos[1], w, h, -5, draw=False)  # 裁剪的车位不绘制车位图

        # (5)裁剪所有的车位框,由于我们的矩形是倾斜的,先要把矩形转正之后再裁剪
        # 变换矩阵,以每个矩形框的左上坐标为参考点,顺时针寻转4°,旋转后的图像大小不变
        rota_params = cv2.getRotationMatrix2D(angle[0], angle=-4, scale=1)

        # 旋转整张帧图片,输入img图像,变换矩阵,指定输出图像大小
        rota_img = cv2.warpAffine(imgDilate, rota_params, (img_w, img_h))

        # 裁剪摆正了的矩形框,先指定高h,再指定宽w
        imgCrop = rota_img[pos[1]:pos[1] + h, pos[0]:pos[0] + w]

        # 显示裁剪出的图像
        cv2.imshow('imgCrop', imgCrop)

处理像素点

处理像素点是车位识别的难点,对于采集到的24位真彩色位图图像文件所需存储量大,图像需要占用大量系统资源,不利于图像的快速处理。

灰度图只包含亮度信息,不含彩色信息,有利于图像的处理,故在对图像进行处理前应先将其转化为灰度图。

由于在拍摄过程中,受各种主客观因素的影响,我们获得的车辆图像和实际的需要存在某种程度的差异,如果差异过大,会造成图像分割和识别的困难,严重时甚至会使分割和识别根本无法进行。为此,本文采取一些图像增强方法来综合处理。

(1)二值化方法
图像的二值化是最简单的图像处理技术,一般都跟具体算法联系,本技术中对滤波后的灰度图转换为二值图,采用自适应阈值方法。

(2)中值滤波

中值滤波是一种局部平均平滑技术,在一定条件下,中值滤波可以克服线性滤波器所带来的图像细节模糊,而且对滤除脉冲干扰及颗粒噪声最为有效。

(3)膨胀

膨胀操作就是将图像(或图像的一部分区域,称之为A)与核(称之为B)进行卷积。核可以是任何形状和大小,它拥有一个单独定义出来的参考点,我们称其为锚点。

代码实现如下:

while True:

    # 记录有几个空车位
    spacePark = 0

    # 返回图像是否读取成功,以及读取的帧图像img
    success, img = cap.read()
    if img is None:
                break
    # 为了使裁剪后的单个车位里面没有绘制的边框,需要在画车位框之前,把原图像复制一份
    imgCopy = img.copy()

    # 获得整每帧图片的宽和高
    img_w, img_h = img.shape[:2]  # shape是(w,h,c)

    # ==1== 转换灰度图,通过形态学处理来检测车位内有没有车
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # ==2== 高斯滤波,卷积核3*3,沿x和y方向的卷积核的标准差为1
    imgGray = cv2.GaussianBlur(imgGray, (3, 3), 1)

    # ==3== 二值图,自适应阈值方法
    imgThresh = cv2.adaptiveThreshold(imgGray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                      cv2.THRESH_BINARY_INV, 101, 20)

    # ==4== 删除零散的白点,
    # 如果车位上有车,那么车位上的像素数量(白点)很多,如果没有车,车位框内基本没什么白点
    imgMedian = cv2.medianBlur(imgThresh, 5)

    # ==5== 扩张白色部分,膨胀
    kernel = np.ones((3, 3), np.uint8)  # 设置卷积核
    imgDilate = cv2.dilate(imgMedian, kernel, iterations=1)  # 迭代次数为1

    # 由于这个视频比较短,就循环播放这个视频
    if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
        # 如果当前帧==总帧数,那就重置当前帧为0
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

三种方法处理后的图像分别如图所示。

车位检测

我们的检测思路是:通过计算每个车位框内的像素个数来判断该车位内是否有车。经过上述处理后,我们计算每个分割出来的车位框中的白点个数,返回灰度值不为0的像素数量。经过分析,如果白点数量大于1800,那么就表明车位上有车。

代码实现如下:

        count = cv2.countNonZero(imgCrop)

        # 将计数显示在矩形框上
        cv2.putText(imgCopy, str(count), (pos[0] + 5, pos[1] + 20), cv2.FONT_HERSHEY_COMPLEX, 0.8, (0, 255, 255), 2)

        # (7)确定车位上是否有车
        if count < 3000:  # 像素数量小于3000辆就是没有车
            color = (0, 255, 0)  # 没有车的话车位线就是绿色
            spacePark += 1  # 每检测到一个空车位,数量就加一
        else:
            color = (0, 0, 255)  # 有车时车位线就是红色

最后我们的检测结果如图所示。

现在,我们就构建好了一个停车场车位识别的系统!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于OpenCV构建停车场车位识别项目 的相关文章

  • 在OpenCV Python中编写4通道以上图像

    这对我来说是一个持续的挑战 我正在尝试使用 openCV 将两个 3 RGB 图像组合成一个 6 通道 TIFF 图像 到目前为止我的代码如下 import cv2 import numpy as np im1 cv2 imread im1
  • 如何使用 Python 3 在 OpenCV 3 上正确加载 cv2.KeyPoint 和描述符?

    有一天 我不得不恢复一个使用 OpenCV 3 和 Python 2 7 的旧项目 在此代码中 要加载 cv2 KeyPoint 我执行以下操作 import numpy as np import cPickle import cv2 ke
  • 从一个 Mat 复制到另一个 Mat 仅接近黑色像素

    I have Mat difference其中有一些黑色像素 或者几乎是黑色像素 gt 如果发生地震 建筑物会移动等 并且Mat current它由具有自然色彩的真实图像组成 我想替换中的像素Mat current这些黑色像素Mat dif
  • 在 python + openCV 中使用网络摄像头的问题

    我正在使用以下代码使用 openCV python 访问我的网络摄像头 import cv cv NamedWindow webcam feed cv CV WINDOW AUTOSIZE cam cv CaptureFromCAM 1 然
  • 构建 OpenCV 时出错 :: MonitorFromRect 未在此范围内声明

    我试图建立OpenCV version 2 4 8与它一起使用CodeBlocks and MinGw 我按照以下指示进行操作here http kevinhughes ca tutorials opencv install on wind
  • 使用 Azure 机器学习检测图像中的符号

    4年前我发帖这个问题 https stackoverflow com q 6999920 411094不幸的是 得到的一些答案超出了我的技能水平 我刚刚参加了一次构建巡演会议 他们在会上谈论了机器学习 这让我想到了使用 ML 来解决我的问题
  • 跟踪白色背景中的白球(Python/OpenCV)

    我在 Python 3 中使用 OpenCV 来检测白场上的白 黑球 并给出它的精确 x y 半径 和颜色 我使用函数 cv2 Canny 和 cv2 findContours 来找到它 但问题是 cv2 Canny 并不总是检测到圆的完整
  • 如何计算立体视觉的基本矩阵

    我正在尝试编写一些代码来计算基本矩阵以确定立体图像之间的关系 我从大多数人推荐的 Hartley 和 Zisserman 书开始 但它没有任何实际示例 并且示例代码是在 MATLAB 中 而我没有 然后我切换到这个比较实用 里面有实际例子
  • 如何获得垂直线穿过的完整内轴线?

    我有一个图像 我想获取穿过其中轴的像素 我尝试使用骨架化 and 中轴方法来获取它们 但这两种方法都返回比相应对象短的一维线 这是带有示例图像的代码 gt gt gt import skimage filter gt gt gt impor
  • 如何使用Java OpenCV

    我正在使用图像处理开始我的最后一年项目 并希望完成类似的事情this http www youtube com watch v EPai5f2sWaA 它是人体和物体检测的结合 我真的很想用 Java 来做 因为我在 C 方面的经验很少 I
  • OpenCV 完美识别物体

    我有一个应用程序 我想一次跟踪 2 个在图片中相当小的对象 该应用程序应该在 Android 和 iPhone 上运行 因此算法应该是高效的 对于我的客户来说 如果我们提供一些模式以及附加到要跟踪的对象的软件 以获得易于识别的目标 那就完全
  • OpenCV:如何使用图像计算相机和物体之间的距离?

    我是 OpenCV 的新手 我正在使用以下公式来计算距离 distance to object mm focal length mm real height of the object mm image height pixels obje
  • Haar训练时正样本和负样本使用多少张图片?

    我已经阅读了大量有关 Haar 训练的内容 但我不清楚应该为正样本集和负样本集使用多少图像 我看到建议使用很多图像 有些人推荐数千张 我也不清楚正负样本图像的数量是否应该相同 这是关于 Haar 训练的最佳教程 你试过这个吗 http no
  • 使用 cv2 在 python 中创建多通道零垫

    我想用 cv2 opencv 包装器在 python 中创建一个多通道 mat 对象 我在网上找到了一些例子 其中 c Mat zeros 被 numpy zeros 替换 这看起来不错 但似乎没有多通道类型适合 看代码 import cv
  • 使用 OpenCV 和 Python 叠加两个图像而不丢失颜色强度

    如何叠加两个图像而不损失两个图像的颜色强度 我有图像1和图像2 2 我尝试使用 0 5 alpha 和 beta 但它给我的合并图像的颜色强度只有一半 dst cv2 addWeighted img1 0 5 img2 0 5 0 但是当我
  • 如何将 OpenCV 的测试框架与 CMake 结合使用?

    好像 OpenCV 有一个测试框架 https github com Itseez opencv tree ef91d7e8830c36785f0b6fdbf2045da48413dd76 modules ts include opencv
  • 在OpenCV中将YUV转换为BGR或RGB

    我有一个电视采集卡 其输入内容为 YUV 格式 我在这里看到了与此问题类似的其他帖子 并尝试尝试所述的所有可能的方法 但它们都没有提供清晰的图像 目前最好的结果是 OpenCVcvCvtColor scr dst CV YUV2BGR 函数
  • 在 Python 中使用音频流 RTMP 通过管道和 OpenCV 到 FFmpeg

    我正在尝试使用音频流式传输 FFmpeg 我将在下面展示我的代码 导入模块 import subprocess as sp 创建变量 rtmpUrl rtmp a rtmp youtube com live2 key camera path
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np

随机推荐

  • 10. Regular Expression Matching

    10 Regular Expression Matching Given an input string s and a pattern p implement regular expression matching with suppor
  • 866. Prime Palindrome

    866 Prime Palindrome Find the smallest prime palindrome greater than or equal to N Recall that a number is prime if it s
  • CMakeLists用法总结

    分一下几个方面来描述 xff1a 1 每一个LIB要编译成静态库或动态库如何描述 xff0c 每一个TOOL要编译成可执行文件如何描述 xff1f 2 LIB和TOOL可能会依赖于其他LIB xff0c 该如何描述 xff1f 3 每个LI
  • 声明变量为类成员变量(静态变量)的条件

    建议在全部具备下列条件的情况下使用静态变量 1 静态所包含的对象体积较大 xff0c 占用的内存比较大时 xff1a 2 变量所包含的对象数据稳定 3 变量包含的对象生命周期比较长时 4 用于该类的对象实例化之后 xff0c 实例的数据共享
  • HDFS读流程

    文章目录 HDFS读流程读流程的概述读流程大体步骤对逻辑图的解释读流程代码 剖析OPEN方法客户端类关系图NameNode数据存储逻辑图 服务端方法关系图 对Block列表进行排序 剖析READ方法数据传输格式客户端方法关系图服务端方法关系
  • 应用层log函数的写法

    int my log const char format va list args FILE fp fp 61 fopen 34 tmp my log 34 34 a 43 34 if fp fprintf stderr 34 fp is
  • 工程计算流体力学软件FloEFD

    推荐一款工程计算流体力学软件FloEFD 此前一直使用ICEM 43 FLUENT软件 xff0c 后来由于工作原因 xff0c 使用的机会逐渐变少了 对不少人而言 xff0c CFD通常作为一种工程的辅助工具 xff0c 不想花太多精力
  • #统计整数个数(指针)

    以下面这题为例 xff1a 题目内容 xff1a 输入一个字符串 xff0c 其包括数字和非数字字符 xff0c 如 xff1a a123x456 17935 098tab xff0c 将其中连续的数字作为一个整数 xff0c 依次存放到数
  • 富斯i6B接收机与pixhawk连接

    pix接收PPM编码信号 xff0c 传统PWM接收器不能直接接收 xff08 例如FS ia6 xff09 xff0c 通常需要PWM转PPM转接板 xff0c 或者直接采用PPM输出的接收器 xff08 例如FS ia6B xff09
  • mission planner飞行模式设置

    我采用的富斯i6遥控器 xff0c 可以设置三种飞行模式 飞行模式中有六种模式 xff0c 在哪三个通道设置会与遥控器对应呢 xff1f 首先在 遥控器校准 选 项观察切换遥控器 模式时 输出的pwm值 xff1a 三个值分别为1000 1
  • ArduPilot Tutorial(PDF版)及ArduPilot飞行模式介绍

    ArduPilot官方Tutorial PDF 2017 2 http download csdn net download xiaoshuai537 10262086 ArduPilot中有14种常用的模式 xff1a 依赖GPS的模式有
  • PX4飞行模式-多旋翼

    手动模式 xff08 1 xff09 ARCO xff1a 特技模式 遥控器输入被转换为横滚 俯仰和偏航速度 xff0c 当摇杆回中时飞行器不会保持平衡 xff0c 可以用于翻滚等特技飞行 xff08 2 xff09 RATTITUDE x
  • 《PID控制算法的C语言实现》学习笔记

    1 PID算法原理 如果偏差为0 xff0c 则比例环节不起作用 xff1b 积分环节主要是用来消除静差 xff0c 即系统稳定后输出值和设定值之间的差值 xff1b 微分环节则反映了偏差信号的变化规律 xff0c 根据偏差信号的变化趋势来
  • 跟我一起写Makefile(整理版)

    跟我一起写Makefile 陈皓 xff08 博客地址 xff1a http blog csdn net haoel article details 2886 xff09 整理的PDF文件 xff1a http download csdn
  • PX4 Makefile分析解读

    参考文章 xff1a PX4源码的Makefile详细理解 http blog csdn net linkcian article details 79152724 感谢原文作者 主要分析 make px4fmu v2 default编译流
  • CREO工程图学习笔记

    CREO工程图技术手册 学习笔记 1 小功能 不同窗口切换操作 xff1a 视图 激活 材料设置 xff1a 文件 准备 模型属性 2 视图创建 插入视图 xff1a 图纸上长按右键 插入普通视图插入投影视图 xff1a 选择母视图 xff
  • 操作系统清华向勇陈渝版笔记(七) 进程与线程 PCB TCB 进程挂起 用户线程 内核线程 轻量级进程 僵尸队列

    7 1 进程定义 OS系统从只能跑一个程序到能跑多个 进程可以描述程序的执行过程 进程 xff1a 一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程 只有当一个程序被OS加载到内存中 xff0c cpu对其执行时 xff0c 这
  • 基于stm32F103HAL库+cubemx+freertos无感无刷电机BLDC控制程序开发

    基于stm32F103HAL库 43 cubemx 43 freertos无感无刷电机BLDC控制程序开发 最近在做一个舵机控制项目 xff0c 控制对象为大功率无感无刷电机 xff0c 网上搜遍了资源 xff0c 貌似这方面的资源真得十分
  • C++思路

    1 统计英文单词 在进行文章重复度检查时 xff0c 经常需要统计一段英文中的单词数量 xff0c 并找出长度最长的单词 设有如下定义 xff1a char str 500 编写程序 xff0c 通过利用cin getline str 50
  • 基于OpenCV构建停车场车位识别项目

    OpenCV是一个基于 xff08 开源 xff09 发行的跨平台计算机视觉库 xff0c 能实现图像处理和计算机视觉方面的很多通用算法 车位识别的图像处理过程如图所示 在python中设置完所有内容后 xff0c 最重要的依赖关系将是Op