Opencv(Python)内存使用问题

时间:2017-04-13 19:01:00

标签: python xml opencv memory

我的Python软件存在问题。这是一个很棒的角色,我采用了英特尔实际(USB相机)流。使用opencv我制作了几个findContours,然后将轮廓的结果发送到另一个软件。

问题在于存在内存消耗。实际上,RAM使用量每2-3秒增加0.1%。

我不知道该怎么做......

这是代码(对不起,如果它不漂亮,但我正在测试很多东西)

import numpy as np
import random
import socket
import cv2
import time
import math
import pickle
import httplib, urllib
from xml.etree import ElementTree as ET
import logging


logging.basicConfig(level=logging.INFO)

try:
    import pyrealsense as pyrs
except:
    print("No pyralsense Module installed!")
#funzione per registrare gli eventi del mouse
def drawArea(event,x,y, flag, param):
    global fx,fy,ix,iy

    if event == cv2.EVENT_LBUTTONDOWN:
        ix,iy = x,y

    elif event == cv2.EVENT_LBUTTONUP:
        fx,fy = x,y

def RepresentsInt(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

quit = False
read = False
while read == False:
        file = open('default.xml', 'r')
        tree = ET.parse(file)
        root = tree.getroot()
        for child in root:
            if child.tag == "intel":
                intel = int(child[0].text)
            elif child.tag == "output":
                portOut = int(child[2].text)
            elif child.tag =="source":
                video_source = child.text
        file.close()
        root.clear()
        ix,iy = -1,-1
        fx,fy = -1,-1
        timeNP = 10
        last = time.time()
        smoothing = 0.9
        fps_smooth = 30


        #video_source = video_source.split(",")
        read = True

if RepresentsInt(video_source):
    video_source = int(video_source)

if intel == 1:
    pyrs.start()
    dev = pyrs.Device(video_source)
master = 1
address = ('', 3333)
broadSockListe = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
broadSockListe.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
broadSockListe.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
broadSockListe.bind(('',3333))
while True:
    if master == 0:
        datas, address = broadSockListe.recvfrom(1024)

        if str(datas) == "8000":
            separator = ":"
            seq = (address[0],"8081")
            masterAddr = separator.join(seq)
            IP = str([l for l in (
            [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [
                [(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in
                 [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
            params = separator.join(("addUnit",IP,str(portOut),"camera","generalList.xml"))
            params = urllib.urlencode({"Python":params})
            headers = {}
            conn = httplib.HTTPConnection(masterAddr)
            conn.request("POST",masterAddr ,params, headers)
            params = separator.join(("masterIP",address[0],str(portOut)+"/","default.xml"))
            params = urllib.urlencode({"Python":params})
            headers = {}
            myip = IP + ":8081"
            conn = httplib.HTTPConnection(myip)
            #eseguo una post al mio server
            conn.request("POST", myip, params, headers)
            broadSockListe.close()
            #imposto master a 1 per dire che l'ho registrato e posso partire col programma
            master = 1
    read = False
    while read == False:

            '''# leggo le varie impostazioni dal file default
            file = open('default.xml','r+')
            tree = ET.parse(file)
            root = tree.getroot()
            for child in root:
                if child.tag == "modifica" and child.text == "1":
                    child.text = "0"
                    tree.write('default.xml')
            root.clear()
            file.close()'''
            read = True


    prev,prevprev,dirX,dirY = 0,0,0,0
    spostamento = 15
    UDP_IP = ["", ""]
    UDP_PORT = ["", ""]
    UDP_IP[0] = "127.0.0.1"
    UDP_PORT[0] = 3030
    IP_left = "127.0.0.1"
    IP_right = "127.0.0.1"
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("",portOut))
    message = ""
    sep = "-"
    font = cv2.FONT_HERSHEY_SIMPLEX
    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
    #rettangoli = [x,y,width,height,angle,box, area, contours]
    rettangoli = []
    cnt = 0
    letto = 0
    while True:
        now = time.time()
        if letto < now - 2 or letto == 0 or now < letto:
            letto = now
            print(now)
            read = False
            while read == False:
                    file = open('default.xml', 'r')
                    tree = ET.parse(file)
                    root = tree.getroot()
                    for child in root:
                        if child.tag == "output":
                            UDP_IP[1] = child[0].text
                            UDP_PORT[1] = int(child[1].text)
                        if child.tag == "effects":
                            erode = int(child[0].text)
                            erodePos = int(child[1].text)
                            erode2 = int(child[2].text)
                            erodePos2 = int(child[3].text)
                            dilate1 = int(child[4].text)
                            dilatePos1= int(child[5].text)
                            dilate2 = int(child[6].text)
                            dilatePos2 = int(child[7].text)
                            blur = int(child[8].text)
                            blurPos = int(child[9].text)
                        if child.tag == "intel":
                            val1Min = int(child[1].text)
                            val1Max = int(child[2].text)
                            val2Min = int(child[3].text)
                            val2Max = int(child[4].text)
                            val3Min = int(child[5].text)
                            val3Max = int(child[6].text)
                        if child.tag == "modifica":
                            if child.text == "1":
                                break
                        #definisco dimensioni per collisioni
                        if child.tag == "size":
                            blobSize= int(child[0].text)
                            dimBordoBlob= int(child[1].text)
                        if child.tag == "visualizza":
                            visualizza= child.text
                        if child.tag == "feedback":
                            SFB = int(child.text)
                    root.clear()
                    file.close()
                    read = True
        dev.wait_for_frame()
        c = dev.colour
        c = cv2.cvtColor(c, cv2.COLOR_RGB2BGR)
        d = dev.depth * dev.depth_scale * -60
        d = d[5:485, 25:635]
        d = cv2.applyColorMap(d.astype(np.uint8), cv2.COLORMAP_HSV)
        c = cv2.resize(c, (320 ,240), interpolation=cv2.INTER_AREA)
        d = cv2.resize(d, (320,240), interpolation=cv2.INTER_AREA)
        #trasformo i colori in HSV per filtrarli
        frame = cv2.cvtColor(d, cv2.COLOR_BGR2HSV)
        lower_red = np.array([val1Min, val2Min, val3Min])
        upper_red = np.array([val1Max, val2Max, val3Max])
        frame = cv2.inRange(frame, lower_red, upper_red)
        dimensions = frame.shape
        widthStream = dimensions[1]
        heightStream = dimensions[0]
        roomFrame = np.zeros(( heightStream,widthStream, 3), np.uint8)
        roomFrame[:] = (0, 0, 0)
        fgmask = frame
        halfheight = int(heightStream / 2)
        halfwidth = int(widthStream / 2)
        for i in range(0, 15):
            if erode >= 1 and erodePos == i:
                fgmask = cv2.erode(fgmask, kernel, iterations=erode)
            if dilate1 >= 1 and dilatePos1 == i:
                fgmask = cv2.dilate(fgmask, kernel, iterations=dilate1)
            if erode2 >= 1 and erodePos2 == i:
                fgmask = cv2.erode(fgmask, kernel, iterations=erode2)
            if dilate2 >= 1 and dilatePos2 == i:
                fgmask = cv2.dilate(fgmask, kernel, iterations=dilate2)
            if blur == 1 and blurPos == 1:
                fgmask = cv2.GaussianBlur(fgmask, (5, 5), 0)
        if ix > fx:
            temp = fx
            fx = ix
            ix = temp
        if iy > fy:
            temp = fy
            fy = iy
            iy = temp
        if cnt == 0:
            ix,iy = 1,1
            fx,fy = widthStream-1,heightStream-1
        fgmask, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        rettangoli = []
        for cont in contours:
            rect = cv2.minAreaRect(cont)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            width = rect[1][0]
            height = rect[1][1]
            angle = rect[2]
            if width > height:
                angle = 180 + angle
            else:
                angle = 270 + angle
            x, y, w, h = cv2.boundingRect(cont)
            centerX = int(w / 2 + x)
            centerY = int(h / 2 + y)
            M = cv2.moments(cont)
            area = int(M['m00'])
            if area > blobSize:
                if ix < centerX < fx and iy < centerY < fy:
                    cv2.drawContours(fgmask, [cont], 0, (100, 100, 100), dimBordoBlob)
                    cv2.drawContours(fgmask, [cont], 0, (255, 255, 255), -1)
                    rettangoli.append([centerX, centerY, w, h, angle, box, area, cont])
        indice = 0
        fgmask, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)
        if intel == 1:
            fgmask = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2RGB)
        rettangoli = []
        for cont in contours:
            rect = cv2.minAreaRect(cont)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            width = rect[1][0]
            height = rect[1][1]
            angle = rect[2]
            if width > height:
                angle = 180 + angle
            else:
                angle = 270 + angle
            x, y, w, h = cv2.boundingRect(cont)
            centerX = int(w / 2 + x)
            centerY = int(h / 2 + y)
            M = cv2.moments(cont)
            indice += 1
            if M['m00'] > blobSize:
                if ix < centerX < fx and iy < centerY < fy:
                    rettangoli.append([centerX, centerY, w, h, angle, box, int(M['m00']), cont])
                    cv2.drawContours(roomFrame, [cont], 0, (255, 255, 255), -1)
        for rett in rettangoli:
            seq = (message,np.array_str(rett[7]))
            message = sep.join(seq)
        temp = 0
        while temp < len(UDP_IP):
            sock.sendto(bytes(message), (UDP_IP[temp], UDP_PORT[temp]))
            temp += 1
        message = ""
        if SFB == 1:
            cv2.imshow("Camera Intel", roomFrame)
        if cv2.waitKey(1) & 0xFF == ord('r'):
            break
        if cv2.waitKey(1) & 0xFF == ord('q'):
            quit = True
            break
        name = "color.jpeg"
        cv2.imwrite(name, c)
        name = "bn.jpeg"
        cv2.imwrite(name, roomFrame)
    if intel == 0:
        cap.release()
    cv2.destroyAllWindows()

1 个答案:

答案 0 :(得分:1)

您正在while循环中创建新对象。以现在为例,您创建一个变量,然后为其分配一个仅存在于该循环中的新对象。如果在循环之前声明变量,则会覆盖相同的对象而不是重新创建。

通过使用name = None提前声明变量,您将能够确保重复使用这些变量。

我希望这适合你。