каскад хаара что это
Python | Каскады Хаара для обнаружения объектов
Обнаружение объектов — это компьютерная технология, связанная с компьютерным зрением, обработкой изображений и глубоким обучением, которая занимается обнаружением объектов на изображениях и видео. В этой статье мы сделаем обнаружение объектов, используя нечто, известное как каскады Хаара.
Что такое каскады Хаара?
Классификаторы Хаара Каскад являются эффективным способом обнаружения объектов. Этот метод был предложен Полом Виолой и Майклом Джонсом в их статье « Быстрое обнаружение объектов» с использованием расширенного каскада простых функций. Хаарский каскад — это подход, основанный на машинном обучении, в котором для обучения классификатора используется множество положительных и отрицательных изображений.
Требования
Реализация
# Импорт всех необходимых пакетов
import numpy as np
import matplotlib.pyplot as plt % matplotlib inline
# Читать в каскадных классификаторах для лица и глаз
face_cascade = cv2.CascadeClassifier( ‘../DATA / haarcascades / haarcascade_frontalface_default.xml’ )
eye_cascade = cv2.CascadeClassifier( ‘../DATA / haarcascades / haarcascade_eye.xml’ )
# создать функцию для обнаружения лица
for (x, y, w, h) in face_rect:
cv2.rectangle(face_img, (x, y),
# создать функцию для обнаружения глаз
for (x, y, w, h) in eye_rect:
cv2.rectangle(eye_img, (x, y),
# Чтение на изображении и создание копий
img = cv2.imread( ‘../sachin.jpg’ )
Код: обнаружение глаз
Код: обнаружение лица и глаз
Каскады Хаара могут использоваться для обнаружения любых типов объектов, если для этого у вас есть соответствующий XML-файл. Вы даже можете создавать свои собственные файлы XML с нуля, чтобы обнаружить любой тип объекта, который вы хотите.
Обучение OpenCV каскада Хаара
На хабре уже есть несколько статей и про то, что такое каскад Хаара (раз, два, три). Есть даже одна, где затронут процесс обучения, но в отношении описанной задачи. На тему обучения есть пара неплохих статей на английском (первая, вторая, третья), но, на мой взгляд, они путанные: либо рассказывают очень мало, либо слишком много и обо всём — выделить нужную мысль сложно. 
В этой статье я попробую показать, как обучить каскад с нуля за несколько часов, натренировав на поиск простого предмета в видеопотоке (примером будет очаровательная сова с фотографии). Все обучающие выборки и программы будут приложены.
Зачем всё это нужно? Каскад Хаара это один из простейших способов распознавания классов объектов с большой скоростью работы. К ним относятся лица и руки людей, номера автомобилей, пешеходы. Детектором Хаара просто находить животных в кадре (кстати, удивительно, что я не видел ещё ни одной автоматической кормушки для синиц на raspberry pi). К тому же, готовые реализации OpenCV есть под большинство существующих систем (даже для blackfin’a встречал). Всё это делает Хаара одним из самых удобных методов, позволяющих решать задачи видеообработки даже людям, которые никогда не работали с обработкой видео.
Статья которую вы читаете — из 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 и.т.д.
Что нам будет нужно?
Где достать примеры и контрпримеры?
Сколько нужно фотографий?
Для стабильно работающего детектора лиц это 3000-4000 положительных примеров и столько же отрицательных. Из 500 положительных и 1000 отрицательных я делал стабильный детектор номеров. Для детектора, который показан в этой статье, я взял 250 положительных и 500 негативных фотографий.
Чем больше и разнообразнее выборка, тем стабильнее работает и тем дольше обучается.
Приступаем к работе.
Для того, чтобы начать обучение, нам нужно иметь 2 папки с примерами. «Good» — папка с позитивными изображениями, «Bad» — с отрицательными. ВАЖНО! По крайней мере, в одной из прошлых версий программы обучения она плохо реагировала на наличие пробелов и точек в названии файлов. Русский не воспринимает никакая версия. Старайтесь называть изображения «0.bmp», «1. bmp » и.т.д. Форматы » bmp » и «jpg» работают стабильно, с остальными не проверял.
Для каждой папки нужно иметь текстовый файл, в котором описаны используемые изображения. Назовём их «Good.dat» и «Bad.dat». ВАЖНО! Этот файл должен лежать на том же уровне файловой системы, на котором лежит папка.
Файлы описания для отрицательных и положительных объектов имеют разную структуру. Для файла отрицательных примеров это просто список относительных путей к изображениям:
Для файлов с положительными примерами запись чуть хитрее. Кроме пути должно быть указанно положение рассматриваемого объекта и его размер. В принципе, каждое положительное изображение может содержать несколько примеров объектов. Но я так не советую. Лучше всего: один кадр — один объект.
» 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_traincascade.exe», лежащая в той же папке, что и opencv_createsamples.exe. Работает долго. Даже очень долго. Обучение каскада на 500-1000 объектов займёт почти целый день. Пример обучался часа 2. При вызове:
Известные баги
Нужно сказать, что обучение не страдает юзабельностью. Есть много багов. Но потихоньку OpenCV исправляется. В последнем OpenCV достаточно подробно объясняются большинство причин, по которым вылетает программа. Как правило, это нехватка положительных или отрицательных примеров, недостижимые характеристики, криво написанные адреса. Правда, был какой-то глюк с подвисанием обучения, когда я обучал выборку по сове. Cудя по всему, было слишком мало тестовых примеров (я тогда использовал 150 сов и 200 контр-примеров).
Визуализация каскадов Хаара
Интерпретируемое машинное обучение — популярная тема в последние годы. Во многом благодаря использованию этой технологии в медицине, транспорте и других областях, где цена ошибки велика, нужно понимать, как модель устроена и чем «руководствуется» при принятии решений.
Простота объяснения зависит от сложности модели. Куда проще понять, как работает дерево принятия решений, чем извлечь какие-то определенные правила из весов полносвязной нейронки. К счастью, каскады Хаара имеют довольно простую структуру и можно, последовательно применяя их к изображению, узнать, как работает модель.
Парсинг xml-файла
Начнем с начала. OpenCV работает с каскадами, сохраненными в xml. Автор статьи помог разобраться, как этот файл устроен. Давайте посмотрим.
Сперва идет описание каскада. Будем использовать детектор лиц из OpenCV. stageType говорит нам, что каскады являются бустингом. featureType — тип признаков, а height и width — высота и ширина признаков, используемых классификаторами. maxWeakCount — максимальное количество слабых классификаторов на каждом уровне каскада. stageNum — количество уровней.
Что за признаки и классификаторы? Признаки — это небольшие свертки (маски), которые применяются к изображению.
Из пикселей изображения, находящихся под белой областью, вычитаются пиксели, находящиеся под черной областью
Классификаторы — это решающие деревья, которые после получения значений от сверток выдают какие-то чиселки. И в зависимости от суммы этих чиселок каскад решает, есть ли на изображении нужный предмет.
Уровни ( stages ) — это группы классификаторов. Каждый уровень смотрит на активацию своих классификаторов и говорит, нужно ли уточнить свои показания (перейти на следующий уровень) или пропустить изображение, потому что на нем ничего нет.
С файлом разобрались, давайте парсить:
Отрисовка классификаторов
Итак, у нас 25 уровней. Давайте наложим их на картинку:
Кислотный Шерлок
Код выведет 25 картинок, поэтому я прикреплю только последние 2:
В ноутбуке после статьи можно посмотреть активации на разных размерах картинки:
Куда копать дальше?
Я реализовал визуализацию только одноуровневых каскадов (то есть деревьев с одной нодой и двумя листами), но это можно относительно просто исправить. А чтобы посчитать, какое значение свертки принесет наибольшую активацию, можно распарсить дерево и вытащить оттуда промежуток значений [свертки].
Помимо признаков Хаара есть и другие. Например, LBF или обобщенные признаки Хаара. Их также можно визуализировать. Также на картинке можно показывать сами признаки — отображать не белый прямоугольник, а матрицу классификатора (черно-белые области).
Весь код (ноутбук и скрипт для разбора одного каскада) оставлю на Github’е, так что его можно модифицировать, добавляя новые фичи.
Немного о нас
Еще раз привет, меня зовут Евгений. Обожаю Data science (и особенно — учить модельки *^*) и занимаюсь им полтора года. Этот пост создан благодаря нашей команде. Мы — начинающие российские стартаперы и хотим делиться с Вами тем, что узнаем сами.
Обучение каскада Хаара на примере поиска символов автомобильного номера OpenCV
Поиска объекта на цифровом изображении одна из приоритетных задач в области распознавания изображений с помощью библиотеки OpenCV.
В данной статье рассматриваются математические основы Метода Виолы-Джонса и процесс поиска и распознавания букв автомобильного номера с помощью OpenCV и детектора Хаара.
О детекторе Хаара и библиотеке OpenCV
Принцип работы
Классификатор формируется на примитивах Хаара путём расчёта значений признаков. Для обучения на вход классификатора сначала подаётся набор «правильных» изображений с предварительно выделенной областью на изображении, дальше происходит перебор примитивов и расчёт значения признака. Вычисленные значения сохраняются в файле в формате xml.
Немного математики
Принципы метода Виолы-Джонса
В настоящее время метод Виолы–Джонса является популярным методом для поиска объекта на изображении в силу своей высокой скорости и эффективности. В основу метода Виолы–Джонса положены: интегральное представление изображения по признакам Хаара, построение классификатора на основе алгоритма адаптивного бустинга и способ комбинирования классификаторов в каскадную структуру. Эти идеи позволяют осуществлять поиск объекта в режиме реального времени. Рассмотрим их более подробно.
Интегральное представление изображения – это матрица, одинаковая по размерам с исходным изображением. В каждом элементе матрицы хранится сумма интенсивностей всех пикселов, находящихся левее и выше данного элемента – правого нижнего угла прямоугольной области (0,0) до (x,y). Элементы матрицы L можно рассчитать по формуле:
Расчёт значений элементов матрицы проходит за время, пропорциональное числу пикселов в исходном изображении, поэтому интегральное изображение просчитывается за один проход.
Элементы матрицы рассчитываются по формуле:
L(x,y)= I(x,y)+ L(x-1,y-1) + L(x,y-1) + L(x-1,y)
С помощью интегрального представления изображения можно быстро рассчитать суммарную яркость произвольной прямоугольной области на изображении. Пример вычисления приведен в приложении 1.
На этапе обнаружения объекта в методе Виолы-Джонса используется окно определенного размера, которое движется по изображению. Для каждой области изображения, над которой проходит окно, рассчитывается признак Хаара, с помощью которого происходит поиск нужного объекта.
Признаки делятся на следующие типы в зависимости от множества Df:
Признак Хаара вычисляется по смежным прямоугольным областям. В стандартном методе Виолы–Джонса используются прямоугольные примитивы, изображенные на рисунке 1.
Рисунок 1 – Примитивы Хаара
Вычисляемым значением F признака Хаара будет
где X – сумма значений яркостей точек, закрываемых светлой частью примитива, Y –сумма значений яркостей точек, закрываемых темной частью. Для вычисления используется понятие интегрального изображения, рассмотренное выше, и признаки Хаара могут вычисляться быстро, за постоянное время. Использование признаков Хаара дает точечное значение перепада яркости по оси X и Y соответственно.
Поскольку признаки Хаара мало подходят для обучения или классификации, для описания объекта с достаточной точностью необходимо большее число признаков. Поэтому признаки Хаара поступают в каскадный классификатор, служащий для быстрого отбрасывания окон, где не найден требуемый объект, и выдачи результата «истина» или «ложь» относительно нахождения объекта.
Классификатор строится на основе алгоритма бустинга (от англ.boost–улучшение, усиление) для выбора наиболее подходящих признаков для искомого объекта на данной части изображения. В общем случае бустинг — это комплекс методов, способствующих повышению точности аналитических моделей. Эффективная модель, допускающая мало ошибок классификации, называется «сильной». «Слабая» же, напротив, не позволяет надежно разделять классы или давать точные предсказания, делает большое количество ошибок. Поэтому бустинг означает «усиление» «слабых» моделей и является процедурой последовательного построения композиции алгоритмов машинного обучения, когда каждый следующий алгоритм стремится компенсировать недостатки композиции всех предыдущих алгоритмов.
В результате работы алгоритма бустинга на каждой итерации формируется простой классификатор вида:
p_j– направление знака неравенства, θ_j— значение порога, f_j(z)– вычисленное значение признака, z – окно изображения размером 24×24 пикселов.
Полученный классификатор имеет минимальную ошибку по отношению к текущим значениям весов, задействованным в процедуре обучения для определения ошибки.
Для поиска объекта на цифровом изображении используется обученный классификатор, представленный в формате xml. Классификатор формируется на примитивах Хаара.
где maxWeakCount – количество слабых классификаторов;
stageThereshold – максимальный порог яркости;
weakClassifiers – набор слабых классификаторов, на основе которых выносится решение о том, находится объект на изображении или нет;
internalNodes и leafValues – параметры конкретного слабого классификатора.
Первые два значения в internalNodes не используются, третье — номер признака в общей таблице признаков (она располагается в XML-файле под тегом features), четвертое — пороговое значение слабого классификатора. Если значение признака Хаара меньше порога слабого классификатора, выбирается первое значение leafValues, если больше — второе.
На основе этого базиса строится каскад классификаторов, принимающих решение о том, распознан объект на изображении или нет. Наличие или отсутствие предмета в окне определяется разницей между значением признака и порогом, полученным в результате обучения.
Обучение каскада Хаара
Для начала поставим задачу. Например, на изображении автомобильного номера необходимо выделить символы.
Классификатор формируется на примитивах Хаара путём расчёта значений признаков. Для обучения на вход классификатора сначала подаётся набор «правильных» изображений с предварительно выделенной областью автомобильного номера, дальше происходит перебор примитивов и расчёт значения признака. Вычисленные значения сохраняются в файле в формате xml.
Утилита для обучения каскада Хаара встроена в пакет OpenCV.
Для обучения нам необходимо собрать коллекцию файлов, которые нам в дальнейшем понадобятся.
Список:
Сколько нужно фотографий?
Для стабильно работающего детектора лиц это 3000-4000 положительных примеров и столько же отрицательных. Из 500 положительных и 1000 отрицательных мои коллеги делали стабильный детектор номеров. Для детектора, который показан в этой статье, я взял 500 положительных и 500 негативных фотографий.
Чем больше и разнообразнее выборка, тем стабильнее работает и тем дольше обучается.
Начнём
Для начала нам нужно сформировать папку с положительными и отрицательными фотографиями. Для данной цели я использовал программу Picture Cropper скачать. Работа с программой: мышкой выделяется область которая должна быть сохранена. По «s» происходит сохранение. По «r» – сохранение и переход к следующему изображению. По пробелу — просто переход к следующему изображению.
Для обучения нам нужно иметь 2 папки с примерами. «Good» — папка с позитивными изображениями, «Bad» — с отрицательными. Стоит учесть, что OpenCV отказывается работать с точками, пробелами и спец. символами. Не используйте данные символы в названиях примеров. Идеальные названия: «0.bmp», «1. bmp» и.т.д.
Для каждой папки с примерами необходимо иметь файл описания, в котором описаны используемые изображения. Стандартно их называют «Good.dat» и «Bad.dat».
Файлы должны лежать на одном уровне с папками.
Файлы описания для отрицательных и положительных объектов имеют разную структуру. Для файла отрицательных примеров это просто список относительных путей к изображениям:
Для файлов с положительными примерами запись чуть хитрее. Кроме пути должно быть указанно положение рассматриваемого объекта и его размер. Стоит помнить, что один кадр — один объект.
«Good \0.bmp» — адрес объекта относительно файла описания. «1» — количество положительных объектов на изображении. «0 0 414 148» — координаты прямоугольника на изображении в котором находится объект. Если объектов несколько, то запись приобретает вид: «Good \0.bmp 2 100 200 50 50 300 300 25 25».
Удобнее всего, когда каждый объект представляет собой отдельный кадр, при этом координаты объекта равны размеру кадра.
Пример создания Good.dat и Bad.dat на примере работы с Picture Cropper
В итоге у нас должна получиться следующая структура:
Кладём в папку Good и Bad необходимые файлы.
Запускаем PictureCropper.exe.
Выбираем нужную папку и обрабатываем изображения.
Работа с программой: мышкой выделяется область которая должна быть сохранена. По «s» происходит сохранение. По «r» – сохранение и переход к следующему изображению. По пробелу — просто переход к следующему изображению.
После завершения работы у нас должен появиться Good.dat. И в папке Good папка Cropper, в которой хранятся обрезанные изображения.
Отлично. Проделываем тоже самое с папкой Bad.
После процедуры обработки фотографий в папке Bad, приведём его файл описания Bad.dat к «правильному виду».
Сейчас файл Bad.dat выглядит следующим образом:
Приводим его к нужному формату:
На этом работа с файлами описания закончена.
Переходим к обучению.
Для начала откроем командную строку и перейдём в директорию с файлом описания Good.dat, то есть в папку learn:
Для создания пачки приведённых положительных изображений запустим opencv_createsamples через консоль:
Если всё прошло успешно должен появиться файл samples.vec.
Созданием основного каскада:
Для подсчёта итогового каскада используется программа «opencv_traincascade.exe», лежащая в той же папке, что и opencv_createsamples.exe. Работает долго. Даже очень долго. Обучение каскада на 500-1000 объектов займёт почти целый день. Пример обучался часа 24. При вызове:
После того, как алгоритм закончит работу, у вас появится папка haarcascade и файл cascade.xml в этой папке, это и будет созданный каскад.
Пример выполнения:
Напишем простую программу на OpenCV для демонстрации работы алгоритма:

















