@krox
аспирант, программист, исследователь

Как разделить содержимое монохромного изображения на отдельные файлы?

Собственно, есть некоторое изображение (bmp/jpg/png) которое содержит в себе некоторое количество объектов с ломанными границами. Объекты находятся на изображении как угодно (могут находиться очень близко друг к другу), но не пересекаются.
ce709da9f87840ccbdcf16c8318521c7.png

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

Какие алгоритмы можете посоветовать?
Может есть что-то в OpenCV, что позволит узнать координаты крайних точек (x1,y1,x2,y2) и уже с помощью, например, QImage->copy скопировать выбранный фрагмент и из QImage сохранить его (передать другому компоненту).

P.S> В размышлениях придумал вариант заносить данные в двумерный массив (черный цвет - 0, белый - 1) и уже из него каким-то образом выделять группы нулей и записывать их ещё куда-нибудь. Соответственно, из куда-нибудь опять превращать в файл и сохранять (работать далее с ним). Что может быть лучше этого варианта?
  • Вопрос задан
  • 3919 просмотров
Решения вопроса 1
@krox Автор вопроса
аспирант, программист, исследователь
Так как поступают ответы, напишу вариант, на котором я остановился и реализовал.
1. В библиотеке OpenCV берётся алгоритм поиска контуров.
2. Если контур удовлетворяет условиям по размерам (не шум и не слишком маленький) копируем этот контур на новое изображение
3. По имеющимся координатам крайних точек контура просто вырезаем изображение из картинки
4. Сохраняем результат в файл.
Всё оказалось довольно просто
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
@plasticmirror
э... перебор массива точек, находим черный цвет - поиском в ширину находим всю фигуру - скидываем в файл, точки помечаем белыми, повторяем.
нет черных точек - выход

п.с. пишется за 20 минут, на оптимальность по скорости не претендует, но и условия этого не предполагают...
Ответ написан
donkaban
@donkaban
Умею рисовать тени
Для самозамкнутых фигур (если сканлиния, проведенная через фигуру будет прерывистой) поиск в ширину не сработает. Правай нижняя фигура, к примеру
Ответ написан
Комментировать
vipuhoff
@vipuhoff
Волновой алгоритм подходит, самый простой алгоритм можно описать так:
выбрать черную точку, любую, в любой фигуре, любым методом,
создать bitmap\image с размерами равными исходному изображению.
по волновому алгоритму искать все черные точки начиная от той что выбрали,
все черные отрисовывать в созданный bitmap на те же координаты что были в исходном, отрисованные закрашивать нечерным цветом
так со всеми точками по волновому алгоритму пока не закончатся черные
сохранить полученный bitmap
повторить всю процедуру пока в исходной не закончатся черные точки.

по скорости алгоритм не шибко быстрый выйдет, но и не сильно медленный, сек за 5-10 на HD картинку.

волновой алгоритм можно упростить до простейшей рекурсии, на вход координаты первой точки p
void voln(p){
сделать p-белый в исходной
сделать p-черный в созданном bitmap
для каждой черной точки p2 вокруг точки p
voln(p2)
}

на выходе из рекурсии вторая картинка заполнена тем фрагментом, точка которого подавалась на вход в рекурсию
Ответ написан
Комментировать
@odissey_nemo
Программист, ГИС-системы, растры, космоснимки
Берётся любой алгоритм заливки одноцветного растрового полигона любым цветом, начиная с любой его точки заданного цвета. Они были ещё под ДОС заготовлены в любом растровой библиотеке (в том-же Борланде).

1. Ищется слева направо сверху вниз первая точка нужного цвета. Если не найдена - выход. Иначе на 2.
2. Точка запоминается на будущее. Начиная от найденной точки, заливается полигон, включающий её каким-либо рабочим цветом (алгоритмом заливки).
3. Определяются bounding box (экстенты) этого найденного полигона (top Y уже известен - как у первой точки) в растровой системе координат. Создаётся растр этого размера (или чуть расширенный для красивых границ). В него перегоняется найденный полигон.
4. Сохраняется найденный полигон в файл.
5. Из оригинального изображения устраняется найденный полигон. Скажем, методом той же заливки, но уже цветом отсутствия. Или вариацией операции XOR по цвету заливки.
6. Начиная с запомненной точки, ищется следующая точка нужного цвета.
7. Если найдена, на шаг 2.
8. Если не найдена, выход.

Не ясным пока остаётся поиск экстентов (Bounding box, BB). Самое простое - сканировать каждый раз весь исходный растр, что не комильфо. Или как-то модифицировать алгоритм заливки - с запоминанием экстентов. Что достаточно просто. И залил и экстенты получил за один раз.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы