Как работают Каскады Хаара в OpenCV?

Можете на доступном языке объяснить, как это работает?
Вот допустим есть некоторое изображение, на котором нужно определить лица, и мы пропускаем его через этот алгоритм.
В нём мы имеем чёрно-белые маски и признаки размером 24 на 24. Ещё и 25 уровней каких-то есть.
Так и что в итоге с ними происходит?
Предполагаю типа признаком 24 на 24 проходимся по всему изображению. На каждом таком проходе ещё проходим и масками, чтобы определить может ли быть на этом месте лицо или нет (если так, то как?). В итоге имеем изображение с несколькими отметками 24 на 24, на которых по идее лицо. И как в итоге будет решено, есть ли на всём изображении это лицо?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Обучение OpenCV каскада Хаара
Всем привет! Пытаюсь обучить сеть. Создаю Good.vec opencv_createsamples.exe -info.
OpenCV каскад хаара
Всем привет! Есть рабочий каскад хаара, сейчас он распознает объекты и выделяет их рамкой.
Нейросеть на базе Каскада Хаара и OpenCV
Всем привет, делал нейросеть на базе Каскада Хаара и OpenCV для подсчёта объектов, для 1 камеры.
Каскады хаара
Всем привет. Кто нибудь пожалуйста дайте ссылку для скачивания cvhaartraining.lib, очень нужна эта.
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Объясните, как работают каскады усилителя мощности
Здравствуйте, подскажите пожалуйста на схеме верхний транзистор предвыходного каскада в насыщении.
Не загружаются каскады в OpenCV
Есть код, полностью скопированный с оф. сайта OpenCV, но к сожалению почему-то не загружаются.
Каскад Хаара OpenCV
Кто делал каскад помогите пожалуйста, нужны настройки: opencv_createsamples.exe.

Не прогружаются каскады haarcascade_frontalface_alt.xml в Visual Studio 2010. OpenCV. Завершается с ошибкой 1
Все форумы перечитала, много вариантов испробовала, но результата никакого. Подскажите кто.

