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

Ну, в основном вам нужно обнаружить круги . Вы видели cvHoughCircles() ? Разрешено ли вам это использовать?

На этой странице есть хорошая информация о том, как обнаружить вещи с помощью OpenCV . Вас может заинтересовать раздел 2.5 .

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

Вход :

Выходы :

// compiled with: g++ circles.cpp -o circles `pkg-config --cflags --libs opencv` #include #include #include #include int main(int argc, char** argv) { IplImage* img = NULL; if ((img = cvLoadImage(argv))== 0) { printf("cvLoadImage failed\n"); } IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); CvMemStorage* storage = cvCreateMemStorage(0); cvCvtColor(img, gray, CV_BGR2GRAY); // This is done so as to prevent a lot of false circles from being detected cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7); IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1); IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3); cvCanny(gray, canny, 50, 100, 3); CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, gray->height/3, 250, 100); cvCvtColor(canny, rgbcanny, CV_GRAY2BGR); for (size_t i = 0; i < circles->total; i++) { // round the floats to an int float* p = (float*)cvGetSeqElem(circles, i); cv::Point center(cvRound(p), cvRound(p)); int radius = cvRound(p); // draw the circle center cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0); // draw the circle outline cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0); printf("x: %d y: %d r: %d\n",center.x,center.y, radius); } cvNamedWindow("circles", 1); cvShowImage("circles", rgbcanny); cvSaveImage("out.png", rgbcanny); cvWaitKey(0); return 0; }

Обнаружение кругов сильно зависит от параметров cvHoughCircles() . Обратите внимание, что в этой демонстрации я также использовал Canny.

Я должен закодировать детектор объекта (в данном случае шарик) с помощью OpenCV. Проблема в том, что каждый поиск в google возвращает мне что-то с FACE DETECTION. Поэтому мне нужна помощь в том, с чего начать, что использовать и т. Д.

Некоторая информация:

  • Мяч не имеет фиксированного цвета, он, вероятно, будет белым, но он может измениться.
  • Я должен использовать машинное обучение, не обязательно быть сложным и надежным, предложение KNN (это проще и проще).
  • После всего моего поиска я обнаружил, что вычисление гистограммы образцов только для шаров и обучение его ML может быть полезным, но моя главная забота здесь в том, что размер шара может и изменится (ближе и дальше от камеры) и я понятия не имею, что передать ML, чтобы классифицировать для меня, я имею в виду.. я не могу (или я могу?) просто проверить каждый пиксель изображения для каждого возможного размера (от, скажем, от 5x5 до WxH) и надеемся найти положительный результат.
  • Там может быть неравномерный фон, например, люди, ткань за мячом и т. Д.
  • Как я уже сказал, мне нужно использовать алгоритм ML, что означает отсутствие алгоритмов Хаара или Виолы.
  • Кроме того, я думал об использовании контуров, чтобы найти круги на изображении Canny"ed, просто нужно найти способ преобразования контура в строку данных для обучения KNN.

    Итак... предложения?

    Заранее спасибо. ;)

Из этой статьи вы узнаете, как создать Python-скрипт для подсчёта количества книг на изображении с помощью 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) 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, , -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. Применить контурную аппроксимацию, чтобы определить, был ли контур прямоугольником и, следовательно, книгой.

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

Библиотека компьютерного зрения и машинного обучения с открытым исходным кодом. В неё входят более 2500 алгоритмов, в которых есть как классические, так и современные алгоритмы для компьютерного зрения и машинного обучения. Эта библиотека имеет интерфейсы на различных языках, среди которых есть Python (в этой статье используем его), Java, C++ и Matlab.

Установка

Инструкцию по установке на Windows можно посмотреть , а на Linux - .

Импорт и просмотр изображения

import cv2 image = cv2.imread("./путь/к/изображению.расширение") cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows()

Примечание При чтении способом выше изображение находится в цветовом пространстве не RGB (как все привыкли), а BGR. Возможно, в начале это не так важно, но как только вы начнёте работать с цветом - стоит знать об этой особенности. Есть 2 пути решения:

  1. Поменять местами 1-й канал (R - красный) с 3-м каналом (B - синий), и тогда красный цвет будет (0,0,255) , а не (255,0,0) .
  2. Поменять цветовое пространство на RGB: rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

    И тогда в коде работать уже не с image , а с rgb_image .

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

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

