Python OpenCV运行10秒后CPU使用率极高



我目前正在做一个项目,我正在建造一辆自动驾驶汽车。到目前为止,我已经对图像处理部分进行了分类,并对SVM(libSVM)进行了训练。我从IP摄像机获取视频源,但即使使用视频文件,我也会遇到同样的问题。运行几秒钟后,CPU使用率飙升至100%,帧速率降至1FPS以下。一开始我以为可能是磁盘I/O,但创建了一个ramdisk,问题仍然存在。有人能帮我找到代码中的问题吗?

#!/usr/bin/env python
import socket
import os
import cv2.cv as cv
import cv as _cv
import numpy
import time
import serial
from subprocess import call
TCP_IP = '192.168.1.101'
TCP_PORT = 23
BUFFER_SIZE = 1
serial = serial.Serial('/dev/ttyACM0',9600)
def run():
    prevDirection = 'e'
    directions = {  0:'d', 
            1:'w', 
            2:'w', 
            3:'w', 
            4:'a', 
            5:'a', 
            6:'a', 
            7:'a', 
            8:'a', 
            9:'a', 
            10:'d', 
            11:'d', 
            12:'d', 
            13:'d', 
            14:'d', 
            15:'d', 
            16:'d', 
            17:'d', 
            18:'d', 
            19:'d', 
            20:'d', 
            21:'d', 
            22:'d', 
            23:'d', 
            24:'e', 
            25:'e', 
            26:'e',
            27:'e'
             }
    vidFile = cv.CaptureFromFile('vvv.mp4')
    hist = cv.CreateHist([180], cv.CV_HIST_ARRAY, [(0,180)], 1)
    #selection = (270,460,100,20)
    selection = (1,1,100,20)
    framesToDrop = 5;
    while True:
        frame = None
        frame = cv.QueryFrame(vidFile)
        cv.ShowImage("selected", frame)
        cv.Smooth(frame, frame, cv.CV_BLUR, 5, 5)
        sub = cv.GetSubRect(frame, selection)
        cv.ShowImage("selected", sub)
        cv.Smooth(sub, sub, cv.CV_BLUR, 5, 5)
        _hsv = cv.CreateImage(cv.GetSize(sub), 8, 3)
        cv.CvtColor(sub, _hsv, cv.CV_BGR2HSV)
        _hue = cv.CreateImage(cv.GetSize(sub), 8, 1)
        cv.Split(_hsv, _hue, None, None, None)
        # Convert to HSV and keep the hue
        hsv = cv.CreateImage(cv.GetSize(frame), 8, 3)
        cv.CvtColor(frame, hsv, cv.CV_BGR2HSV)
        hue = cv.CreateImage(cv.GetSize(frame), 8, 1)
        cv.Split(hsv, hue, None, None, None)
        # Compute back projection
        backproject = cv.CreateImage(cv.GetSize(frame), 8, 1)
        cv.CalcArrBackProject([hue], backproject, hist)
        x,y,w,h = selection
        cv.Rectangle(frame, (x,y), (x+w,y+h), (255,255,255))
        cv.CalcArrHist( [_hue], hist, 0)
        (_, max_val, _, _) = cv.GetMinMaxHistValue(hist)
        threshold=100
        colour=255
        cv.Threshold(backproject,backproject, threshold,colour,cv.CV_THRESH_BINARY)
        cv.Smooth(backproject, backproject, cv.CV_BLUR, 5, 5)
        cv.Dilate(backproject,backproject,None,5)
        cv.Smooth(backproject, backproject, cv.CV_BLUR, 5, 5)
        cv.Dilate(backproject,backproject,None,5)
        cv.Smooth(backproject, backproject, cv.CV_BLUR, 5, 5)
        cv.Dilate(backproject,backproject,None,5)
        cv.Rectangle(backproject, (0,0), (640,280), cv.RGB(0, 0, 0), -1)
        SVMPrediction = predict(backproject)
        moveDirection = directions[SVMPrediction]
        #sendCommandToCarWifi(moveDirection,prevDirection)
        sendCommandToCarSerial(moveDirection,prevDirection)
        #print moveDirection
        cv.ShowImage("Live", frame)
        cv.ShowImage("Backproject", backproject)
        c = cv.WaitKey(7) % 0x100
        if c == 27:
            break
def sendCommandToCarSerial(direction,prevDirection):
    serial.write(direction)
def sendCommandToCarWifi(direction,prevDirection):
    if(prevDirection != direction):
        print'Sent: ' , direction
        prevDirection = direction
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((TCP_IP, TCP_PORT))
        s.send(direction)
        s.close()
    return prevDirection
def predict(inputFrame):
    resizedImage = cv.CreateImage((40,30),inputFrame.depth, inputFrame.nChannels)
    cv.Resize(inputFrame, resizedImage) 
    createBinary(resizedImage, 0)
    trash = os.system('/tmp/ramdisk/svm-predict /tmp/ramdisk/currentImageBinaryData.txt /tmp/ramdisk/currentImageBinaryData.txt.model /tmp/ramdisk/output')
    output = open('/tmp/ramdisk/output','r')
    result = output.read()
    output.close()
    return int(result)
def createBinary(image, number):
    threshold=100
    colour=255
    cv.Threshold(image,image, threshold,colour,cv.CV_THRESH_BINARY)
    width,height = cv.GetSize(image)
    pixelNum = 1
    pixelValues = []
    for i in range(height):
        for j in range(width):
            pixel = image[i,j]
            value = 2
            if(pixel == 0.0):
                value = 0
            if(pixel == 255.0):
                value = 1
            temp = ("%s:%s") % (pixelNum, value)
            pixelNum += 1
            pixelValues.append(temp)
    f = open('/tmp/ramdisk/currentImageBinaryData.txt','w')
    numberString = ('%d ') % (number)
    f.write(numberString)
    t = ' '.join(pixelValues)
    f.write(t)
    f.write(' n')
    f.flush()
    f.close()
if __name__=="__main__":
    run()
    cv.DestroyAllWindows()

您应该使用CProfile运行代码的概要文件,看看是什么占用了您的资源。关于评测的官方文档如下:http://docs.python.org/2/library/profile.html

最新更新