Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка

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

Аватар Дмитрий Юрченко
Отредактировано

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

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

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

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

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

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

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

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

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

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

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

Команды для установки:

			pip3 install imutils
pip3 install numpy
pip3 install opencv-python
		

Поиск книг на изображениях с помощью 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 в оттенки серого.

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

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

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

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

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

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

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

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

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

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

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

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

			# найдите контуры в изображении и подсчитайте количество книг
cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
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 5

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

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

 

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

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

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

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

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

Следите за новыми постами
Следите за новыми постами по любимым темам
40К открытий40К показов