简体   繁体   中英

Python OpenCV extremely high CPU usage after 10 second runtime

I'm currently doing a project where I'm building an autonomous driving car. So far I have sorted out the image processing parts as well as training the SVM (libSVM). I'm getting the video feed from an IP camera but even using a video file I'm encountering this same problem. After a few seconds of runtime CPU usage spikes to 100% and the frame rate drops to below 1FPS. At first I thought it could be disk I/O, but created a ramdisk and the problem still persisted. Can someone help me find the problem in my code?

#!/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()

You should run a profile of your code with CProfile and see what's chewing up your resources. The official docs on profiling are here: http://docs.python.org/2/library/profile.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM