CV2.imread()的内存使用问题

时间:2017-12-11 15:30:47

标签: python opencv

我已经构建了一个更快的r-cnn模型,并且正在使用一堆边界框标记图像。我的问题是python内核最终崩溃,同时标记了70,000个图像中的第一个~3000个。我已经将问题缩小到image = cv2.imread()。无论使用del image还是image = None,过剩的内存使用都会持续存在。 CV2库是否存在无内存泄漏问题?我使用的是3.3版。无论如何要清除记忆?谢谢。

def SaveFigureAsImage(fileName,fig=None,**kwargs):
    ''' Save a Matplotlib figure as an image without borders or frames.
       Args:
            fileName (str): String that ends in .png etc.

            fig (Matplotlib figure instance): figure you want to save as the image
        Keyword Args:
            orig_size (tuple): width, height of the original image used to maintain 
            aspect ratio.
    '''
    a=fig.gca()
    a.set_frame_on(False)
    a.set_xticks([]); a.set_yticks([])
    plt.axis('off')
    fig.savefig(fileName, transparent=True, bbox_inches='tight', \
                        pad_inches=0)

#classes
classes = {
redacted
}

#load model
image_input = keras.layers.Input((None, None, 3))
model = keras_retinanet.models.ResNet50RetinaNet(image_input, num_classes=len(classes), weights='imagenet')
model.load_weights('snapshots/resnet50_model_1_6.h5')

test_image_data_generator = keras.preprocessing.image.ImageDataGenerator()
#possibely resize the image
test_generator = PascalVocIterator(
    '../',
    'test',
    test_image_data_generator,
    classes=classes
)

#stats
frequency = {} 

ef read_image_bgr(path):
    image = np.asarray(PIL.Image.open(path).convert('RGB'))
    return image[:, :, ::-1].copy()


def preprocess_image(x):
    # mostly identical to "https://github.com/fchollet/keras/blob/master/keras/applications/imagenet_utils.py"
    # except for converting RGB -> BGR since we assume BGR already
    x = x.astype(keras.backend.floatx())
    if keras.backend.image_data_format() == 'channels_first':
        if x.ndim == 3:
            x[0, :, :] -= 103.939
            x[1, :, :] -= 116.779
            x[2, :, :] -= 123.68
        else:
            x[:, 0, :, :] -= 103.939
            x[:, 1, :, :] -= 116.779
            x[:, 2, :, :] -= 123.68
    else:
        x[..., 0] -= 103.939
        x[..., 1] -= 116.779
        x[..., 2] -= 123.68

    return x


def random_transform(
    image,
    boxes,
    image_data_generator,
    seed=None
):
    if seed is None:
        seed = np.random.randint(10000)

    image = image_data_generator.random_transform(image, seed=seed)

    # set fill mode so that masks are not enlarged
    fill_mode = image_data_generator.fill_mode
    image_data_generator.fill_mode = 'constant'

    for index in range(boxes.shape[0]):
        # generate box mask and randomly transform it
        mask = np.zeros_like(image, dtype=np.uint8)
        b = boxes[index, :4].astype(int)

        assert(b[0] < b[2] and b[1] < b[3]), 'Annotations contain invalid box: {}'.format(b)
        assert(b[2] <= image.shape[1] and b[3] <= image.shape[0]), 'Annotation ({}) is outside of image shape ({}).'.format(b, image.shape)

        mask[b[1]:b[3], b[0]:b[2], :] = 255
        mask = image_data_generator.random_transform(mask, seed=seed)[..., 0]
        mask = mask.copy()  # to force contiguous arrays

        # find bounding box again in augmented image
        [i, j] = np.where(mask == 255)
        boxes[index, 0] = float(min(j))
        boxes[index, 1] = float(min(i))
        boxes[index, 2] = float(max(j)) + 1  # set box to an open interval [min, max)
        boxes[index, 3] = float(max(i)) + 1  # set box to an open interval [min, max)

    # restore fill_mode
    image_data_generator.fill_mode = fill_mode

    return image, boxes


def resize_image(img, min_side=600, max_side=1024):
    (rows, cols, _) = img.shape

    smallest_side = min(rows, cols)

    # rescale the image so the smallest side is min_side
    scale = min_side / smallest_side

    # check if the largest side is now greater than max_side, wich can happen
    # when images have a large aspect ratio
    largest_side = max(rows, cols)
    if largest_side * scale > max_side:
        scale = max_side / largest_side

    # resize the image with the computed scale
    img = cv2.resize(img, None, fx=scale, fy=scale)

    return img, scale

def run(beg):
    gc.enable()
    images_path = glob.glob('../1brower-167136992/data/167136992/SESI/SESI_files/19/*.jpg')

    count = -1 
    for p in images_path:
        count += 1
        if count >= beg and count - beg < 2000:
            #image = cv2.imread(p) #this is the memory leak
            image = np.array(Image.open(p))
            image_copy = image.copy()

            #preprocess image
            image_copy = preprocess_image(image_copy)
            image, scale = resize_image(image, 600, 600)
            image_copy, scale = resize_image(image_copy, 600, 600)

            name = p.split('/')[7]
            name = name.split('.jpg')[0]
            start = time.time()
            _, _, detections = model.predict_on_batch(np.expand_dims(image_copy, axis=0))
            print("processing time: ", time.time() - start)

            im = image.copy()
            predicted_labels = np.argmax(detections[0, :, 4:], axis=1)
            scores = np.max(detections[0, :, 4:], axis=1)

            for idx, (label, score) in enumerate(zip(predicted_labels, scores)):
                #print(label, score)
                if score < 0.25: #change the 0.5 cuttoff to a lower number
                    continue
                b = detections[0, idx, :4].astype(int)
                caption = "{} {:.3f}".format(test_generator.labels[label], score)
                if label == 0:
                    cv2.rectangle(im, (b[0], b[1]), (b[2], b[3]), (255, 0, 0), 3)
                    if "redacted" not in frequency:
                        frequency["redacted"] = 1
                    else:
                        frequency["redacted"] += 1
                elif label == 2:
                    cv2.rectangle(im, (b[0], b[1]), (b[2], b[3]), (0, 0, 255), 3)
                    if "redacted" not in frequency:
                        frequency["redacted"] = 1
                    else:
                        frequency["redacted"] += 1
                elif label == 3:
                    cv2.rectangle(im, (b[0], b[1]), (b[2], b[3]), (0, 120, 120), 3)
                    if "redacted" not in frequency:
                        frequency["redacted"] = 1
                    else:
                        frequency["redacted"] += 1
                elif label == 4:
                    cv2.rectangle(im, (b[0], b[1]), (b[2], b[3]), (0, 120, 120), 3)
                    if "pocks" not in frequency:
                        frequency["redacted"] = 1
                    else:
                        frequency["redacted"] += 1
                else:
                    cv2.rectangle(im, (b[0], b[1]), (b[2], b[3]), (0, 255, 0), 3)
                    if "redacted" not in frequency:
                        frequency["redacted"] = 1
                    else:
                        frequency["redacted"] += 1
                cv2.putText(im, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 0, 0), 3)
                cv2.putText(im, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1.5, (255, 255, 255), 2)
            plt.figure(figsize=(10, 10))
            plt.axis('off')
            plt.imshow(im)
            print(name)
            SaveFigureAsImage('../processed_data/' + name, plt.gcf() )
            plt.close("all")
            print("----------------------------")
            #print(gc.collect())

0 个答案:

没有答案