Края(границы) — это такие кривые на изображении, вдоль которых происходит резкое изменение яркости или других видов неоднородностей.
Проще говоря, край — это резкий переход/изменение яркости.
Причины возникновения краёв:
* изменение освещенности
* изменение цвета
* изменение глубины сцены (ориентации поверхности)
Получается, что края отражают важные особенности изображения и поэтому, целями преобразования изображения в набор кривых являются:
* выделение существенных характеристик изображения
* сокращение объема информации для последующего анализа
Самым популярным методом выделения границ является детектор границ Кенни.
Хотя работа Кенни была проведена на заре компьютерного зрения (1986), детектор границ Кенни до сих пор является одним из лучших детекторов.
Шаги детектора:
— Убрать шум и лишние детали из изображения
— Рассчитать градиент изображения
— Сделать края тонкими (edge thinning)
— Связать края в контура (edge linking)
Детектор использует фильтр на основе первой производной от гауссианы. Так как он восприимчив к шумам, лучше не применять данный метод на необработанных изображения. Сначала, исходные изображения нужно свернуть с гауссовым фильтром.
Границы на изображении могут находиться в различных направлениях, поэтому алгоритм Кенни использует четыре фильтра для выявления горизонтальных, вертикальных и диагональных границ. Воспользовавшись оператором обнаружения границ (например, оператором Собеля) получается значение для первой производной в горизонтальном направлении (Gу) и вертикальном направлении (Gx).
Из этого градиента можно получить угол направления границы:
Q=arctan(Gx/Gy)
Угол направления границы округляется до одной из четырех углов, представляющих вертикаль, горизонталь и две диагонали (например, 0, 45, 90 и 135 градусов).
Затем идет проверка того, достигает ли величина градиента локального максимума в соответствующем направлении.
Например, для сетки 3x3:
* если угол направления градиента равен нулю, точка будет считаться границей, если её интенсивность больше чем у точки выше и ниже рассматриваемой точки,
* если угол направления градиента равен 90 градусам, точка будет считаться границей, если её интенсивность больше чем у точки слева и справа рассматриваемой точки,
* если угол направления градиента равен 135 градусам, точка будет считаться границей, если её интенсивность больше чем у точек находящихся в верхнем левом и нижнем правом углу от рассматриваемой точки
* если угол направления градиента равен 45 градусам, точка будет считаться границей, если её интенсивность больше чем у точек находящихся в верхнем правом и нижнем левом углу от рассматриваемой точки.
Таким образом, получается двоичное изображение, содержащее границы (т.н. «тонкие края»).
В OpenCV, детектор границ Кенни реализуется функцией cvCanny(), которая обрабатывает только одноканальные изображения.
image — одноканальное изображение для обработки (градации серого)
edges — одноканальное изображение для хранения границ, найденных функцией
threshold1 — порог минимума
threshold2 — порог максимума
aperture_size — размер для оператора Собеля
Обратите внимание, как меняется картина, если увеличить размер оператора Собеля:
вот результат работы функции
cvCanny(gray, dst, 10, 100, 5);
И в качестве бонуса :)
Вот какой прикольный эффект можно получить, если найденные контуры вычесть из изображения.
Выглядит, как комикс :)
Для вычитания используем функцию cvSub():
cvSub — поэлементрная разница между двумя массивами
cvSubS — разница между элементами массива и скаляром
cvSubRS — разница между скаляром и элементами массива
— разница между скаляром и элементами массива
src — первый исходный массив
value — скаляр из которого производится вычитание
dst — целевой массив
mask — маска (8-битный однаканальный массив, указывающий какие элементы целефого массива могут быть изменены)
функция вычитает каждый элемент массива из скаляра:
dst(I)=value-src(I) if mask(I)!=0
массивы должны быть одного типа (кроме маски) и одинакового размера (или ROI).
Получающиеся картинки мне очень понравились и я на скорую руку набросал сервис Генератора комиксов :)
примеры его работы можно посмотреть здесь:
например, вот пример работы Генератора:
чтобы получить цветное изображение, я так понимаю нужно разбить исходное на три ч/б, выполнить поиск границ, затем вычитание, а затем опять слить их в одно да?
угу — cvPyrMeanShiftFiltering(), но обратите внимание, что в версии 2.1 в реализации этой функции есть ошибка. Впрочем, у меня она нормально работала в Release-версиях программы.
Можете погуглить и найти, как пофиксить эту ошибку, а затем пересобрать библиотеку, или же использовать версию 2.2, где эта ошибка исправлена.
поставил 2.2, теперь даже не компилится, cvCanny ваще нет, Canny принимает не IplImage а Mat, как перейти на 2.2, теперь вместо IplImage Mat писать чтоли???
применил вместо cvPyrMeanShiftFiltering cvPyrSegmentation, результат неплохой, примерно кадр в секунду
только всёравно линии цветные а не чёрные как у вас, может вы ещё чего добавили?
Спасибо за статью. Если определять контуры по исходному изображению, то видно много шумовых контуров. Сначала наеобходимо убрать шум из мелких деталей, те немного размыть изображение и определить контуры, потом еще немного размыть. Предлагаю готовый код. Что вам мешает найти контуры на изображениии комиксов?
Комментарии (23)
RSS свернуть / развернутьRomiks
noonv
Romiks
и у меня контуры цветные а не чёрные получились
Romiks
noonv
Romiks
Romiks
Можете погуглить и найти, как пофиксить эту ошибку, а затем пересобрать библиотеку, или же использовать версию 2.2, где эта ошибка исправлена.
noonv
Romiks
Romiks
noonv
Romiks
сразу же вылетает «Access violation», а по старому либо ваще не работает либо чёрный экран
Romiks
Romiks
noonv
Romiks
только всёравно линии цветные а не чёрные как у вас, может вы ещё чего добавили?
Romiks
DikiiSlon
JohnJ
Необработанное исключение в «0x766eb727» в «cv1.exe»: Исключение Microsoft C++: cv::Exception по адресу 0x0015e71c…
А с cvLoadImage без проблем. Как сделать сделать правильно манипуляции с захваченным видео на лету?
r2d2
tester
tester
tester
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.