Import cv2 def viewImage(image, name_of_window): cv2.namedWindow(name_of_window, cv2.WINDOW_NORMAL) cv2.imshow(name_of_window, image) cv2.waitKey(0) cv2.destroyAllWindows()

Кадрирование

Пёсик после кадрирования

Import cv2 cropped = image viewImage(cropped, "Пёсик после кадрирования")

Где image - это image .

Изменение размера

После изменения размера на 20 %

Import cv2 scale_percent = 20 # Процент от изначального размера width = int(img.shape * scale_percent / 100) height = int(img.shape * scale_percent / 100) dim = (width, height) resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA) viewImage(resized, "После изменения размера на 20 %")

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

Поворот

Пёсик после поворота на 180 градусов

Import cv2 (h, w, d) = image.shape center = (w // 2, h // 2) M = cv2.getRotationMatrix2D(center, 180, 1.0) rotated = cv2.warpAffine(image, M, (w, h)) viewImage(rotated, "Пёсик после поворота на 180 градусов")

image.shape возвращает высоту, ширину и каналы. M - матрица поворота - поворачивает изображение на 180 градусов вокруг центра. -ve - это угол поворота изображения по часовой стрелке, а +ve , соответственно, против часовой.

Перевод в градации серого и в чёрно-белое изображение по порогу

Пёсик в градациях серого

Чёрно-белый пёсик

Import cv2 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) ret, threshold_image = cv2.threshold(im, 127, 255, 0) viewImage(gray_image, "Пёсик в градациях серого") viewImage(threshold_image, "Чёрно-белый пёсик")

gray_image - это одноканальная версия изображения.

Функция threshold возвращает изображение, в котором все пиксели, которые темнее (меньше) 127 заменены на 0, а все, которые ярче (больше) 127, - на 255.

Для ясности другой пример:

Ret, threshold = cv2.threshold(im, 150, 200, 10)

Здесь всё, что темнее, чем 150, заменяется на 10, а всё, что ярче, - на 200.

Остальные threshold-функции описаны .

Размытие/сглаживание

Размытый пёсик

Import cv2 blurred = cv2.GaussianBlur(image, (51, 51), 0) viewImage(blurred, "Размытый пёсик")

Функция GaussianBlur (размытие по Гауссу) принимает 3 параметра:

  1. Исходное изображение.
  2. Кортеж из 2 положительных нечётных чисел. Чем больше числа, тем больше сила сглаживания.
  3. sigmaX и sigmaY . Если эти параметры оставить равными 0, то их значение будет рассчитано автоматически.

Рисование прямоугольников

Обводим прямоугольником мордочку пёсика

Import cv2 output = image.copy() cv2.rectangle(output, (2600, 800), (4100, 2400), (0, 255, 255), 10) viewImage(output, "Обводим прямоугольником лицо пёсика")

Эта функция принимает 5 параметров:

  1. Само изображение.
  2. Координата верхнего левого угла (x1, y1) .
  3. Координата нижнего правого угла (x2, y2) .
  4. Цвет прямоугольника (GBR/RGB в зависимости от выбранной цветовой модели).
  5. Толщина линии прямоугольника.

Рисование линий

2 пёсика, разделённые линией

Import cv2 output = image.copy() cv2.line(output, (60, 20), (400, 200), (0, 0, 255), 5) viewImage(output, "2 пёсика, разделённые линией")

Функция line принимает 5 параметров:

  1. Само изображение, на котором рисуется линия.
  2. Координата первой точки (x1, y1) .
  3. Координата второй точки (x2, y2) .
  4. Цвет линии (GBR/RGB в зависимости от выбранной цветовой модели).
  5. Толщина линии.

Текст на изображении

Изображение с текстом

Import cv2 output = image.copy() cv2.putText(output, "We <3 Dogs", (1500, 3600),cv2.FONT_HERSHEY_SIMPLEX, 15, (30, 105, 210), 40) viewImage(output, "Изображение с текстом")

