Узнайте, как раскрасить каждый пиксель изображения с помощью U-net

Вступление

Сегментация изображения - это приложение компьютерного зрения, в котором мы кодируем каждый пиксель изображения цветом. Затем каждый пиксель представляет определенный объект на этом изображении. Если вы посмотрите на изображения выше, каждая улица имеет фиолетовый код, каждое здание - оранжевое, каждое дерево - зеленое и так далее. Почему мы это делаем и чем это отличается от обнаружения объектов?

Сегментация изображения обычно используется, когда мы заботимся о краях и областях, когда мы хотим отделить важные объекты от фона. Мы хотим знать специфику объекта и с этого момента проводить его дальнейший анализ. Подумайте об этом с точки зрения беспилотного автомобиля. Беспилотный автомобиль не только хочет идентифицировать улицу, но и знать ее края или изгибы, чтобы сделать правильный поворот.

Сегментация изображений имеет большое значение в области медицины. Детали, которые необходимо изучить, имеют цветовую маркировку и просматриваются на отсканированных изображениях, сделанных под разными углами. Затем они используются для таких вещей, как автоматическое измерение органов, подсчет клеток или моделирование на основе извлеченной информации о границах.

Процесс

Мы рассматриваем сегментацию изображения как проблему классификации, когда для каждого пикселя изображения мы пытаемся предсказать, что это такое. Это велосипед, дорога, тротуар или здание? Таким образом мы создаем изображение с цветовой кодировкой, в котором все объекты имеют одинаковый цвет.

Код

Как обычно, мы начинаем с импорта библиотек fastai.

Давайте сначала взглянем на одно из изображений.

Далее мы посмотрим, как выглядит изображение после сегментации. Поскольку значения на помеченном изображении являются целыми числами, мы не можем использовать те же функции, чтобы открыть его. Вместо этого мы используем open_mask with show для отображения изображения.

Обратите внимание на функцию get_y_fn внутри open_mask. В каждой задаче сегментации нам дается 2 набора изображений: оригинальные и помеченные. Нам нужно сопоставить помеченные изображения с обычными. Мы делаем это, используя имена файлов. Давайте посмотрим на имена файлов некоторых изображений.

Мы видим, что имена файлов обычных изображений и изображений с метками совпадают, за исключением того, что соответствующее изображение с меткой имеет в конце _P. Следовательно, мы пишем функцию, которая для каждого изображения идентифицирует соответствующий помеченный аналог.

У нас также есть файл с именем codes.txt, который сообщает нам, какому объекту соответствуют целые числа в нашем помеченном изображении. Давайте откроем данные для изображения с пометкой.

Теперь давайте проверим значение этих целых чисел в файле кодов.

В помеченных данных было много цифр 26. Отсчитывая от индекса 0 в нашем файле кодов, мы видим, что объект, на который указывает целое число 26, является деревом.

Теперь, когда мы разобрались с нашими данными, мы можем перейти к созданию группы данных и обучению нашей модели.

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

Как обычно, мы создаем нашу группу данных. Чтение приведенного выше кода:

  • Создайте группу данных из папки
  • Разделите данные на обучение и тестирование на основе имен файлов, упомянутых в valid.txt
  • Найдите помеченные изображения с помощью функции get_y_fn и используйте коды как классы, которые нужно предсказать.
  • Применить преобразования к изображению (обратите внимание на tfm_y = True здесь. Это означает, что любое преобразование, которое мы применяем к нашим зависимым изображениям, также должно применяться к нашему целевому изображению. (Пример: если мы перевернем изображение по горизонтали, мы также должны перевернуть соответствующий помеченный изображение))

Для обучения мы будем использовать архитектуру CNN под названием U-Net, поскольку они хороши для воссоздания изображений.

Прежде чем объяснять, что такое U-Net, обратите внимание на показатели, используемые в приведенном выше коде. Что acc_camvid?

Точность в задаче сегментации изображения такая же, как и в любой задаче классификации.

Accuracy = no. of correctly classified pixels / total no. of pixels

Однако в этом случае некоторые пиксели помечены как Void (эта метка также существует в codes.txt), и их не следует учитывать при расчете точности. Следовательно, мы создаем новую функцию для точности, где мы избегаем этих меток.

CNN разбивает изображение на все меньшие и меньшие части, пока не останется только одно, что можно предсказать (левая часть архитектуры U-Net, показанная ниже). Затем U-Net берет это и снова делает все больше и больше, и делает это на каждом этапе CNN. Однако построить изображение из небольшого вектора - сложная работа. Следовательно, у нас есть связи от исходных слоев свертки к нашей сети деконволюции.

Как всегда находим скорость обучения и тренируем нашу модель. Даже с половиной набора данных мы получаем довольно хорошую точность - 92%.

Проверяем некоторые результаты.

Абсолютные истины - это фактические цели, а прогнозы - это то, что обозначила наша модель.

Теперь мы можем тренироваться на полном наборе данных.

Заключение

Это будет все для этой статьи. В этой статье мы увидели, как раскрасить каждый пиксель изображения с помощью U-net. U-сети набирают популярность, потому что они работают лучше, чем GAN, в таких приложениях, как создание изображений с высоким разрешением из размытых изображений. Следовательно, будет действительно полезно узнать, что это такое и как их использовать.

Полную записную книжку можно найти здесь.

Если вы хотите узнать больше о глубоком обучении, ознакомьтесь с моей серией статей об этом:



~ счастливого обучения