Изменение размера изображений переменного размера для обнаружения объектов - PullRequest
0 голосов
/ 14 марта 2019

Я использую набор данных обнаружения объектов KITTI для обучения Faster R-CNN с ResNet 101, предварительно обученным в MS COCO. KITTI изображения "в основном" размером 375x1242

Когда у меня было batch_size: 1, все было идеально. Мой keep_aspect_ratio_resizer был как ниже, как это было предложено самим TensorFlow.

min_dimension: 600
max_dimension: 1987

Но теперь я хочу использовать batch_size: 5, но продолжаю получать ошибки несоответствия размеров. Потому что некоторые изображения имеют немного меньший размер, например 370x1224 и т. Д.

Я не могу найти общие keep_aspect_ratio_resizer значения. Я пробовал приведенные ниже значения на основе значений, которые я видел в сообщениях об ошибках, но я не могу сделать все изображения одинакового размера действительно

min_dimension: 600
max_dimension: 1985

min_dimension: 599
max_dimension: 1985

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Исправлено добавлением tf.image.resize_image_with_crop_or_pad(images, max_height, max_width) к create_input_queue() в https://github.com/tensorflow/models/blob/master/research/object_detection/legacy/trainer.py

0 голосов
/ 14 марта 2019

Вы можете изменить размеры изображений самостоятельно, чтобы обойти ошибку округления. или Вы можете попытаться сгруппировать элементы одного размера вместе в пакеты.

Предполагая, что у вас есть генератор изображений и что у изображений есть атрибут размера, вы можете создать генератор, который будет выдавать партии изображений одинакового размера следующим образом:

from itertools import groupby
from collections import deque, defaultdict


def same_size_batches(images, batch_size=5):
    image_cache = defaultdict(deque)

    # We assume the image object has a size parameter we can group by
    for size, images in groupby(images, key=lambda image: image.size):
        for image in images:
            image_cache[size].append(image)

            # Everytime our batch gets big enough, yield it and reset
            if len(image_cache[size]) == batch_size:
                yield iter(image_cache[size])
                image_cache[size].clear()

Основная часть здесь - это группа, которая группирует последовательные элементы по одному и тому же ключу и возвращает этот ключ, а также генератор элементов, соответствующих этому ключу. В нашем случае ключом является размер изображения.

Затем мы сохраняем кэш элементов одинакового размера, и каждый раз, когда один из размеров достигает желаемого размера партии, мы выдаем генератор для этой партии.

Мы можем продемонстрировать эту работу с поддельным объектом изображения, который имеет требуемый параметр размера:

import random


class FakeImage(object):
    def __init__(self, _id):
        self.id = _id
        self.size = (370, 1224) if random.random() < 0.25 else (375, 1242)

    def __repr__(self):
        return "<Image {} {}>".format(self.id, self.size)


images = (FakeImage(_id) for _id in range(100))
for batch in same_size_batches(images, batch_size=5):
    print(list(batch))

В результате получается что-то вроде:

[<Image 0 (375, 1242)>, <Image 2 (375, 1242)>, <Image 3 (375, 1242)>, <Image 4 (375, 1242)>, <Image 6 (375, 1242)>]
[<Image 7 (375, 1242)>, <Image 8 (375, 1242)>, <Image 9 (375, 1242)>, <Image 10 (375, 1242)>, <Image 12 (375, 1242)>]
[<Image 1 (370, 1224)>, <Image 5 (370, 1224)>, <Image 11 (370, 1224)>, <Image 14 (370, 1224)>, <Image 16 (370, 1224)>]
[<Image 13 (375, 1242)>, <Image 15 (375, 1242)>, <Image 18 (375, 1242)>, <Image 19 (375, 1242)>, <Image 20 (375, 1242)>]
[<Image 21 (375, 1242)>, <Image 23 (375, 1242)>, <Image 24 (375, 1242)>, <Image 25 (375, 1242)>, <Image 26 (375, 1242)>]
...

Мы не гарантируем, что создадим все изображения, если мы не получим достаточно, чтобы заполнить блок размером пакета, но если вход является бесконечным генератором, это не проблема.

...