今年是个比较难说的年,又碰上疫情,几乎全国人民都赋闲在家,本着自己寒假回家后的雄心壮志,我躺了近一个多月了,增长的只有满身的肥肉,以及与日俱增的懒惰,想着去年上学时自己学习的一些笔录,也都没有再记,把自己临近寒假做课设时的一些感悟,收获都没有记下,就感觉到十分想打自己几个耳刮子,现在只留茫然的眼神,以及光想着吃的脑子,,,,,
这下就叫做去年了,去年做课设的时候,就非常疯狂的启用Python这个让我又爱又恨的东西,用它做开发,做课设,用它想实现所有能想到的想法,用Python的话,去年做课设做了一个基于Python的vissim的二次开发,还有做了一个基于Python的OpenCV的视频车流量检测,感觉这个对Python的理解还是更上了一层楼,所以现在就回忆式的写写自己当时的感悟,以及当时的一些经历。也同时激励着自己,不忘初心,希望能越走越远。
我记得第一个课设时基于的vb的vissim的二次开发,做一个单交叉口的四相位信号控制系统,当时一接到题目就很头大,因为我连相位都不知道是啥,更不懂什么叫开发,何况二次开发,而且单交叉口都是在反应了好长一时间段才反应过来的,至于vb就更不用说了,上学期的vb是61分飘过的,就记着它是个计算机语言,所以这下就头大的很,询问了老师和我涵妈(宿舍大神)之后,想用还算较熟悉的Python来做开发,同组的小伙伴也很支持,所以就用Python做了。
额,,,,具体开发过程忘了,一些想法自己当时也没记下来,现在也毫无记忆,反正就记着基于Python的vissim二次开发网上资料太少,而matlab的却很多,所以自己也是一边看基于vb的例程,一边写代码,(还参考了两位大神的一些程序,,,但恕我无知,当时居然没有记下大神的名字)最后总算是完成了一些功能,能打开vissim以及能让小车按相位走(相位时真的难整,我记弄了整整两天)
写着写着想着有必要贴一下代码(凑一下篇幅)让我去找找,,,,,
嘿,,,居然让我找到了,我以为都不见了呢(窃喜嘻嘻嘻嘻)
import win32com.client as com
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
#加载接口及文件
vissim_com = com.Dispatch("Vissim.Vissim")
vissim_com.LoadNet('F:\\Exe\\新建文件夹\\02.inp')
vnet = vissim_com.net
SgCtrls = vnet.SignalControllers
DaCtrls = vnet.DataCollections
vehins = vnet.VehicleInputs
SgGrps1 = SgCtrls.GetSignalControllerByNumber(1).SignalGroups.GetSignalGroupByNumber(1)
SgGrps2 = SgCtrls.GetSignalControllerByNumber(1).SignalGroups.GetSignalGroupByNumber(2)
SgGrps3 = SgCtrls.GetSignalControllerByNumber(1).SignalGroups.GetSignalGroupByNumber(3)
SgGrps4 = SgCtrls.GetSignalControllerByNumber(1).SignalGroups.GetSignalGroupByNumber(4)
#vehin1 = vehins.GetVehicleInputByNumber(1)
#vehin2 = vehins.GetVehicleInputByNumber(8)
#vehin3 = vehins.GetVehicleInputByNumber(5)
#vehin4 = vehins.GetVehicleInputByNumber(2)
# 设置仿真参数
Sim = vissim_com.simulation
Sim.RandomSeed = 60
Sim.Resolution = 10
Sim.Period = 1200
# 打开评价
eval = vissim_com.Evaluation
eval.SetAttValue('DATACOLLECTION', True)
dceval = eval.DataCollectionEvaluation
dceval.SetAttValue('FILE', True)
dceval.SetAttValue('COMPILED', True)
vegicle_flowrate = [1000,1280,900,1200]#车流量设置
#vegicle_flowrate_1 = [1340,1280,1520,1640]
#Webster算法设置
Ge = 0
c0 = 0
ge1 = 0
ge2 = 0
ge3 = 0
ge4 = 0
re1 = 0
re2 = 0
re3 = 0
re4 = 0
si = 1650*4
L = 4*(3+3-3)#损耗时间
Yi = []
Y = 0
for i in vegicle_flowrate:
Yi = i/(1650*4)
Y = 0.1515+0.1939+0.1363+0.1818
c0 = (1.5*L+5)/(1-Y)
Ge = c0-L-0.35
ge1 = Ge*(0.1515)/Y
ge2 = Ge*(0.1939)/Y
ge3 = Ge*(0.1363)/Y
ge4 = Ge*(0.1818)/Y
re1 = 68-3-ge1
re2 = 68-3-ge2
re3 = 68-3-ge3
re4 = 68-3-ge4
for SimStep in range(1,int(Sim.Period*Sim.Resolution)):
Sim.RunSingleStep()
if SimStep 360 or SimStep 720 or SimStep 1080 or SimStep <=1440:
pass
'''
这下凑得有些多了,至于Webster算法,我不知道为啥加进去就有那么多错,车流量也测不出来(又扯到一大堆问题,不说了,不说了,破烦的很,就,,,)
最后一个涉及Python的课设时设计一个超声波传感器测车流量,加上暑假比赛对超声波有些了解,就感觉这个比较简单(当时就是这么认为的)刚好我们大创项目我刚好负责视频车流量检测,就想着用视频做,在问了老师的情况下就用视频了,当时想着用matlab的,但是多方考虑之下还是用了Python,matlab不会还得现学,Python的资料也还多些,就用Python了。
记得那个早上起来的还挺早(至少宿舍人都还没起),就去学校外面的那个大桥上去采视频了,采回来之后就着手做了,一直在考虑方案,最后选择了以前做过的帧间差分,然后就是各种写代码,调整。
图像中车被剔离出来了但是我不会计数呀,不会让计算机记下这就是一个车呀,最后在一片论文(我就是一个毫无honor之人,又没记下大神的名字)的指导下,照着论文提供的思路写程序,调算法,总算弄出来了,这个设计我还是比较满意的,贴一下代码:
import cv2
import numpy as np
from scipy import ndimage
from PIL import Image
from matplotlib import pyplot as plt
kernel_3x3 = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])
font = cv2.FONT_HERSHEY_SIMPLEX
cap = cv2.VideoCapture('222.mp4')#视频读入
width =int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))#图像矩阵宽度
height =int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))#图像矩阵长度
one_frame = np.zeros((height,width),dtype=np.uint8)
two_frame = np.zeros((height,width),dtype=np.uint8)
three_frame = np.zeros((height,width),dtype=np.uint8)
previous_frame = []
now_frame = []
differ_frame = []
roi = []
area = 0
count = 0
a = 0
b = 0
vicle_flowrate = 0
vicle_ = 0
pts1 = np.float32([[406,394],[742,398],[193,597],[810,582]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
for i in range(60):
previous_frame.append(i)
def ostu(roi):
global area
global count
#image=cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) # 转灰度
#blur = cv2.GaussianBlur(image,(5,5),0) # 阈值一定要设为 0 !高斯模糊
ret3,th3 = cv2.threshold(roi,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) # 二值化 0 = black ; 1 = white
#cv2.imshow('image', th3)
# a = cv2.waitKey(0)
# print a
height, width = th3.shape
for i in range(height):
for j in range(width):
if th3[i, j] == 255:
area += 1
if area >135 :
area = 1
else:
area = 0
count = area
area = 0
return count
while (True):
ret,frame = cap.read() #读取视频
frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
cv2.namedWindow("frame", 0)# 0可调大小,注意:窗口名必须imshow里面的一窗口名一直
#cv2.namedWindow("fra", 0)
cv2.resizeWindow("frame", 800, 600)
#cv2.resizeWindow("fra", 800, 600)
if ret:
one_frame,two_frame,three_frame = two_frame,three_frame,frame_gray
abs1 = cv2.absdiff(one_frame,two_frame)#图像矩阵相减
_,thresh1 = cv2.threshold(abs1,45,255,cv2.THRESH_BINARY)#二值化,大于45的为255,小于0
abs2 =cv2.absdiff(two_frame,three_frame)#图像矩阵相减
_,thresh2 = cv2.threshold(abs2,45,255,cv2.THRESH_BINARY)#二值化,大于39的为255,小于0
binary =cv2.bitwise_and(thresh1,thresh2)#图像矩阵与运算
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))#定义卷积kernel算子
erode = cv2.erode(binary,kernel)#腐蚀操作
dilate =cv2.dilate(binary,kernel)#膨胀操作
#img =cv2.dilate(dilate,kernel)#由于图像处理效果不太好,再膨胀一次
a = 220
for i in range(1,61):
roi = dilate[540:580,a+10:a+20]
a = 220+10*i
#print(roi.shape)
ostu(roi)
now_frame.append(count)
differ_frame = [now_frame[i] - previous_frame[i] for i in range(len(now_frame))]
previous_frame = now_frame
now_frame = []
b = 0
for i in differ_frame:
b = b + i
if b>5:
vicle_ = 1
if b>10:
vicle_ = 2
if b>14:
vicle_ = 3
vicle_flowrate += vicle_
vicle_ = 0
print(differ_frame)
vicle = 'flowrate:'+str(vicle_flowrate)
#设置外部显示
pts = np.array([[238,540],[798,540],[830,580],[190,580]],np.int32)
pts = pts.reshape((-1,1,2))
cv2.polylines(frame,[pts],True,(0,255,0),2)
cv2.putText(frame,vicle,(100,100),font,2,(0,255,0),2,cv2.LINE_AA)
#print(area)
k3 = ndimage.convolve(dilate,kernel_3x3)
blurred = cv2.GaussianBlur(dilate,(11,11),0)
g_hpf = dilate - blurred
dst = cv2.warpPerspective(frame,M,(300,300))
cv2.imshow('frame',dst)
#cv2.imshow('fra',g_hpf)
if cv2.waitKey(1)&0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
总算能写到现在过年时的想法了,过年前,在学校还和同学商量着回来要好好学习学习数学建模,想参加个美赛,最后在疫情的影响下(主要回来之后自己也没好好学),念想作罢,最后手头要紧的就是大创项目,下学期一开就要展示了呢,我还是只弄了视频处理的一个程序,硬件搭载,单片机通讯,摄像头处理,这些都还没有眉目,最后在网上接触到esp32,网络摄像头这个还像差不多能弄,大创的目的是构建新型智能城市交通系统,说白了就是控制红绿灯,而我要做的是,要把车流量检测结果报给单片机,单片机计算并控制绿信比,难题是我没有合适的视频处理硬件,不知道怎么把视频在一个硬件上处理,与寻常不一样,能处理视频的硬件,,,我就不知道,就算能接收到视频图像一般单片机就处理不了,太慢了会卡成ppt的,所以就很难,所以突然就接触到了网络摄像头,把视频传给电脑,然后电脑处理之后再传给单片机不就行了,,,,(现在这么想)
用esp32传过到电脑,电脑视频车流量检测处理之后,通过蓝牙模块传送检测数据,然后再单片机蓝牙接收,差不多就行了,硬件也就设计一个esp32,蓝牙模块,,,,(这几天就是这么想着的)esp32买了快递还没到,所以就先祈祷这个想法能落地吧。
希望记下的都当做成长的激励,证明自己还活着,还有用,还能为着梦想而奋斗!
新的一年,加油!
作者:qq_42771610