博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Matlab实现路口车量的计数
阅读量:6259 次
发布时间:2019-06-22

本文共 5309 字,大约阅读时间需要 17 分钟。

最近有一个作业,用matlab写一段代码来检测路口的车流量(虽然我一直喜欢用C胜过用matlab,原因你懂的,但是这是作业没办法),简单实现了下。

这里写图片描述

这是视频中的一帧图片,可以看到主要分为4个车道(应该有5个)由于视频是直行时拍的所以不考虑最右边的转弯车道,也不考虑自行车等非机动车。
首先这边使用背景差分法,由于视频的时间比较短,笔者只选用了没有车的一张图片作为背景,如果要进行长时间的计算,应该进行背景的更新,效果应该会更好一些。背景更新,可以用均值滤波法,W4法或者一些背景统计的算法。
将背景转化为灰度,;
在选取另一张图片,转化为灰度图,与原来背景灰度图进行相减,可以得到一张背景差分图片,再将背景差分图转化为二值图像,在转化为二值图像时用合适的阈值将车道上的噪声消除(有车时几乎没有噪声,无车时噪声出奇大,这可能与摄像头有关),这里转换出来的车可能被分割为大大小小多块,笔者用的时膨胀和腐蚀,将小的腐蚀掉或用膨胀将大块和小块相连接。

对整个机动车道按车道分成四部分:

这里写图片描述

可以用matlab中figure上的数据游标大致的测量出车道(图中的黑线)在图片中坐标位置,大致计算出黑线的函数表达式,方便对车道的切割。如图:

这里写图片描述

这是笔者对第一车道的分割结果。
主要代码要根据你的黑线函数式:

for u=1:a(1,1)        for v=1:a(1,2)            if(v>(u-287)/(-1.6)&&v<((u-843)/(-3)))              dst1(u,v,1)=erzhi(u,v,1);             elseif(v>((u-843)/(-3))&&v<(u+4551)/(13))              dst2(u,v,1)=erzhi(u,v,1);            elseif(v<((u+1327)/(3.2))&&v>(u+4551)/(13))               dst3(u,v,1)=erzhi(u,v,1);            elseif(v>((u+1327)/(3.2))&&v<(u+1006)/(2))               dst4(u,v,1)=erzhi(u,v,1);            end           end
这是笔者的分割,主要是将相应坐标像素复制到了四张新的图片中(额~,现在只是在分析,这种复制的方法只适合在分析时使用,实际复制出奇的慢)对每一个车道进行计数。对车的计数方法有很多种,可以选择线计数,可以选择块计数,点计数等等,这里我使用块计数,即选取某一块区域当区域中白点(二值化后车的部分),到达一定数目时表明这是有车。由于车速比较慢,不可能在一帧的时间间隔内完全驶过这个区域,所以我将区域由黑变白的时刻当成一辆车,即设置一个标志,记录这时是否有车,与记录上一帧是否有车的标志相减,如果为1,则该车道的车数加一。代码:
for u=261:281        for v=50:70            if(erzhi(u,v)==1)                mianji=mianji+1;            end        end    end    if(mianji>300)        baocun(1,2)=1;    else        baocun(1,2)=0;    end     if(baocun(1,2)-baocun(1,1)==1)        ceshu(1)=1;    else        ceshu(1)=0;    end    jishu(1)=jishu(1)+ceshu(1);    baocun(1,1)=baocun(1,2);    mianji=0;

如代码中的261到281,50到70是我选择计算的区域;

关于区域的选择,我认为也是有一定的规律的:
1.首先靠内车的几个车道由于中间没有白线,进入入口后,车辆行驶可能会有一定的变道,或者偏离原来的方相,选取地区应尽量靠近入口出,即图片的上半部分,同时应进来靠近车道的中心位置。
2.对于外车道因为有右转弯车道,车辆偏离方向的影响较小。
3.从图片中看摄像头摆放的位置在靠近内车道,外车道的车的光线反射对摄像头的影响大,还有挡风玻璃在二值时会把车切成两半,这时可能要一点膨胀,或连通域。
分析时的总代码:

