【问题标题】:Raspberry pi, python, open cv memory leak?树莓派、python、open cv 内存泄漏?
【发布时间】:2018-03-17 17:14:14
【问题描述】:

在 Raspery Pi 上运行此 python 代码会导致 pi 在几个小时后变得不稳定。我认为存在内存泄漏或某些资源未释放。我对 python 很陌生。

#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,我认为这是因为没有足够的资源。

【问题讨论】:

    标签: python opencv memory-leaks raspberry-pi3


    【解决方案1】:

    您可以使用以下工具自己查明/检查内存泄漏:

    • 第一个使用的工具是guppy/heapy - 它将跟踪所有对象 在 Python 的内存中

    • 对于长时间运行的系统,使用dowser - 它允许实时 对象自省

    • memory_profiler 揭开了 RAM 使用的神秘面纱

    见我的presentation

    顺便说一句,SO 有很多条目解释了如何使用上述工具来跟踪内存泄漏 (GIYF)。

    【讨论】:

      猜你喜欢
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多