实例介绍
【实例简介】行人检测与轨迹追踪.py
行人检测追踪系统利用OpenCV中预先训练好的HOG 线性SVM模型(也可自己训练HOG 线性SVM模型)对视频中的行人进行检测,利用追踪算法绘制出行人的移动轨迹。整个系统用python实现,并用wxpython实现了GUI。
【实例截图】
【核心代码】
# -*- coding: utf-8 -*- """ Created on Wed Mar 29 11:04:22 2017 @author: Eric Liuwch """ from __future__ import print_function from imutils.object_detection import non_max_suppression import numpy as np import datetime import imutils import wx import cv2 import cv2.cv as cv from PIL import Image import matplotlib # matplotlib采用WXAgg为后台,将matplotlib嵌入wxPython中 matplotlib.use("WXAgg") from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar from matplotlib.ticker import MultipleLocator, FuncFormatter from matplotlib.font_manager import FontProperties from skimage import data,exposure font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=15) import matplotlib.pyplot as plt ###################################################################################### class MPL_Panel_base(wx.Panel): ''''' #MPL_Panel_base背景面板,可以继承或者创建实例''' def __init__(self,parent): wx.Panel.__init__(self,parent=parent, id=-1) self.max_width = 400 self.max_height = 600 self.MinScale=2000 self.MaxScale=20000 self.MinContourArea=100 self.MaxContourArea=10000 self.flag1=True self.flag2=True self.flag3=True self.flag4=True self.flag5=True self.flag6=True self.Figure=plt.figure(figsize=(3,3)) # figsize(单位:英寸)不能太大,会压缩空白位图,使其无法显示 self.subplot = self.Figure.add_subplot(3,2,1) self.subplot1 = self.Figure.add_subplot(3,2,2) self.subplot2 = self.Figure.add_subplot(3,2,3) self.subplot3 = self.Figure.add_subplot(3,2,4) self.subplot2 = self.Figure.add_subplot(3,2,5) self.subplot3 = self.Figure.add_subplot(3,2,6) self.FigureCanvas = FigureCanvas(self,-1,self.Figure) self.NavigationToolbar = NavigationToolbar(self.FigureCanvas) self.StaticText = wx.StaticText(self,-1,label='Show Help String') self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL) self.SubBoxSizer.Add(self.NavigationToolbar,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.SubBoxSizer.Add(self.StaticText,proportion =1, border = 5,flag = wx.ALL | wx.EXPAND) self.SubBoxSizer1 = wx.BoxSizer(wx.HORIZONTAL) self.SubBoxSizer1.Add(self.FigureCanvas,proportion =-5, border = 12,flag = wx.ALL | wx.EXPAND) self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL) self.TopBoxSizer.Add(self.SubBoxSizer,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND) self.TopBoxSizer.Add(self.SubBoxSizer1,proportion =-5, border = 2,flag = wx.ALL | wx.EXPAND) self.SetSizer(self.TopBoxSizer) ###方便调用 self.plt=plt def plotImage111(self, path): uipath = unicode(path, "utf8") img=Image.open(uipath) self.plt.subplot(1,1,1) self.plt.axis('off') self.plt.imshow(img) def plotVideo111(self, path): cap = cv2.VideoCapture(path.encode('gbk')) for i in range(50): ret, frame = cap.read() if ret==True: self.cla() self.plt.subplot(1,1,1) self.plt.imshow(frame) self.plt.axis('off') self.UpdatePlot() cap.release() cv2.destroyAllWindows() def plotImage121(self, path): img=Image.open(path) self.plt.subplot(1,2,1) self.plt.imshow(img) def PlotImage122(self, path): img=Image.open(path) self.plt.subplot(1,2,2) self.plt.imshow(img) def PlotImage211(self, path): img=Image.open(path) self.plt.subplot(2,1,1) self.plt.imshow(img) def PlotImage212(self, path): img=Image.open(path) self.plt.subplot(2,1,2) self.plt.imshow(img) def PlotImage221(self, path): img=Image.open(path) self.plt.subplot(2,2,1) self.plt.imshow(img) def PlotImage222(self, path): img=Image.open(path) self.plt.subplot(2,2,2) self.plt.imshow(img) def PlotImage223(self, path): img=Image.open(path) self.plt.subplot(2,2,3) self.plt.imshow(img) def PlotImage224(self, path): img=Image.open(path) self.plt.subplot(2,2,4) self.plt.imshow(img) def Exit(self): self.flag1=False self.flag2=False self.flag3=False self.flag4=False self.flag5=False self.flag6=False def GetSize(self, img): height, width = img.shape[:2] if width>self.max_width: height = height*self.max_width/width width = self.max_width if height>self.max_height: width = width*self.max_height/height height = self.max_height size = width, height return size def ScaleImage(self, path): source = cv2.imread(path.encode('gbk'),cv2.CV_LOAD_IMAGE_COLOR) size= self.GetSize(source) res = cv2.resize(source,size, interpolation = cv2.INTER_CUBIC) #利用opencv做的图像压缩 img = cv2.cvtColor(np.uint8(res), cv2.cv.CV_BGR2RGB) cv2.imwrite(frame.ObjPath, img) def ShowVideo(self, path): cap = cv2.VideoCapture(path.encode('gbk')) while(cap.isOpened()): ret, frame = cap.read() #gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) if ret==True: cv2.imshow('video',frame) else: break if cv2.waitKey(1) & self.flag1==False: break cap.release() cv2.destroyAllWindows() def OpencvCanny(self, path): cap = cv2.VideoCapture(path.encode('gbk')) while(cap.isOpened()): ret, frame = cap.read() #gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) if ret==True: img = cv2.GaussianBlur(frame,(3,3),0) canny = cv2.Canny(img, 50, 150) cv2.namedWindow('frame',0)#通过指定的名字,创建一个可以作为图像和进度条的容器窗口 cv2.namedWindow('canny',0)#通过指定的名字,创建一个可以作为图像和进度条的容器窗口 cv2.resizeWindow('frame',640,480) cv2.resizeWindow('canny',640,480) cv2.imshow('frame',frame) cv2.imshow('canny',canny) else: break if cv2.waitKey(1) & self.flag2==False: break cap.release() cv2.destroyAllWindows() def OpencvCaptureMoveTarget(self, path): camera = cv2.VideoCapture(path.encode('gbk')) if not camera.isOpened(): camera = cv2.VideoCapture(0) firstFrame = None while True: (grabbed, frame) = camera.read() # if could not grab ,is end of the frame if not grabbed: break # resize scale and GaussianBlur frame = imutils.resize(frame, width=500) orig = frame.copy() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (21, 21), 0) # initial if firstFrame is None: firstFrame = gray continue # compute the difference of the current frame to the firstframe frameDelta = cv2.absdiff(firstFrame, gray) thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1] # dilate the threshing image thresh = cv2.dilate(thresh, None, iterations=2) (cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # choose every contours rects = [] for c in cnts: # if the contour is too small, ignore it if cv2.contourArea(c) < cv2.getTrackbarPos('Min','Capture move target'): continue # compute the bounding box for the contour, draw it on the frame,and update the text (x, y, w, h) = cv2.boundingRect(c) cv2.rectangle(orig, (x, y), (x w, y h), (0, 255, 0), 2) rects.append((x, y, x w, y h)) #transform to array rects = np.array(rects) #apply non-maxima suppression to the bounding boxes pick = non_max_suppression(rects, probs=None, overlapThresh=0.65) # draw the final bounding boxes for (xA, yA, xB, yB) in pick: cv2.rectangle(frame, (xA, yA), (xB, yB), (0, 255, 0), 2) cv2.putText(frame, "Contour Size: {}".format(cv2.getTrackbarPos('Min','Capture move target')), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1) cv2.imshow("Before NMS", orig) cv2.imshow("Capture move target", frame) if cv2.waitKey(1) & self.flag3==False: break camera.release() cv2.destroyAllWindows() def OpencvCaptureMovePerson(self, path): camera = cv2.VideoCapture(path.encode('gbk')) (grabbed, frame) = camera.read() fps = camera.get(cv2.cv.CV_CAP_PROP_FPS) if not camera.isOpened(): camera = cv2.VideoCapture(0) hog = cv2.HOGDescriptor() hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) prev_points = [] curr_points = [] nbFrames=0 frame = imutils.resize(frame, width=min(750, frame.shape[1])) out = cv2.VideoWriter('C:\Users\hp\Videos\Capturesoutput.avi',-1, fps,(frame.shape[1],frame.shape[0]))#size必须与frame的size保持一致 while True: nbFrames = 1 if (nbFrames%cv2.getTrackbarPos('Min','Capture person'))!=0: continue # 获取当前帧并初始化occupied/unoccupied文本 (grabbed, frame) = camera.read() # 如果不能抓取到一帧,说明我们到了视频的结尾 if not grabbed: break # load the image and resize it to (1) reduce detection time # and (2) improve detection accuracy frame = imutils.resize(frame, width=min(750, frame.shape[1])) # detect people in the image (rects, weights) = hog.detectMultiScale(frame, winStride=(4, 4), padding=(0, 0), scale=1.5) # apply non-maxima suppression to the bounding boxes using a # fairly large overlap threshold to try to maintain overlapping # boxes that are still people rects = np.array([[x, y, x w, y h] for (x, y, w, h) in rects]) pick = non_max_suppression(rects, probs=None, overlapThresh=0.65) # draw the final bounding boxes for (xA, yA, xB, yB) in pick: cv2.rectangle(frame, (xA, yA), (xB, yB), (0, 255, 0), 2) point= (int((xA xB)/2),int((yA yB)/2)) curr_points.append(point) #Add the new points to list if len(curr_points)==len(prev_points): for i in range(len(curr_points)): cv2.line(frame, prev_points[i], curr_points[i], (255, 255, ),2) prev_points= curr_points if len (rects)==0: prev_points = [] curr_points = [] # draw the text and timestamp on the frame cv2.putText(frame, "Frame intervals : {}".format(cv2.getTrackbarPos('Min','Capture person')), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1) # show the output images cv2.imshow("Capture person", frame) out.write(frame) if cv2.waitKey(1) & self.flag2==False: break camera.release() out.release() cv2.destroyAllWindows() def ShowCamera(self): cap = cv2.VideoCapture(0) fourcc = cv2.cv.CV_FOURCC(*'XVID') #opencv3的话用:fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('C:\Users\hp\Videos\Captures\Camera.avi',fourcc,20.0,(640,480))#保存视频 while True: ret,frame = cap.read() #gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) out.write(frame)#写入视频 img = cv2.GaussianBlur(frame,(3,3),0) canny = cv2.Canny(img, 50, 150) cv2.imshow('frame',frame)#一个窗口用以显示原视频 cv2.imshow('gray',canny)#另一窗口显示处理视频 if cv2.waitKey(1) &self.flag3==False: break cap.release() out.release() cv2.destroyAllWindows() def UpdatePlot(self): '''''#修改图形的任何属性后都必须使用self.UpdatePlot()更新GUI界面 ''' self.FigureCanvas.draw() self.Figure.images def plot1(self,arr): '''''#柱状图绘图命令plot1 ''' self.plt.subplot(2,2,2) n, bins, patches=self.plt.hist(arr, bins=256, normed=1, facecolor='green', alpha=0.75) self.UpdatePlot() def plot2(self,arr): '''''#柱状图绘图命令plot2 ''' self.plt.subplot(2,2,4) n, bins, patches=self.plt.hist(arr, bins=256, normed=1, facecolor='green', alpha=0.75) self.UpdatePlot() def savefig(self,*args,**kwargs): ''''' #保存图形到文件 ''' self.Figure.savefig(*args,**kwargs) def cla(self): ''''' # 再次画图前,必须调用该命令清空原来的图形 ''' self.Figure.clear() self.Figure.set_canvas(self.FigureCanvas) self.UpdatePlot() def ShowHelpString(self,HelpString="Show Help String"): ''''' #可以用它来显示一些帮助信息,如鼠标位置等 ''' self.StaticText.SetLabel(HelpString) def nothing(self,x): self.flag2=False self.flag2=True self.OpencvCaptureMovePerson(frame.path) ############################################################################### # MPL_Frame添加了MPL_Panel的1个实例 ############################################################################### class MPL_Frame(wx.Frame): """MPL_Frame可以继承,并可修改,或者直接使用""" def __init__(self,title=u"行人检测追踪",size=(800,500)): wx.Frame.__init__(self,parent=None,title = title,size=size) self.MPL = MPL_Panel_base(self) self.path = 'C:\Users\hp\Pictures\Saved Pictures\背景.jpg' self.ObjPath = 'C:\Python Scripts\imageprocess\ObjImage.jpg' #创建FlexGridSizer self.FlexGridSizer=wx.FlexGridSizer( rows=9, cols=1, vgap=5,hgap=5) self.FlexGridSizer.SetFlexibleDirection(wx.BOTH) self.RightPanel = wx.Panel(self,-1) #测试按钮1 self.Button1 = wx.Button(self.RightPanel,-1,u"文件打开",size=(100,40),pos=(10,10)) self.Button1.Bind(wx.EVT_BUTTON,self.Button1Event) #测试按钮2 self.Button2 = wx.Button(self.RightPanel,-1,u"播放视频",size=(100,40),pos=(10,10)) self.Button2.Bind(wx.EVT_BUTTON,self.Button2Event) #测试按钮3 self.Button3 = wx.Button(self.RightPanel,-1,u"行人检测追踪",size=(100,40),pos=(10,10)) self.Button3.Bind(wx.EVT_BUTTON,self.Button3Event) #测试按钮4 self.Button4 = wx.Button(self.RightPanel,-1,u"退出",size=(100,40),pos=(10,10)) self.Button4.Bind(wx.EVT_BUTTON,self.Button4Event) #加入Sizer中 self.FlexGridSizer.Add(self.Button1,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.FlexGridSizer.Add(self.Button2,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.FlexGridSizer.Add(self.Button3,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.FlexGridSizer.Add(self.Button4,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.RightPanel.SetSizer(self.FlexGridSizer) self.BoxSizer=wx.BoxSizer(wx.HORIZONTAL) self.BoxSizer.Add(self.MPL,proportion =-10, border = 2,flag = wx.ALL | wx.EXPAND) self.BoxSizer.Add(self.RightPanel,proportion =0, border = 2,flag = wx.ALL | wx.EXPAND) self.SetSizer(self.BoxSizer) #状态栏 self.StatusBar() #MPL_Frame界面居中显示 self.Centre(wx.BOTH) #按钮事件,用于测试 def Button1Event(self,event): self.MPL.flag1=False self.MPL.flag2=False self.MPL.flag3=False wildcard = r"Data files (*.dat)|*.dat|Text files (*.txt)|*.txt|ALL Files (*.*)|*.*" open_dlg = wx.FileDialog(self,message='Choose a file',wildcard = wildcard, style=wx.OPEN|wx.CHANGE_DIR) if open_dlg.ShowModal() == wx.ID_OK: self.path=open_dlg.GetPath() try: self.MPL.ShowHelpString( self.path) self.MPL.plotVideo111(self.path) except IOError, error: dlg = wx.MessageDialog(self, 'Error opening file\n' str(error)) dlg.ShowModal() open_dlg.Destroy() self.MPL.UpdatePlot()#必须刷新才能显示 def Button2Event(self,event): self.MPL.flag1=True self.MPL.flag2=False self.MPL.flag3=False try: self.MPL.ShowVideo(self.path) self.MPL.ShowHelpString(self.path) except: self.MPL.ShowHelpString(u"请先打开视频文件") def Button3Event(self,event): self.MPL.flag1=False self.MPL.flag2=True self.MPL.flag3=False cv2.namedWindow('Capture person') cv2.createTrackbar('Min','Capture person', self.MPL.MinScale, self.MPL.MaxScale, self.MPL.nothing) try: self.MPL.OpencvCaptureMovePerson(self.path) self.MPL.ShowHelpString(self.path) except: self.MPL.ShowHelpString(u'请先打开图像') def Button4Event(self,event): self.MPL.Exit() #自动创建状态栏 def StatusBar(self): self.statusbar = self.CreateStatusBar() self.statusbar.SetFieldsCount(3) self.statusbar.SetStatusWidths([-2, -2, -1]) #About对话框 def AboutDialog(self): dlg = wx.MessageDialog(self, '\twxMatPlotLib\t\nMPL_Panel_base,MPL_Panel,MPL_Frame and MPL2_Frame \n Created by Wu Xuping\n Version 1.0.0 \n 2012-02-01', 'About MPL_Frame and MPL_Panel', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() ############################################################################### ### MPL2_Frame添加了MPL_Panel的两个实例 ############################################################################### class MPL2_Frame(wx.Frame): """MPL2_Frame可以继承,并可修改,或者直接使用""" def __init__(self,title="MPL2_Frame Example In wxPython",size=(850,500)): wx.Frame.__init__(self,parent=None,title = title,size=size) self.BoxSizer=wx.BoxSizer(wx.HORIZONTAL) self.MPL1 = MPL_Panel_base(self) self.BoxSizer.Add(self.MPL1,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND) self.MPL2 = MPL_Panel_base(self) self.BoxSizer.Add(self.MPL2,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND) self.RightPanel = wx.Panel(self,-1) self.BoxSizer.Add(self.RightPanel,proportion =0, border = 2,flag = wx.ALL | wx.EXPAND) self.SetSizer(self.BoxSizer) #创建FlexGridSizer self.FlexGridSizer=wx.FlexGridSizer( rows=9, cols=1, vgap=5,hgap=5) self.FlexGridSizer.SetFlexibleDirection(wx.BOTH) #测试按钮1 self.Button1 = wx.Button(self.RightPanel,-1,"TestButton",size=(100,40),pos=(10,10)) self.Button1.Bind(wx.EVT_BUTTON,self.Button1Event) #测试按钮2 self.Button2 = wx.Button(self.RightPanel,-1,"AboutButton",size=(100,40),pos=(10,10)) self.Button2.Bind(wx.EVT_BUTTON,self.Button2Event) #加入Sizer中 self.FlexGridSizer.Add(self.Button1,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.FlexGridSizer.Add(self.Button2,proportion =0, border = 5,flag = wx.ALL | wx.EXPAND) self.RightPanel.SetSizer(self.FlexGridSizer) #状态栏 self.StatusBar() #MPL2_Frame界面居中显示 self.Centre(wx.BOTH) #按钮事件,用于测试 def Button1Event(self,event): self.MPL1.cla()#必须清理图形,才能显示下一幅图 x=np.arange(-5,5,0.2) y=np.cos(x) self.MPL1.plot(x,y,'--*g') self.MPL1.xticker(2.0,1.0) self.MPL1.yticker(0.5,0.1) self.MPL1.title_MPL("MPL1") self.MPL1.ShowHelpString("You Can Show MPL1 Helpful String Here !") self.MPL1.grid() self.MPL1.UpdatePlot()#必须刷新才能显示 self.MPL2.cla() self.MPL2.plot(x,np.sin(x),':^b') self.MPL2.xticker(1.0,0.5) self.MPL2.yticker(0.2,0.1) self.MPL2.title_MPL("MPL2") self.MPL2.grid() self.MPL2.UpdatePlot() def Button2Event(self,event): self.AboutDialog() #自动创建状态栏 def StatusBar(self): self.statusbar = self.CreateStatusBar() self.statusbar.SetFieldsCount(3) self.statusbar.SetStatusWidths([-2, -2, -1]) #About对话框 def AboutDialog(self): dlg = wx.MessageDialog(self, '\twxMatPlotLib\t\nMPL_Panel_base,MPL_Panel,MPL_Frame and MPL2_Frame \n Created by Wu Xuping\n Version 1.0.0 \n 2012-02-01', 'About MPL_Frame and MPL_Panel', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() ######################################################################## #主程序测试 if __name__ == '__main__': app = wx.PySimpleApp() #frame = MPL2_Frame() frame =MPL_Frame() frame.Center() frame.Show() frame.MPL.plotImage111(frame.path) app.MainLoop()
标签:
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论