вНовости программирования

Пишем скрипт для поиска книг на изображениях с помощью Python и OpenCV

Из этой статьи вы узнаете, как создать Python-скрипт для подсчёта количества книг на изображении с помощью OpenCV

Прим. перев. Также советуем обратить внимание на наше руководство по созданию бота для мессенджера на Python и посмотреть видеокурс, в котором рассказывается о написании автопилота для GTA V — там тоже используется OpenCV.

Что мы будем делать?

Взглянем на изображение, на котором будем искать книги:

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

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

Какие библиотеки нам понадобятся?

Чтобы написать систему для поиска и обнаружения книг на изображениях, мы будем использовать OpenCV для работы с компьютерным зрением и обработки изображений. Нам также необходимо установить NumPy для корректной работы OpenCV. Убедитесь, что у вас установлены эти библиотеки!

Поиск книг на изображениях с помощью Python и OpenCV

Прим. перев. Вы можете заметить, что исходный код в нашей статье отличается от кода в оригинале. Автор, вероятно, использовал установку необходимых библиотек через репозитории. Мы предлагаем использовать pip, что гораздо проще. Во избежание появления ошибок рекомендуем использовать версию кода, приведенную в нашей статье.

Откройте свой любимый редактор кода, создайте новый файл с именем find_books.py и начнем:

# -*- coding: utf-8 -*- # импортируйте необходимые пакеты import numpy as np import cv2 # загрузите изображение, смените цвет на оттенки серого и уменьшите резкость image = cv2.imread("example.jpg") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (3, 3), 0) cv2.imwrite("gray.jpg", gray)

Начнем с импорта библиотеки OpenCV. Загрузка изображения с диска обрабатывается функцией cv2.imread. Здесь мы просто загружаем его с диска, а затем преобразуем цветовую гамму из RGB в оттенки серого.

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

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

Теперь давайте определим края (т.е. контуры) объектов на изображении:

# распознавание контуров edged = cv2.Canny(gray, 10, 250) cv2.imwrite("edged.jpg", edged)

Теперь наше изображение выглядит следующим образом:

Мы нашли контуры объектов на изображениях. Однако, как вы видите, некоторые из контуров не закрыты — между контурами существуют промежутки. Чтобы убрать промежутки между белыми пикселями изображения, мы применим операцию «закрытия»:

# создайте и примените закрытие kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7)) closed = cv2.morphologyEx(edged, cv2.MORPH_CLOSE, kernel) cv2.imwrite("closed.jpg", closed)

Теперь пробелы в контурах закрыты:

Следующим шагом является фактическое обнаружение контуров объектов на изображении. Для этого мы будем использовать функцию cv2.findContours:

# найдите контуры в изображении и подсчитайте количество книг cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1] total = 0

Рассмотрим геометрию книги.

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

Чтобы проверить, является ли контур книгой или нет, нам нужно выполнить цикл по каждому контуру:

# цикл по контурам for c in cnts: # аппроксимируем (сглаживаем) контур peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) # если у контура 4 вершины, предполагаем, что это книга if len(approx) == 4: cv2.drawContours(image, [approx], -1, (0, 255, 0), 4) total += 1

Для каждого из контуров мы вычисляем периметр, используя cv2.arcLength, а затем аппроксимируем (сглаживаем) контур, используя cv2.approxPolyDP.

Причина, по которой мы аппроксимируем контур, заключается в том, что он может не быть идеальным прямоугольником. Из-за зашумления и теней на фото вероятность того, что у книги будет ровно 4 вершины, невелика. Аппроксимируя контур, мы решаем эту проблему.

Наконец, мы проверяем, что у аппроксимируемого контура действительно четыре вершины. Если это так, то мы рисуем контур вокруг книги, а затем увеличиваем счётчик общего количества книг.

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

# показываем результирующее изображение print("Я нашёл {0} книг на этой картинке".format(total) cv2.imwrite("output.jpg", image))

На данном этапе наше изображение будет выглядеть так:

Терминал показывает, что мы успешно нашли четыре книги на изображении, игнорируя другие предметы:

 

Подведем итоги

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

Наш подход состоял в том, чтобы:

  1. Загрузить изображение с диска и преобразовать его в оттенки серого.
  2. Немного размыть изображение.
  3. Применить детектор контуров Canny для обнаружения объектов на изображении.
  4. Закрыть любые промежутки в контурах.
  5. Найти контуры объектов на изображении.
  6. Применить контурную аппроксимацию, чтобы определить, был ли контур прямоугольником и, следовательно, книгой.

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

Типичный программист.

Источник: Типичный программист