Python OpenCV extremely high CPU usage after 10 second runtime
Question: 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()
    


Answer: 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>

