加速运动检测代码opencv python numpy

时间:2013-01-10 20:12:21

标签: python optimization opencv numpy

我有这些

codebook.py

#http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.148.9778&rep=rep1&type=pdf

import numpy as np
import cv2

alpha = 5
beta = 0.95

Tdel = 80
Tadd = 140
Th= 80

mn,mx,f,l,p,q=0,1,2,3,4,5

class CodeBook():
    def __init__(self,h,w):
        self.h = h
        self.w = w
        self.M = np.empty((h, w), dtype=np.object)
        self.H = np.empty((h, w), dtype=np.object)
        filler = np.frompyfunc(lambda x: list(), 1, 1)
        filler(self.M,self.M)
        filler(self.H,self.H)
        self.t = 1

    def updatev(self,gray,cb):
        I,t = gray,self.t     
        if not cb:
            c = [max(0.0,I-alpha),min(255.0,I+alpha),1,t-1,t,t]
            cb.append(c)
        else:
            found = False
            for cm in cb:
                if(cm[mn]<=I<=cm[mx] and not found): 
                    cm[mn] = ((I-alpha)+(cm[f]*cm[mn]))/(cm[f]+1.0)    
                    cm[mx] = ((I+alpha)+(cm[f]*cm[mx]))/(cm[f]+1.0)
                    cm[f] += 1
                    #cm[l] = max(cm[l],t-cm[q])
                    cm[l] = 0
                    cm[q] = t
                    found = True
                else:
                    cm[l] = max(cm[l],10-cm[q]+cm[p]-1)
            if not found:
                c = [max(0.0,I-alpha),min(255.0,I+alpha),1,t-1,t,t]
                cb.append(c)                
        return cb
    def update(self,gray):       
        h,w,M = self.h,self.w,self.M
        updatev = np.vectorize(self.updatev,otypes=[np.object])
        self.M=updatev(gray,M)
        self.t += 1   
    def fgv(self,gray,cwm,cwh):
        I,t = gray,self.t
        pixval = 0
        found = False
        for cm in cwm:
            if(cm[mn]<=I<=cm[mx] and not found):
                cm[mn] = (1-beta)*(I-alpha) + (beta*cm[mn])
                cm[mx] = (1-beta)*(I+alpha) + (beta*cm[mx])
                cm[f] += 1
                #cm[l] = max(cm[l],t-cm[q])
                cm[l] = 0
                cm[q] = t
                found = True
            else:
                cm[l] += 1
                #cm[l]=max(cm[l],t-cm[q]+cm[p]-1)
        cwm[:] = [cw for cw in cwm if cw[l]<Tdel]  
        if found: return 0
        for cm in cwh:
            if(cm[mn]<=I<=cm[mx] and not found):
                cm[mn] = (1-beta)*(I-alpha) + (beta*cm[mn])
                cm[mx] = (1-beta)*(I+alpha) + (beta*cm[mx])
                cm[f] += 1
                #cm[l] = max(cm[l],t-cm[q])
                cm[l] = 0
                cm[q] = t
                found = True
            else:
                #cm[l]=max(cm[l],t-cm[q]+cm[p]-1)
                cm[l] += 1
        if not found:
            c = [max(0.0,I-alpha),min(255.0,I+alpha),1,0,t,t]
            cwh.append(c)
        cwh[:] = [cw for cw in cwh if cw[l]<Th]
        tomove = [cw for cw in cwh if cw[f]>Tadd]
        cwh[:] = [cw for cw in cwh if not cw in tomove]
        cwm.extend(tomove)
        return 255
    def fg(self,gray):  
        h,w,M,H = self.h,self.w,self.M,self.H
        fgv = np.vectorize(self.fgv,otypes=[np.uint8])
        fg = fgv(gray,M,H)
        self.t += 1
        return fg

test.py

import cv2
import sys
import numpy as np
import time
import cProfile
import pyximport; pyximport.install(reload_support=True,                                     
                                    setup_args={'script_args':["--compiler=mingw32"]})
import codebook
c = cv2.VideoCapture(0)
c.set(3,320)
c.set(4,240)
cv2.namedWindow('vid',0)
cv2.namedWindow('fg',0)
_,img = c.read()
img = cv2.resize(img,(160,120))
h,w = img.shape[:2]
cb = codebook.CodeBook(h,w)
N=0

def fillholes(gray):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
    res = cv2.morphologyEx(gray,cv2.MORPH_OPEN,kernel)    

def run():
    while(1):
        global N
        _,img = c.read()
        img = cv2.resize(img,(160,120))
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        cv2.imshow('vid',gray)    
        if N < 10:        
            cb.update(gray)
        else:
            start = time.clock()
            fg = cb.fg(gray)
            print time.clock()-start
            element = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2,2))
            fg= cv2.erode(fg,element)
            fillholes(fg)                
            cv2.imshow('fg',fg)
        N += 1
        if cv2.waitKey(5)==27:
            break
run()
cv2.destroyAllWindows()
c.release()

代码卡住了@ fgv。 cython可以加快一些速度。但它仍然运行缓慢。我正在考虑做两个中的任何一个

  • 让它并行运行
    • 多线程。我正在使用epd的numpy并将MKL_NUM_THREADS更改为8.但它仍然绑定到单个核心。
    • 分发到工作进程数组切片
  • 重做一些/所有(我没有exp)部分在cpp虽然我真的想避免这个

我已经改变了fgv,就像我知道的那样。请让我知道接下来应该怎么看。非常感谢!