Hibernate каскады
Есть категория продуктов, и сам продукт: @Entity @Table(name = "categories") public class.
Или воспользуйтесь поиском по форуму:
Использование Haar Cascade для обнаружения объектов в OpenCV
Что такое особенности волос и каскад волос?
С тех пор, как Пол Виола и Майкл Джонс разработали технику в 2001 году, функции Хаара и каскады Хаара произвели революцию в обнаружении объектов. Они стали неотъемлемыми компонентами различных приложений — от распознавания лиц до обнаружения объектов в реальном времени.
Характеристики Хаара извлекаются из прямоугольных областей изображения. Значение функции основано на интенсивности пикселей. Обычно он рассчитывается с использованием скользящего окна, а область внутри окна разделяется на две или более прямоугольных области. Особенностью Хаара является разница суммы интенсивностей пикселей между этими областями.
Считается, что присутствие объекта исказит изменение интенсивности пикселей. Например, фон обычно имеет однородный узор, в который не помещается объект переднего плана. Проверив интенсивность пикселей между соседними прямоугольными областями, вы сможете заметить разницу. Следовательно, это указывает на присутствие объекта.
Для повышения эффективности вычислений прямоугольные области объектов Хаара обычно располагаются параллельно краям изображения, а не наклонены. Однако мы можем использовать прямоугольники разных размеров и форм, чтобы фиксировать различные особенности и вариации масштаба объекта. Таким образом, ключевая сила функций Хаара заключается в их способности представлять три шаблона:
- Края: вертикальные или горизонтальные в зависимости от того, как мы сориентировали прямоугольную область. Они полезны для определения границ между различными областями изображения.
- Линии: диагональные края изображения. Они полезны для определения линий и контуров объектов.
- Объекты, окруженные центром: определяет изменения интенсивности между центром прямоугольной области и окружающей ее областью. Это полезно для идентификации объектов особой формы или рисунка.
Каскад Хаара объединяет несколько функций Хаара в иерархию для создания классификатора. Вместо анализа всего изображения с использованием каждого признака Хаара каскады разбивают процесс обнаружения на этапы, каждый из которых состоит из набора признаков.
Ключевая идея каскада Хаара заключается в том, что только небольшое количество пикселей всего изображения связано с рассматриваемым объектом. Поэтому крайне важно как можно быстрее отбросить ненужную часть изображения. В процессе обнаружения каскад Хаара сканирует изображение в разных масштабах и местах, чтобы исключить ненужные области. Каскадная структура, обученная с помощью алгоритма AdaBoost, обеспечивает эффективную иерархическую оценку функций, снижая вычислительную нагрузку и увеличивая скорость обнаружения.
Каскад волос в OpenCV
Каскад Хаара — это алгоритм, но сначала вам необходимо обучить каскадный классификатор Хаара, прежде чем вы сможете использовать его в качестве детектора объектов.
В OpenCV имеются предварительно обученные каскадные классификаторы Хаара для следующих целей (файлы моделей можно скачать по адресу https://github.com/opencv/opencv/tree/ 4.x/data/haarcascades):
- человеческое лицо
- обнаружение глаз
- все тело, верхняя часть тела или нижняя часть тела человека
- номерной знак автомобиля
Предварительно обученный классификатор хранится в виде XML-файла. Имя файла встроенных классификаторов можно найти по ссылке GitHub. Чтобы создать классификатор, необходимо указать путь к этому XML-файлу. Если вы используете тот, который поставляется с OpenCV, вы можете использовать следующий синтаксис:
# Load the Haar cascade for face detection face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
Обычно фотография имеет несколько каналов для разных цветов (например, красного, зеленого и синего). Каскад Хаара зависит только от интенсивности пикселей. Следовательно, вам следует предоставить одноканальное изображение, например версию в оттенках серого.
Использование каскадного классификатора Хаара для обнаружения объектов означает использование метода detectMultiScale(). Он принимает следующие аргументы:
- image: это входное изображение, на котором вы хотите выполнить обнаружение объекта. Оно должно быть в формате оттенков серого или канал «V» для изображения в формате канала HSV.
- scaleFactor: этот параметр компенсирует тот факт, что объект на разных расстояниях от камеры будет иметь разные размеры. Он контролирует, насколько уменьшается размер изображения в каждом масштабе изображения. Оно должно быть строго больше 1. Меньшее значение scaleFactor увеличивает время обнаружения, но также увеличивает вероятность обнаружения. Типичные значения варьируются от 1,01 до 1,3.
- minNeighbors: этот параметр указывает, сколько соседей должен иметь каждый объект-кандидат, чтобы сохранить его. Более высокие значения приводят к меньшему количеству обнаружений, но с более высоким качеством. Более низкие значения могут привести к большему количеству обнаружений, но с возможными ложными срабатываниями. Это компромисс между точностью и отзывом.
- minSize: этот параметр устанавливает минимальный размер объекта. Объекты меньшего размера будут игнорироваться. Это кортеж вида (width, height).
Давайте попробуем на примере. Вы можете скачать уличную фотографию по следующему URL:

- https://unsplash.com/photos/people-walking-on-sidewalk-during-daytime-GBkAx9qUeus
Фото для распознавания лиц с помощью каскада Хаара.
Фото JACQUELINE BRANDWAYN. Некоторые права защищены.
В этом примере используется разрешение среднего размера 1920×1080. Если у вас другое разрешение, возможно, вам придется настроить аргументы detectMultiScale() ниже, в частности minSize.
Давайте создадим детектор лиц и найдем расположение лиц пешеходов. Классификатор создается с использованием предварительно обученной модели haarcascade_frontalface_default.xml, поставляемой с OpenCV. Файл модели находится по пути, указанному cv2.data.haarcascades. Затем мы можем использовать его для обнаружения лиц как ограничивающих рамок:
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4, minSize=(20, 20))
Не стесняйтесь корректировать параметры в вашем случае. Чтобы проиллюстрировать результат, вы можете использовать функцию OpenCV для рисования на исходном изображении.
for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
Обратите внимание, что функция cv2.rectangle() запрашивает координаты противоположных углов прямоугольного прямоугольника, а выходные данные detectMultiScale() предоставляют координаты вершины левый угол, а также ширину и высоту. Функция выше рисует синюю рамку шириной в два пикселя на каждом обнаруженном лице. Обратите внимание, что в OpenCV изображения представлены в порядке каналов BGR. Следовательно, цвет пикселя (255, 0, 0) соответствует синему цвету.

