Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have the following codes, for resizing an an image numpy array with OpenCV in Python. It works well on my Windows desktop, but has memory leak on the Linux (ubuntu). It ate all memory after processing hundreds of images (9000x9000 pix). Any hints?


import cv2.cv as cv
def resizeMemLeak(imArray, size=(1000,1000), interp=cv.CV_INTER_LINEAR):
    """
    Resize a numpy array to size given by rows and cols, the array is first 
    converted into cv.mat image to do the resize.   
    @param inArray: numpy array to be resized
    @param size: int   - Percentage of current size
                 float - Fraction of current size
                 tuple - Size of the output image
    @type size: {int, float, tuple}
    @param interp: {cv.CV_INTER_LINEAR [default], 
                    cv.CV_INTER_NN, 
                    cv.CV_INTER_AREA,
                    cv.CV_INTER_CUBIC }
    @return: the resized numpy array kept the same dtype.
    """
    # make a copy of the input array to avoid OpenCV step bug
    import copy
    imCopy = copy.deepcopy(imArray)
    mat = cv.fromarray(imCopy, allowND=False)
    if len(imCopy.shape) == 2:
        assert mat.channels == 1
    elif len(imCopy.shape) == 3:
        assert mat.channels == imArray.shape[2]
    else:
        raise TypeError("unknown image array")
    import numpy as np
    if imCopy.dtype == np.uint8:
        assert mat.step // mat.cols == mat.channels
    elif imCopy.dtype == np.uint16:
        assert mat.step // mat.cols == 2 * mat.channels
    elif imCopy.dtype == np.int32:
        assert mat.step // mat.cols == 4 * mat.channels
    else:
        raise TypeError("unknown image array")
    if type(size) is int:
        assert 0 < size
        rows = mat.rows * size // 100
        cols = mat.cols * size // 100
    elif type(size) is float:
        assert 0.0 < size
        rows = int( mat.rows * size )
        cols = int( mat.cols * size )
    elif type(size) is tuple:
        assert len(size) == 2
        rows = int(size[0])
        cols = int(size[1])
    else:
        raise TypeError("parameter size: wrong type.")
    imResized = cv.CreateMat(rows, cols, mat.type)
    cv.Resize(mat, imResized)
    resized = np.asarray(imResized)
    return resized

Configuration:

  • Linux, Ubuntu, 8G mem, installed as virtual machine.
  • python2.7/oneiric uptodate 2.7.2-5ubuntu1
  • python-opencv/oneiric uptodate 2.1.0-7build1
  • python-numpy/oneiric uptodate 1:1.5.1-2ubuntu2

Thanks!

share|improve this question
    
You'll get more help if you reduce the code to the minimal amount of code that still exhibits the properties in question e.g. it's not clear what all the if .. elif .. else statements are doing, or if they are relevant, and since you are asking the question you can help others help you by doing the working of narrowing down the amount of code. (e.g. for this question you could probably remove all type(size) checks, and just assume that size is a tuple, and similarly assume that imCopy.dtype is just np.int32 or whatever.) –  huon-dbaupp Apr 20 '12 at 6:01
    
Do you really need to copy OpenCV array's in order to resize them? You mention that you're working around a 'step bug' but maybe this isn't the right solution. It might be the problem, because if you don't properly change all of the references to the original object then Python won't free up the memory from the original array. –  Adam Cadien May 4 '12 at 23:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.