2017-10-06 87 views
0

在Raspery Pi上運行此python代碼將導致pi在幾個小時後變得不穩定。我認爲有一個內存泄漏或一些資源沒有被釋放。我對python很陌生。樹莓派,蟒蛇,打開CV內存泄漏?

#initialise pygame 
pygame.init() 
pygame.camera.init() 
cam = pygame.camera.Camera("/dev/video0",(width,height)) 
cam.start() 

.... 

# Read the image we have presaved as an alert image 
# and convert it to greyscale and blur it 
alertimage = cv2.imread('./alert/alert.jpg') 
alertgray = cv2.cvtColor(alertimage, cv2.COLOR_RGBA2GRAY) 
alertgray = cv2.GaussianBlur(alertgray, (21, 21), 0)  

# Compare a given image to the saved image to and return true if 
# they are the same 
def IsAlert(image): 
    global alertgray 

    gray = cv2.cvtColor(image, cv2.COLOR_RGBA2GRAY) 
    gray = cv2.GaussianBlur(gray, (21, 21), 0) 

    frameDelta = cv2.absdiff(alertgray, gray) 
    thresh = cv2.threshold(frameDelta, 40, 255, cv2.THRESH_BINARY)[1] 
    thresh = cv2.dilate(thresh, None, iterations=2) 
    (_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 

    # loop over the contours 
    for c in cnts: 
     # if the contour is large enough 
     if cv2.contourArea(c) > 1600: 
      return 0 
    return 1 

# Main loop #################################################### 
while True: 

    # Get an image from tpygame and save it to ram disk 
    # im doing this beacuse I can't figure our how to convert 
    # pygame image to cv2 image so I save it and read it back 
    imageS = cam.get_image()  
    pygame.image.save(imageS,'/var/ramdsk/picture.jpg') 

    # Read the image I just saved 
    image = cv2.imread('/var/ramdsk/picture.jpg') 

    # Compare the image to a standard image that I have presaved 
    alert = IsAlert(image) 

    # Convert the image to grey and blur it 
    gray = cv2.cvtColor(image, cv2.COLOR_RGBA2GRAY) 
    gray = cv2.GaussianBlur(gray, (21, 21), 0) 

    if lastgray is None: 
     lastgray = gray 

    # See what has changed... 
    frameDelta = cv2.absdiff(lastgray, gray) 
    thresh = cv2.threshold(frameDelta, 40, 255, cv2.THRESH_BINARY)[1] 
    thresh = cv2.dilate(thresh, None, iterations=2) 
    (_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 

    # loop over the contours 
    waschange = change 
    for c in cnts: 
     # if the contour is large enough 
     if cv2.contourArea(c) > 1600: 
      print "Area: ",cv2.contourArea(c) 
      change = change + 1 
      same = 0 
      break 

    # If the image is 
    if change == waschange: 
     same = same + 1 

    # If the image has settled after changing then it's time to 
    # capture it by moving the saved version to another directory 
    if (change > 0 and same > 3) or init == 0: 
     fileout = '/home/pi/Desktop/CamManager/clips_new/0x{}L-{}-{}.jpg'.format(mac,t,alert) 
     shutil.move('/var/ramdsk/picture.jpg',fileout) 
     change = 0 
     same = 0 
     init = 1 
     print "Saving New Still",fileout 

    lastgray = gray 

cam.stop() 

在一個類似的腳本我解決了一個問題,frame.truncate(0)

camera = picamera.PiCamera() 
.... 
camera.capture(frame, format='bgr', use_video_port=True) 
.... 
frame.truncate(0) 

對不起張貼這麼多的代碼,但我不是很確定在資源泄漏。幾個小時後,我無法在pi上打開一個新shell,我認爲這是因爲沒有足夠的資源。

回答

0

可以精確定位/檢查內存泄漏自己,使用以下工具:

  • 使用的工具是guppy/heapy - 這將跟蹤所有對象 內Python的內存

  • 對於長時間運行的系統,使用dowser - 允許實時對象 對象內省

  • RAM使用率揭祕與memory_profiler

見我presentation

順便說一句,SO有很多條目解釋如何使用上述工具來跟蹤內存泄漏(GIYF)。