Лица, обнаруженные каскадом Хаара
Вы можете видеть, что есть некоторые ложные срабатывания, но в целом это дало довольно хороший результат. Вы можете настроить параметры выше, чтобы увидеть, как изменится ваш результат. Качество детектора объектов, использующего каскад Хаара, зависит от того, насколько хорошо он обучен создавать модель, которую вы считываете из XML-файла.
Полный код выглядит следующим образом:
import cv2 import sys # Photo https://unsplash.com/photos/people-walking-on-sidewalk-during-daytime-GBkAx9qUeus # Jacqueline Brandwayn filename = 'jacqueline-brandwayn-GBkAx9qUeus-unsplash.jpg' #filename = 'people2.jpg' # Load the Haar cascade for face detection face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # Read the input image img = cv2.imread(filename) # Convert the image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Perform face detection faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4, minSize=(20, 20)) # Draw rectangles around the detected faces for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) # Display the result cv2.imshow('Face Detection', img) cv2.waitKey(0) cv2.destroyAllWindows()
Дальнейшее чтение
В этом разделе представлены дополнительные ресурсы по этой теме, если вы хотите углубиться в нее.
Обучение OpenCV каскада Хаара

2014-01-04 в 1:38, admin , рубрики: Без рубрики

На хабре уже есть несколько статей и про то, что такое каскад Хаара (раз, два, три). Есть даже одна, где затронут процесс обучения, но в отношении описанной задачи. На тему обучения есть пара неплохих статей на английском (первая, вторая, третья), но, на мой взгляд, они путанные: либо рассказывают очень мало, либо слишком много и обо всём — выделить нужную мысль сложно.
В этой статье я попробую показать, как обучить каскад с нуля за несколько часов, натренировав на поиск простого предмета в видеопотоке (примером будет очаровательная сова с фотографии). Все обучающие выборки и программы будут приложены.
Зачем всё это нужно? Каскад Хаара это один из простейших способов распознавания классов объектов с большой скоростью работы. К ним относятся лица и руки людей, номера автомобилей, пешеходы. Детектором Хаара просто находить животных в кадре (кстати, удивительно, что я не видел ещё ни одной автоматической кормушки для синиц на raspberry pi). К тому же, готовые реализации OpenCV есть под большинство существующих систем (даже для blackfin’a встречал). Всё это делает Хаара одним из самых удобных методов, позволяющих решать задачи видеообработки даже людям, которые никогда не работали с обработкой видео.
Процесс
Весь процесс обучения выборки не требует навыков программирования. Для этого имеются уже готовые консольные программы, присутствующие в основной сборке OpenCV. Использование каскада требует минимального навыка программирования, достаточно изменить пару строк уже в готовом примере, которые есть под С, С++, С#, Java, Python и.т.д.
Что нам будет нужно?
- Фотографии предмета в реальной среде обитания. Чем более похожа выборка будет на то, что мы будем распознавать, тем лучше будут результаты. Если обучать распознаватель лица по фотографиям людей из студии, то на улице уровень распознавания будет ниже, чем в студии. На это влияют как тени, одежда, так и выражение лица.
- Выборка отрицательных фотографий, на которых нет объекта распознавания. Фотографии должны быть сделаны в той же среде где будет распознавание. Если выборка контрпримеров будет сделана по фотографиям на северном полюсе, а распознавать будете в тропических джунглях, то ничего не заработает.
- OpenCV. В этой статье использовался актуальный сейчас 2.4.7. Все программы примеры, расположенные тут будут работать с ним. Но если делаете проект с нуля — лучше скачайте новый OpenCV.
Где достать примеры и контрпримеры?
Есть несколько способов:
- Наснимать фотоаппаратом самому.
- Использовать готовую базу, если она есть в интернете. Для лиц, номеров, глаз, эмоций, людей и.т.д. таких баз много.
- Включить видеокамеру и сделать набор снимков из видеопотока.
- Использовать софтину, приложенную к OpenCV и сгенерировать новые выборки из имеющихся 2-3 изображений. Этот вариант подробно описан тут, я не буду на нём останавливаться. Работает он плохо, для серьёзных целей не годится.
Для вариантов 1-3 есть несколько программ упрощающих жизнь. В первую очередь это программы, позволяющие разметить фотографии. В статьях на английском используется самописная программа » imageclipper». Мне она не понравилась, так как некорректно работает с большими фотографиями. Для себя я написал программу, с которой было удобно работать мне. Исходники и код приложены в разделе «Загрузки» этой статьи (программа PictureCropper).
Сколько нужно фотографий?
Для стабильно работающего детектора лиц это 3000-4000 положительных примеров и столько же отрицательных. Из 500 положительных и 1000 отрицательных я делал стабильный детектор номеров. Для детектора, который показан в этой статье, я взял 250 положительных и 500 негативных фотографий.
Чем больше и разнообразнее выборка, тем стабильнее работает и тем дольше обучается.
Приступаем к работе.
Для того, чтобы начать обучение, нам нужно иметь 2 папки с примерами. «Good» — папка с позитивными изображениями, «Bad» — с отрицательными. ВАЖНО! По крайней мере, в одной из прошлых версий программы обучения она плохо реагировала на наличие пробелов и точек в названии файлов. Русский не воспринимает никакая версия. Старайтесь называть изображения «0.bmp», «1. bmp » и.т.д. Форматы » bmp » и «jpg» работают стабильно, с остальными не проверял.
Для каждой папки нужно иметь текстовый файл, в котором описаны используемые изображения. Назовём их «Good.dat» и «Bad.dat». ВАЖНО! Этот файл должен лежать на том же уровне файловой системы, на котором лежит папка.
Good 1. bmp 2. bmp . bmp N. bmp Bad 1. bmp 2. bmp . bmp N. bmp Good.dat Bad.dat
Файлы описания для отрицательных и положительных объектов имеют разную структуру. Для файла отрицательных примеров это просто список относительных путей к изображениям:
Bad1. bmp Bad2. bmp Bad. bmp BadN. bmp
Для файлов с положительными примерами запись чуть хитрее. Кроме пути должно быть указанно положение рассматриваемого объекта и его размер. В принципе, каждое положительное изображение может содержать несколько примеров объектов. Но я так не советую. Лучше всего: один кадр — один объект.
Good .bmp 1 0 0 414 148 Good 1.bmp 1 0 0 568 164 Good . bmp 1 0 0 440 144 Good N.bmp 1 0 0 590 182
» Good .bmp » — адрес объекта относительно файла описания. «1» — количество положительных объектов на изображении. «0 0 414 148» — координаты прямоугольника на изображении в котором находится объект. Если объектов несколько, то запись приобретает вид: «Good .bmp 2 100 200 50 50 300 300 25 25».
Повторюсь, что удобнее всего, когда каждый объект представляет собой отдельный кадр, при этом координаты объекта равны размеру кадра.
Пример снимков положительной выборки:

