我已经构建了一个更快的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())