Функция putText принимает 7 параметров:

  1. Непосредственно изображение.
  2. Текст для изображения.
  3. Координата нижнего левого угла начала текста (x, y) .
  4. Лиц обнаружено: 2

    Import cv2 image_path = "./путь/к/фото.расширение" face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") image = cv2.imread(image_path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor= 1.1, minNeighbors= 5, minSize=(10, 10)) faces_detected = "Лиц обнаружено: " + format(len(faces)) print(faces_detected) # Рисуем квадраты вокруг лиц for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x+w, y+h), (255, 255, 0), 2) viewImage(image,faces_detected)

    detectMultiScale - общая функция для распознавания как лиц, так и объектов. Чтобы функция искала именно лица, мы передаём ей соответствующий каскад.

    Функция detectMultiScale принимает 4 параметра:

    1. Обрабатываемое изображение в градации серого.
    2. Параметр scaleFactor . Некоторые лица могут быть больше других, поскольку находятся ближе, чем остальные. Этот параметр компенсирует перспективу.
    3. Алгоритм распознавания использует скользящее окно во время распознавания объектов. Параметр minNeighbors определяет количество объектов вокруг лица. То есть чем больше значение этого параметра, тем больше аналогичных объектов необходимо алгоритму, чтобы он определил текущий объект, как лицо. Слишком маленькое значение увеличит количество ложных срабатываний, а слишком большое сделает алгоритм более требовательным.
    4. minSize - непосредственно размер этих областей.

    Contours - распознавание объектов

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

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

    Сохранение изображения

    import cv2 image = cv2.imread("./импорт/путь.расширение") cv2.imwrite("./экспорт/путь.расширение", image)

    Заключение

    OpenCV - отличная библиотека с лёгкими алгоритмами, которые могут использоваться в 3D-рендере, продвинутом редактировании изображений и видео, отслеживании и идентификации объектов и людей на видео, поиске идентичных изображений из набора и для много-много чего ещё.

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

Важнейшими источниками информации о внешнем мире для робота являются его оптические датчики и камеры. После получения изображения необходима его обработка для анализа обстановки или принятия решения. Как я говорил ранее, компьютерное зрение объединяет множество методов работы с изображениями. При функционировании робота предполагается, что видеоинформация с камер обрабатывается какой-либо программой, запущенной на контроллере. Чтобы не писать код с нуля, можно воспользоваться готовыми программными решениями. На текущий момент существует множество готовых библиотек компьютерного зрения:

  • Matrox Imaging Library
  • Camellia Library
  • Open eVision
  • HALCON
  • libCVD
  • OpenCV
  • и т.д…
Данные SDK могут сильно различаться по функциональности, условиям лицензирования, используемым языкам программирования. Мы же подробнее остановимся на OpenCV . Она бесплатна как для учебных целей, так и для коммерческого использования. Написана на оптимизированном C/C++, поддерживает интерфейсы C, C++, Python, Java и включает в себя реализации свыше 2500 алгоритмов. Помимо стандартных функций обработки изображений (фильтрация, размытие, геометрические преобразования и т.д…) данный SDK позволяет решать более сложные задачи, к которым относятся обнаружение объекта на фотографии и его «узнавание». Следует понимать, что задачи обнаружения и распознавания могут быть совершенно различными:
  • поиск и распознавание конкретного объекта,
  • поиск объектов одной категории (без распознавания),
  • только распознавание объекта (уже готовое изображение с ним).
Для обнаружения признаков на изображении и проверки на совпадение в OpenCV имеются следующие методы:
  • Гистограмма направленных градиентов HOG(Histogram of Oriented Gradients) — может применяться для обнаружения пешеходов
  • Алгоритм Виолы-Джонса — применяется для поиска лиц
  • Алгоритм обнаружения признаков SIFT (Scale Invariant Feature Transform)
  • Алгоритм обнаружения признаков SURF (Speeded Up Robust Features)
Например, SIFT обнаруживает наборы точек, которые можно использовать для идентификации объекта. Помимо приведенных методик в OpenCV имеются и другие алгоритмы для детектирования и распознавания, а также набор алгоритмов, относящихся к машинному обучению, таких как метод k ближайших соседей, нейронные сети, метод опорных векторов и т.д… В целом OpenCV предоставляет инструментарий, достаточный для решения подавляющего большинства задач компьютерного зрения. Если алгоритм не имеется в составе SDK, то, как правило, он может быть без проблем запрограммирован. Кроме того, существует множество авторских версий алгоритмов, написанных пользователями на основе OpenCV. Также следует отметить, что за последние годы OpenCV сильно расширилась и стала в некоторой степени «тяжеловесной». В связи с этим, разными группами энтузиастов создаются «облегченные» библиотеки, основанные на OpenCV. Примеры: SimpleCV, liuliu ccv, tinycv… Полезные сайты
  1. http://opencv.org/ — Основной сайт проекта
  2. http://opencv.willowgarage.com/wiki/ — Старый сайт проекта с документацией по старым версиям