Пример снимков отрицательной выборки:

Начинаем обучать!
Само обучение происходит в два этапа. Первый этап — все положительные изображения приводятся к общему формату. Делать это нужно расположенной в папке OpenCV программой. Возьмите ту, что соответствует вашей системе. У меня это » opencvbuildx64vc10bin «. Программа называется opencv_createsamples.exe.
Для создания пачки приведённых положительных изображений запустим opencv_createsamples через консоль:
opencv_createsamples.exe -info E:BAZASSovaGood.dat-vec samples.vec -w 20 -h 20
-info E:BAZASSovaGood.dat – файл описания положительных изображений. Указывается либо полный адрес, либо относительно программы opencv_createsamples.exe.
-vec samples.vec – файл, в который будет сохранена приведённая к общему формату база положительных изображений. Адрес должен быть указан относительно программы opencv_createsamples.exe (допустим полный путь в системе).
-w 20 -h 20 — размер шаблона. Должен приблизительно отражать пропорции искомого объекта. Например, для лиц или для совы наиболее подходящая пропорция высоты к ширине 1*1. Для номеров это 3*1. А для поиска карандаша логично поставить что-то вроде 8*1. Размер шаблона должен быть достаточно маленьким. Идеально ставить его таким, чтобы человек сам мог отличить изображённый объект, но не больше того. Чем больше шаблон, тем дольше обучение.
Результатом работы программы является файл samples.vec, в котором будут лежать все ваши положительные изображения в формате, близком к bmp и с размером w*h.
Создаём итоговый каскад
Для подсчёта итогового каскада используется программа «opencv_traincascade.exe», лежащая в той же папке, что и opencv_createsamples.exe. Работает долго. Даже очень долго. Обучение каскада на 500-1000 объектов займёт почти целый день. Пример обучался часа 2. При вызове:
opencv_traincascade.exe -data haarcascade -vec samples.vec -bg E:BAZASSovaBad.dat -numStages 16 -minhitrate 0.999 -maxFalseAlarmRate 0.4 -numPos 200 -numNeg 500 -w 20 -h 20 -mode ALL -precalcValBufSize 1024 -precalcIdxBufSize 1024
-data haarcascade — адрес папки, куда класть полученные результаты. Отсчитывается от корневой папки программы. Нужно создать заранее, а то всё вылетит.
-vec samples.vec — адрес посчитанного в прошлом пункте файла с положительными примерами
-bg E:BAZASSovaBad.dat — адрес файла-описания отрицательных примеров
-numStages 16 — количество уровней каскада, которые программа будет обучать. Чем больше уровней, тем точнее, но тем дольше. Нормальное их количество от 16 до 25.
-minhitrate 0.999 — коэффициент, определяющий качество обучения. По сути, это процент “правильных” обнаружений. Если установлено .999, то есть по исходной выборке будет не более, чем 1- 0.999 =0.1% пропусков целей. Чем выше коэффициент, тем выше уровень ложных тревог. В принципе, если выборка хорошая, можно ставить 0.99-0.999. Если плохая ( объектов мало, они смешиваются с фоном) — то следует опускать.
-maxFalseAlarmRate 0.4 — уровень ложной тревоги. AdaBoost — такой алгоритм, который может любой уровень ложной тревоги по выборке натянуть. Но лучше что-то разумное сделать. По умолчанию все ставят 0.5. Но, возможно, будет иметь смысл поиграться. В случае, если выборка очень хорошая, то уровень требуемой тревоги будет быстро достигнут, и обучение будет остановлено.
-numPos 200 — количество позитивных примеров. ВАЖНО! Казалось бы, тут должно стоять число файлов, которые у вас были. Но это не так (в большинстве руководств это не отмечено). Чем ниже коэффициент «minhitrate », тем больше ваших файлов будет считаться непригодными. В большинстве случаев достаточно поставить numPos 80% от имеющихся у вас положительных файлов. Лучше перестраховаться, чтобы через день работы программа не вылетела с ошибкой:)
-numNeg 500 — количество имеющихся у вас негативных примеров. Что есть — то и пишем.
-w 20 -h 20 — размер примитива из прошлого пункта.
-mode ALL — использовать или нет полный комплект Хаар-признаков. От этого зависит скорость работы и точность алгоритма. Но есть ситуации, когда полного комплекта признаков не нужно (например, если ваш объект не меняет ориентацию).
-precalcValBufSize 1024 -precalcIdxBufSize 1024 — выделяемая под процесс память. Вроде, в последней версии OpenCV, сколько я заявил, примерно столько программа и съела, но чуть более ранние версии ели где-то в 2 раза больше. Если во время обучения вы планируете пользоваться компьютером, то ставьте столько памяти, чтобы вам хватило на дальнейшую работу.
Известные баги
Нужно сказать, что обучение не страдает юзабельностью. Есть много багов. Но потихоньку OpenCV исправляется. В последнем OpenCV достаточно подробно объясняются большинство причин, по которым вылетает программа. Как правило, это нехватка положительных или отрицательных примеров, недостижимые характеристики, криво написанные адреса. Правда, был какой-то глюк с подвисанием обучения, когда я обучал выборку по сове. Cудя по всему, было слишком мало тестовых примеров (я тогда использовал 150 сов и 200 контр-примеров).
Результаты
Пример работы алгоритма на видео. Видно, что имеются пропуски. Но для выборки, в которой всего две сотни примеров, это неплохой результат.
Исходники
Как и обещал, пример проекта и несколько программок, облегчающих жизнь. Скачать целиком можно либо тут (rar-архив на яндекс-диске), либо тут (github). Но на гитхабе максимальный объем файла 100 мегов, а сборка Emgu (OpenCV для C#), которую я использую, тянет два больших файла OpenCV-шных, которые не используются, но которые нельзя исключить из проекта. Оба этих файла лежат внутри папки Binx86, заархивированы в архиве «lagedll.rar», их нужно просто вытащить наружу.
Весь проект на VS2010, Windows 7. Все исполняемые программы лежат в папке » Bin».
VideoCropper — Программа для создания последовательности с видеокамеры. При старте нужно указать папку для сохранения и режим работы (создание положительной или отрицательной выборки). Мышкой выделяется область, которая будет сохранена, по пробелу происходит сохранение области.
PictureCropper — Программа для нарезки имеющейся базы фотографий. При старте указывается рабочая папка. Создает подпапку с нарезанными изображениями. Мышкой выделяется область которая должна быть сохранена. По «s» происходит сохранение. По «r» – сохранение и переход к следующему изображению. По пробелу — просто переход к следующему изображению.
OwlDetector — итоговая программа, ищущая сову
Bad, Good — папки с отрицательными и положительными примерами
haarcascade — Итоговые каскады, полученные при обучении
Bad.dat, Good.dat — файлы описания изображений
samples.vec — файл с набором положительных изображений, подготовленный для обучения
Обучение OpenCV каскада Хаара

На хабре уже есть несколько статей и про то, что такое каскад Хаара (раз, два, три). Есть даже одна, где затронут процесс обучения, но в отношении описанной задачи. На тему обучения есть пара неплохих статей на английском (первая, вторая, третья), но, на мой взгляд, они путанные: либо рассказывают очень мало, либо слишком много и обо всём — выделить нужную мысль сложно.
В этой статье я попробую показать, как обучить каскад с нуля за несколько часов, натренировав на поиск простого предмета в видеопотоке (примером будет очаровательная сова с фотографии). Все обучающие выборки и программы будут приложены.
Зачем всё это нужно? Каскад Хаара это один из простейших способов распознавания классов объектов с большой скоростью работы. К ним относятся лица и руки людей, номера автомобилей, пешеходы. Детектором Хаара просто находить животных в кадре (кстати, удивительно, что я не видел ещё ни одной автоматической кормушки для синиц на raspberry pi). К тому же, готовые реализации OpenCV есть под большинство существующих систем (даже для blackfin’a встречал). Всё это делает Хаара одним из самых удобных методов, позволяющих решать задачи видеообработки даже людям, которые никогда не работали с обработкой видео.
NB.
Статья которую вы читаете — из 2014 года. С тех пор произошла революция в обработке изображений. Сегодня не следует использовать каскады Хаара для детектирования чего бы то ни было. Появилось масса нейронных сетей которые работают быстрее и лучше. На телефонах появилась аппаратная поддержка исполнения нейронных сетей. Масса простых и удобных фреймворков для тренировки и исполнения нейронных сетей.
Тот же OpenCV, о котором тут речь, умеет исполнять практически любую заранее обученную нейронную сеть (почитать об этом можно, например, в другой моей статье).
Что использовать? Я не знаю в каком году вы читаете эту статью. Мои ответы за прошлые года 4 разительно менялись. Например в начале 2019 года я записывал такое видео. Но сейчас, в 2020, оно уже не очень актуально. Может быть лучше смотреть в сторону EfficientDet, Yolov4, и IterDet, и другие детекторы.
А TensorFlow Detection Api кардинально изменился с тех пор, в второй версии. Да и для новичков я бы советовал скорее PyTorch.
Короче, я бы советовал гуглить. Гуглите «neural network for detection», или «training detection network». И внимательно следите за годом!
И ещё. Если я правильно понимаю, то OpenCV в 2020 уже не имеет порядочный кусок из функций описанный в статье. Если вы все же хотите использовать написанное тут — используйте версию OpenCV тех лет.
А так, я часто пишу на своем канале (vk, telegram) про более новые методы/подходы.
Процесс
Весь процесс обучения выборки не требует навыков программирования. Для этого имеются уже готовые консольные программы, присутствующие в основной сборке OpenCV. Использование каскада требует минимального навыка программирования, достаточно изменить пару строк уже в готовом примере, которые есть под С, С++, С#, Java, Python и.т.д.
Что нам будет нужно?
- Фотографии предмета в реальной среде обитания. Чем более похожа выборка будет на то, что мы будем распознавать, тем лучше будут результаты. Если обучать распознаватель лица по фотографиям людей из студии, то на улице уровень распознавания будет ниже, чем в студии. На это влияют как тени, одежда, так и выражение лица.
- Выборка отрицательных фотографий, на которых нет объекта распознавания. Фотографии должны быть сделаны в той же среде где будет распознавание. Если выборка контрпримеров будет сделана по фотографиям на северном полюсе, а распознавать будете в тропических джунглях, то ничего не заработает.
- OpenCV. В этой статье использовался актуальный сейчас 2.4.7. Все программы примеры, расположенные тут будут работать с ним. Но если делаете проект с нуля — лучше скачайте новый OpenCV.
Где достать примеры и контрпримеры?
- Наснимать фотоаппаратом самому.
- Использовать готовую базу, если она есть в интернете. Для лиц, номеров, глаз, эмоций, людей и.т.д. таких баз много.
- Включить видеокамеру и сделать набор снимков из видеопотока.
- Использовать софтину, приложенную к OpenCV и сгенерировать новые выборки из имеющихся 2-3 изображений. Этот вариант подробно описан тут, я не буду на нём останавливаться. Работает он плохо, для серьёзных целей не годится.
Сколько нужно фотографий?
Для стабильно работающего детектора лиц это 3000-4000 положительных примеров и столько же отрицательных. Из 500 положительных и 1000 отрицательных я делал стабильный детектор номеров. Для детектора, который показан в этой статье, я взял 250 положительных и 500 негативных фотографий.
Чем больше и разнообразнее выборка, тем стабильнее работает и тем дольше обучается.
Приступаем к работе.
Для того, чтобы начать обучение, нам нужно иметь 2 папки с примерами. «Good» — папка с позитивными изображениями, «Bad» — с отрицательными. ВАЖНО! По крайней мере, в одной из прошлых версий программы обучения она плохо реагировала на наличие пробелов и точек в названии файлов. Русский не воспринимает никакая версия. Старайтесь называть изображения «0.bmp», «1. bmp » и.т.д. Форматы » bmp » и «jpg» работают стабильно, с остальными не проверял.
Для каждой папки нужно иметь текстовый файл, в котором описаны используемые изображения. Назовём их «Good.dat» и «Bad.dat». ВАЖНО! Этот файл должен лежать на том же уровне файловой системы, на котором лежит папка.
\Good \1. bmp \2. bmp \. bmp \N. bmp \Bad \1. bmp \2. bmp \. bmp \N. bmp Good.dat Bad.dat
Файлы описания для отрицательных и положительных объектов имеют разную структуру. Для файла отрицательных примеров это просто список относительных путей к изображениям:
Bad\1. bmp Bad\2. bmp Bad\. bmp Bad\N. bmp
Для файлов с положительными примерами запись чуть хитрее. Кроме пути должно быть указанно положение рассматриваемого объекта и его размер. В принципе, каждое положительное изображение может содержать несколько примеров объектов. Но я так не советую. Лучше всего: один кадр — один объект.
Good \0.bmp 1 0 0 414 148 Good \1.bmp 1 0 0 568 164 Good \. bmp 1 0 0 440 144 Good \N.bmp 1 0 0 590 182
» Good \0.bmp » — адрес объекта относительно файла описания. «1» — количество положительных объектов на изображении. «0 0 414 148» — координаты прямоугольника на изображении в котором находится объект. Если объектов несколько, то запись приобретает вид: «Good \0.bmp 2 100 200 50 50 300 300 25 25».
Повторюсь, что удобнее всего, когда каждый объект представляет собой отдельный кадр, при этом координаты объекта равны размеру кадра.
Пример снимков положительной выборки:


Пример снимков отрицательной выборки:


Начинаем обучать!
Само обучение происходит в два этапа. Первый этап — все положительные изображения приводятся к общему формату. Делать это нужно расположенной в папке OpenCV программой. Возьмите ту, что соответствует вашей системе. У меня это » opencv\build\x64\vc10\bin «. Программа называется opencv_createsamples.exe.
Для создания пачки приведённых положительных изображений запустим opencv_createsamples через консоль:
opencv_createsamples.exe -info E:\BAZAS\Sova\Good.dat -vec samples.vec -w 20 -h 20
-info E:\BAZAS\Sova\Good.dat – файл описания положительных изображений. Указывается либо полный адрес, либо относительно программы opencv_createsamples.exe.
-vec samples.vec – файл, в который будет сохранена приведённая к общему формату база положительных изображений. Адрес должен быть указан относительно программы opencv_createsamples.exe (допустим полный путь в системе).
-w 20 -h 20 — размер шаблона. Должен приблизительно отражать пропорции искомого объекта. Например, для лиц или для совы наиболее подходящая пропорция высоты к ширине 1*1. Для номеров это 3*1. А для поиска карандаша логично поставить что-то вроде 8*1. Размер шаблона должен быть достаточно маленьким. Идеально ставить его таким, чтобы человек сам мог отличить изображённый объект, но не больше того. Чем больше шаблон, тем дольше обучение.
Результатом работы программы является файл samples.vec, в котором будут лежать все ваши положительные изображения в формате, близком к bmp и с размером w*h.
Создаём итоговый каскад
Для подсчёта итогового каскада используется программа «opencv_traincascade.exe», лежащая в той же папке, что и opencv_createsamples.exe. Работает долго. Даже очень долго. Обучение каскада на 500-1000 объектов займёт почти целый день. Пример обучался часа 2. При вызове:
opencv_traincascade.exe -data haarcascade -vec samples.vec -bg E:\BAZAS\Sova\Bad.dat -numStages 16 -minhitrate 0.999 -maxFalseAlarmRate 0.4 -numPos 200 -numNeg 500 -w 20 -h 20 -mode ALL -precalcValBufSize 1024 -precalcIdxBufSize 1024
-data haarcascade — адрес папки, куда класть полученные результаты. Отсчитывается от корневой папки программы. Нужно создать заранее, а то всё вылетит.
-vec samples.vec — адрес посчитанного в прошлом пункте файла с положительными примерами
-bg E:\BAZAS\Sova\Bad.dat — адрес файла-описания отрицательных примеров
-numStages 16 — количество уровней каскада, которые программа будет обучать. Чем больше уровней, тем точнее, но тем дольше. Нормальное их количество от 16 до 25.
-minhitrate 0.999 — коэффициент, определяющий качество обучения. По сути, это процент “правильных” обнаружений. Если установлено .999, то есть по исходной выборке будет не более, чем 1- 0.999 =0.1% пропусков целей. Чем выше коэффициент, тем выше уровень ложных тревог. В принципе, если выборка хорошая, можно ставить 0.99-0.999. Если плохая ( объектов мало, они смешиваются с фоном) — то следует опускать.
-maxFalseAlarmRate 0.4 — уровень ложной тревоги. AdaBoost — такой алгоритм, который может любой уровень ложной тревоги по выборке натянуть. Но лучше что-то разумное сделать. По умолчанию все ставят 0.5. Но, возможно, будет иметь смысл поиграться. В случае, если выборка очень хорошая, то уровень требуемой тревоги будет быстро достигнут, и обучение будет остановлено.
-numPos 200 — количество позитивных примеров. ВАЖНО! Казалось бы, тут должно стоять число файлов, которые у вас были. Но это не так (в большинстве руководств это не отмечено). Чем ниже коэффициент «minhitrate », тем больше ваших файлов будет считаться непригодными. В большинстве случаев достаточно поставить numPos 80% от имеющихся у вас положительных файлов. Лучше перестраховаться, чтобы через день работы программа не вылетела с ошибкой:)
-numNeg 500 — количество имеющихся у вас негативных примеров. Что есть — то и пишем.
-w 20 -h 20 — размер примитива из прошлого пункта.
-mode ALL — использовать или нет полный комплект Хаар-признаков. От этого зависит скорость работы и точность алгоритма. Но есть ситуации, когда полного комплекта признаков не нужно (например, если ваш объект не меняет ориентацию).
-precalcValBufSize 1024 -precalcIdxBufSize 1024 — выделяемая под процесс память. Вроде, в последней версии OpenCV, сколько я заявил, примерно столько программа и съела, но чуть более ранние версии ели где-то в 2 раза больше. Если во время обучения вы планируете пользоваться компьютером, то ставьте столько памяти, чтобы вам хватило на дальнейшую работу.
Известные баги
Нужно сказать, что обучение не страдает юзабельностью. Есть много багов. Но потихоньку OpenCV исправляется. В последнем OpenCV достаточно подробно объясняются большинство причин, по которым вылетает программа. Как правило, это нехватка положительных или отрицательных примеров, недостижимые характеристики, криво написанные адреса. Правда, был какой-то глюк с подвисанием обучения, когда я обучал выборку по сове. Cудя по всему, было слишком мало тестовых примеров (я тогда использовал 150 сов и 200 контр-примеров).
Результаты
Пример работы алгоритма на видео. Видно, что имеются пропуски. Но для выборки, в которой всего две сотни примеров, это неплохой результат.
Исходники
Как и обещал, пример проекта и несколько программок, облегчающих жизнь. Скачать целиком можно либо тут (rar-архив на яндекс-диске), либо тут (github). Но на гитхабе максимальный объем файла 100 мегов, а сборка Emgu (OpenCV для C#), которую я использую, тянет два больших файла OpenCV-шных, которые не используются, но которые нельзя исключить из проекта. Оба этих файла лежат внутри папки Bin\x86, заархивированы в архиве «lagedll.rar», их нужно просто вытащить наружу.
Весь проект на VS2010, Windows 7. Все исполняемые программы лежат в папке » Bin».
VideoCropper — Программа для создания последовательности с видеокамеры. При старте нужно указать папку для сохранения и режим работы (создание положительной или отрицательной выборки). Мышкой выделяется область, которая будет сохранена, по пробелу происходит сохранение области.
PictureCropper — Программа для нарезки имеющейся базы фотографий. При старте указывается рабочая папка. Создает подпапку с нарезанными изображениями. Мышкой выделяется область которая должна быть сохранена. По «s» происходит сохранение. По «r» – сохранение и переход к следующему изображению. По пробелу — просто переход к следующему изображению.
OwlDetector — итоговая программа, ищущая сову
Bad, Good — папки с отрицательными и положительными примерами
haarcascade — Итоговые каскады, полученные при обучении
Bad.dat, Good.dat — файлы описания изображений
samples.vec — файл с набором положительных изображений, подготовленный для обучения
- каскад Хаара
- распознавание образов
- признаки Хаара
- pattern recognition
- machine learning
- Алгоритмы
- Обработка изображений