src1=imread('jiebai1.jpg');src1=rgb2gray(src1);a=size(src1);erzhi=zeros(a(1,1),a(1,2),1);jishu=zeros(4,1);baocun=zeros(4,2);biaoji=zeros(2,1);ceshu=zeros(4,1);dst1=zeros(a(1,1),a(1,2),1);dst2=zeros(a(1,1),a(1,2),1);dst3=zeros(a(1,1),a(1,2),1);dst4=zeros(a(1,1),a(1,2),1);i=1;for i=1:2:216    filename='jiebai';    src2=imread([filename,num2str(i),'.jpg']);    src2=rgb2gray(src2);    dst_2=src2-src1;    dstgray=dst_2;    erzhi=im2bw(dstgray,0.25);    for u=1:a(1,1)        for v=1:a(1,2)            if(v>(u-287)/(-1.6)&&v<((u-843)/(-3)))              dst1(u,v,1)=erzhi(u,v,1);             elseif(v>((u-843)/(-3))&&v<(u+4551)/(13))              dst2(u,v,1)=erzhi(u,v,1);            elseif(v<((u+1327)/(3.2))&&v>(u+4551)/(13))               dst3(u,v,1)=erzhi(u,v,1);            elseif(v>((u+1327)/(3.2))&&v<(u+1006)/(2))               dst4(u,v,1)=erzhi(u,v,1);            end           end    end%-------------------------------对车道1    baocun(1,2)=chedao1(dst1);    if(baocun(1,2)-baocun(1,1)==1)        ceshu(1)=1;    else        ceshu(1)=0;    end    jishu(1)=jishu(1)+ceshu(1);    baocun(1,1)=baocun(1,2);%-------------------------------对车道2    baocun(2,2)=chedao2(dst2);    if(baocun(2,2)-baocun(2,1)==1)        ceshu(2)=1;    else        ceshu(2)=0;    end    jishu(2)=jishu(2)+ceshu(2);    baocun(2,1)=baocun(2,2);%-----------------------------对车道3    baocun(3,2)=chedao3(dst3);   if(baocun(3,2)-baocun(3,1)==1)        ceshu(3)=1;    else        ceshu(3)=0;    end    jishu(3)=jishu(3)+ceshu(3);    baocun(3,1)=baocun(3,2);%------------------------------对车道4    baocun(4,2)=chedao4(dst4);    if(baocun(4,2)-baocun(4,1)==1)        ceshu(4)=1;    else        ceshu(4)=0;    end    jishu(4)=jishu(4)+ceshu(4);    baocun(4,1)=baocun(4,2);    pause(0.02);endzhongshu=jishu(1)+jishu(2)+jishu(3)+jishu(4);zhongshu

其中一个子函数:

function biaoji=chedao1(erzhi)baocun=0;pengzhuang=[0,1,0;1,1,1;0,1,0];    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    erzhi=imdilate(erzhi,pengzhuang);    imshow(erzhi);    for u=261:281        for v=50:70            if(erzhi(u,v)==1)                baocun=baocun+1;            end        end    end    if(baocun>300)        biaoji=1;    else        biaoji=0;    end   % if(biaoji(2)-biaoji(1)==1)   %    jishu=1;   % else   %    jishu=0;   % end   % biaoji(1)=biaoji(2);   %baocun(2)=0;   %imshow(erzhi);end

这只是分析,面临的问题时时间太慢,无法进行实时记数。

解决方法时对图片不进行复制为4张图片(复制大概花费了进3/4的时间),直接对视频进行读帧,进行实时处理:
大致代码:

videofilename='C:\Users\Administrator\Desktop\matlab\6\jiebai.avi';video=VideoReader(videofilename);frame_number=floor(video.Duration*video.FrameRate);src1=readFrame(video);src1=rgb2gray(src1);a=size(src1);erzhi=zeros(a(1,1),a(1,2),1);jishu=zeros(4,1);baocun=zeros(4,2);biaoji=zeros(4,2);ceshu=zeros(4,1);baise=zeros(4,1);i=1;pengzhuang=[1,1,1;1,1,1;1,1,1];for b=2:frame_number    ......       src2=[];endzhongshu=jishu(1)+jishu(2)+jishu(3)+jishu(4);zhongshu

matlab用了没想象中的差,还是能勉强进行实时计数,如果想减少时间,可以进行跳帧处理。

对车流量的其他操作可以看接下来的两篇博客

你可能感兴趣的文章
[spring] Ioc 基础
查看>>
关于DataTables一些小结
查看>>
win7(windows 7)系统下安装SQL2005(SQL Server 2005)图文教程
查看>>
Hibernate的基本配置
查看>>
Python 3.5 安装geohash库后import geohash失败
查看>>
总结100个英文邮件常用例句让你写作无忧
查看>>
css3--之backface-visibility
查看>>
软件需求分析之猫咪记单词
查看>>
good vs evil
查看>>
算法28-----范围求和
查看>>
基于V4L2的视频驱动开发(1)
查看>>
zoj 1008
查看>>
VC++ CArchive及简单的文件操作方法
查看>>
使用canvas制作一个移动端画板
查看>>
android中ListView数据混乱问题
查看>>
QT学习-10/31/2012
查看>>
jQuery File Upload
查看>>
bbb板运行rtems-编写led底层驱动
查看>>
如何从零安装Mysql
查看>>
Appium简介及工作原理
查看>>