我的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()
答案 0 :(得分:1)
您正在while循环中创建新对象。以现在为例,您创建一个变量,然后为其分配一个仅存在于该循环中的新对象。如果在循环之前声明变量,则会覆盖相同的对象而不是重新创建。
通过使用name = None
提前声明变量,您将能够确保重复使用这些变量。
我希望这适合你。