用Matlab实现路口车量的计数

最近有一个作业,用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);
end
zhongshu=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=[];
end

zhongshu=jishu(1)+jishu(2)+jishu(3)+jishu(4);
zhongshu     

matlab用了没想象中的差,还是能勉强进行实时计数,如果想减少时间,可以进行跳帧处理。
对车流量的其他操作可以看接下来的两篇博客

  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 33
    评论
### 回答1: 通过使用Matlab实现教室人数计数需要以下步骤: 1. 导入图像:使用Matlab中的`imread`函数导入教室的图像。 2. 图像预处理:对导入的图像进行预处理,以提高人数计数的准确性。可以进行图像增强,去除噪声和背景减除等操作。 3. 人体检测:使用Matlab中的人体检测算法,如HOG(方向梯度直方图)或Cascade Object Detector进行人体检测。这些算法可以帮助识别和标定图像中的人体。 4. 目标识别和计数:根据人体检测的结果,可以识别和计数图像中的人体。可以使用Matlab中的图像处理函数进行目标识别和计数。 5. 统计结果:根据目标识别和计数的结果,使用Matlab的统计函数对人数进行计算和分析。可以统计总人数、平均人数等统计指标。 6. 结果显示:最后,使用Matlab的图像显示函数将计算得到的人数显示在图像上,可以通过数值或者在图像上标记的方式显示计数结果。 需要注意的是,人数计数算法的准确性和可靠性可能会受到各种因素的影响,如图像质量、光线条件、人体姿势等。在实际应用中,可能需要对算法进行优化和调整,以提高计数结果的准确性。 ### 回答2: 在使用MATLAB实现教室人数计数的过程中,我们可以利用计算机视觉的技术来实现。首先,我们需要使用一个摄像头或者视频设备来获取教室场景的实时图像。然后,通过图像处理技术,我们可以检测出图像中的人体轮廓。 在MATLAB中,我们可以利用图像处理工具箱提供的函数来实现人体轮廓检测。首先,我们需要将图像转换为灰度图像,然后利用二值化方法来将图像转换为黑白图像。接下来,我们可以使用形态学操作,例如腐蚀和膨胀,来去除图像中的噪声,并将人体轮廓更加清晰地显示出来。 在获取到清晰的人体轮廓后,我们可以使用轮廓检测算法来计算图像中的人数。一种常用的方法是基于轮廓的面积计算。我们可以利用MATLAB提供的函数来计算图像中每个人体轮廓的面积,并设定一个面积阈值,将面积小于该阈值的轮廓排除。最后,统计剩余的轮廓数量即可得到教室中的人数。 要给予计数的准确性,我们可能还需要考虑其他因素,例如遮挡、光照变化等。可以通过使用更复杂的图像处理算法或者结合其他传感器数据来提高计数的精度。 在实施这个任务时,我们还需要考虑软件的实时性和计算效率。为了使用实时图像并实时计算人数,我们可能需要优化算法和代码,以提高计算速度和准确性。 总之,通过MATLAB实现教室人数计数可以利用图像处理的技术,结合MATLAB提供的函数和工具箱来实现。这项任务可以帮助监控教室人数,并为教育机构的管理和安全提供参考。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值