Всем привет.Прошу помощи.Подскажите алгоритм. Мне нужно загрузить картинку и разбить её на блоки (по цвету) должно работать примерно по принципу заливки в графических редакторах. Как это возможно реализовать?
ПС: картинка представляет из себя градацию серого цвета.(практически чёрно белая)
30.05.12 08:28: Перенесено модератором из '.NET' — TK
Здравствуйте, revaldo666, Вы писали:
R>Всем привет.Прошу помощи.Подскажите алгоритм. Мне нужно загрузить картинку и разбить её на блоки (по цвету) должно работать примерно по принципу заливки в графических редакторах. Как это возможно реализовать? R>ПС: картинка представляет из себя градацию серого цвета.(практически чёрно белая)
Здравствуйте, vit_as, Вы писали:
_>Здравствуйте, revaldo666, Вы писали:
R>>Всем привет.Прошу помощи.Подскажите алгоритм. Мне нужно загрузить картинку и разбить её на блоки (по цвету) должно работать примерно по принципу заливки в графических редакторах. Как это возможно реализовать? R>>ПС: картинка представляет из себя градацию серого цвета.(практически чёрно белая)
_>Посмотрите для начала Flood fill.
Спасибо, а можно какой-нибудь простенький пример на C#? В принципи этот алгоритм я уже читал, немного не могу с ориентироватся как все найденный элементы в отдельные битмапы засунуть.
Здравствуйте, revaldo666, Вы писали:
R>Здравствуйте, vit_as, Вы писали:
_>>Здравствуйте, revaldo666, Вы писали:
R>>>Всем привет.Прошу помощи.Подскажите алгоритм. Мне нужно загрузить картинку и разбить её на блоки (по цвету) должно работать примерно по принципу заливки в графических редакторах. Как это возможно реализовать? R>>>ПС: картинка представляет из себя градацию серого цвета.(практически чёрно белая)
_>>Посмотрите для начала Flood fill.
R>Спасибо, а можно какой-нибудь простенький пример на C#? В принципи этот алгоритм я уже читал, немного не могу с ориентироватся как все найденный элементы в отдельные битмапы засунуть.
Вы расскажите по-подробнее что за задача. Приведите пример картинки.
Здравствуйте, vit_as, Вы писали:
_>Здравствуйте, revaldo666, Вы писали:
R>>Здравствуйте, vit_as, Вы писали:
_>>>Здравствуйте, revaldo666, Вы писали:
R>>>>Всем привет.Прошу помощи.Подскажите алгоритм. Мне нужно загрузить картинку и разбить её на блоки (по цвету) должно работать примерно по принципу заливки в графических редакторах. Как это возможно реализовать? R>>>>ПС: картинка представляет из себя градацию серого цвета.(практически чёрно белая)
_>>>Посмотрите для начала Flood fill.
R>>Спасибо, а можно какой-нибудь простенький пример на C#? В принципи этот алгоритм я уже читал, немного не могу с ориентироватся как все найденный элементы в отдельные битмапы засунуть.
_>Вы расскажите по-подробнее что за задача. Приведите пример картинки.
Задача такова, есть гравировочный станок, к нему сейчас пишется программа, для удобства загруженную картинку необходимо сигментировать. Сам станок определяет гравировать данную часть картинки или нет по средству прозрачности. Прозрачность я сделал.
Вот пример картинки
а вот код прозрачности
Bitmap image1;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
System.IO.FileStream fs = new System.IO.FileStream(openFileDialog1.FileName, System.IO.FileMode.Open);
image1 = new Bitmap(fs,true);
fs.Close();
}
int x, y;
for (x = 0; x < image1.Width; x++)
{
for (y = 0; y < image1.Height; y++)
{
Color pixelColor = image1.GetPixel(x, y);
Color newColor;
Color detected;
detected = image1.GetPixel(x, y);
if (detected.B <= 7 && detected.R <= 7 && detected.G <= 7)
{
newColor = Color.FromArgb(0, pixelColor.R, pixelColor.G, pixelColor.B);
image1.SetPixel(x, y, newColor);
}
}
}
pictureBox1.Image = image1;
}
Здравствуйте, revaldo666, Вы писали: R>Задача такова, есть гравировочный станок, к нему сейчас пишется программа, для удобства загруженную картинку необходимо сигментировать.
Сегмент (он же видимо блок) — это какая-то прямоугольная часть изображения? И задача сводится к распиливанию изображения на такие прямоугольники?
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, revaldo666, Вы писали: R>>Задача такова, есть гравировочный станок, к нему сейчас пишется программа, для удобства загруженную картинку необходимо сигментировать.
H>Сегмент (он же видимо блок) — это какая-то прямоугольная часть изображения? И задача сводится к распиливанию изображения на такие прямоугольники?
Да, только прямоугольники должны быть распилены в соответствии тому как происходит заливка в Paint то есть распиливаются или отдельные пиксели или если есть группа пикселей одного цвета то отпиливатся должна сразу эта группа.
Надеюсь понятно изъяснился. Если есть ещё какие-то вопросы то спрашивайте.
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, revaldo666, Вы писали:
R>>Надеюсь понятно изъяснился. Если есть ещё какие-то вопросы то спрашивайте.
H>Все еще не ясна форма сегментов и принцип их формирования.
Форма сегментов произвольная (зависит от количества одинаковых пикселей в отдельной области)
Вот как пример нарисовал картинку (красным выделены участки которые будут разбиты на сегменты(принцип типичной заливки) ) естественно в качестве сигмента может выступать и отдельный пиксель (сигментировать надо всё что не прозрачное).
Здравствуйте, revaldo666, Вы писали:
R>Здравствуйте, hardcase, Вы писали:
H>>Здравствуйте, revaldo666, Вы писали:
R>>>Надеюсь понятно изъяснился. Если есть ещё какие-то вопросы то спрашивайте.
H>>Все еще не ясна форма сегментов и принцип их формирования. R>Форма сегментов произвольная (зависит от количества одинаковых пикселей в отдельной области) R>Вот как пример нарисовал картинку (красным выделены участки которые будут разбиты на сегменты(принцип типичной заливки) ) естественно в качестве сигмента может выступать и отдельный пиксель (сигментировать надо всё что не прозрачное).
Для данной задачи лучше использовать алгоритм обхода (Contour tracing)
Выделяете все контура на изображении и становятся известны координаты ограничивающего объект прямоугольника.
Здравствуйте, vit_as, Вы писали:
_>Здравствуйте, revaldo666, Вы писали:
R>>Здравствуйте, hardcase, Вы писали:
H>>>Здравствуйте, revaldo666, Вы писали:
R>>>>Надеюсь понятно изъяснился. Если есть ещё какие-то вопросы то спрашивайте.
H>>>Все еще не ясна форма сегментов и принцип их формирования. R>>Форма сегментов произвольная (зависит от количества одинаковых пикселей в отдельной области) R>>Вот как пример нарисовал картинку (красным выделены участки которые будут разбиты на сегменты(принцип типичной заливки) ) естественно в качестве сигмента может выступать и отдельный пиксель (сигментировать надо всё что не прозрачное).
_>Для данной задачи лучше использовать алгоритм обхода (Contour tracing) _>Выделяете все контура на изображении и становятся известны координаты ограничивающего объект прямоугольника.
Спасибо, разобрался.
Решил эту проблему чуть-чуть по своему. Сделал рекурсивную функцию которая опрашивает ближайшие пиксели на совпадение.
А вот теперь немного затупил, как мне хранить найденные пиксели, я решил использовать List но так и не определился как правильно его использовать, я думаю что нужно сделать список списков. Не подскажите как правильно его организовать?
R>Спасибо, разобрался. R>Решил эту проблему чуть-чуть по своему. Сделал рекурсивную функцию которая опрашивает ближайшие пиксели на совпадение. R>А вот теперь немного затупил, как мне хранить найденные пиксели, я решил использовать List но так и не определился как правильно его использовать, я думаю что нужно сделать список списков. Не подскажите как правильно его организовать?
В List можно записать либо int'овый индекс в одномерном массиве соответствующий координате в двумерном либо структуру
struct Point
{
public X,Y;
}
Рекурсию не советую использовать. На больших изображениях возможно переполнение стека.
Здравствуйте, vit_as, Вы писали:
_>Здравствуйте, revaldo666, Вы писали:
R>>Спасибо, разобрался. R>>Решил эту проблему чуть-чуть по своему. Сделал рекурсивную функцию которая опрашивает ближайшие пиксели на совпадение. R>>А вот теперь немного затупил, как мне хранить найденные пиксели, я решил использовать List но так и не определился как правильно его использовать, я думаю что нужно сделать список списков. Не подскажите как правильно его организовать?
_>В List можно записать либо int'овый индекс в одномерном массиве соответствующий координате в двумерном либо структуру
_>
_>struct Point
_>{
_>public X,Y;
_>}
_>
_>Рекурсию не советую использовать. На больших изображениях возможно переполнение стека.
С этим я сегодня и столкнулся, на изображении свыше 100х100 переполняется стэк. Однако как тогда обойти пиксели картинки?
Вот как сделал я
Здравствуйте, revaldo666, Вы писали:
R>С этим я сегодня и столкнулся, на изображении свыше 100х100 переполняется стэк. Однако как тогда обойти пиксели картинки?
Сделать список, в котором хранить точки, которые предстоит проверить (т.е. непросмотренные точки). В начале в этом списке хранится стартовая точка. На каждом шаге вытаскивать одну точку для работы. После обработки точки добавить всех ее соседей в список непросмотренных точек. Естественно, добавлять новые точки в этот список нужно только в том случае, если они не были просмотрены ранее, или отсутствуют в этом списке. Поэтому потребуется еще список уже просмотренных точек.
Вместо списков лучше использовать Set. В общем, обычный поиск в ширину.
Создаете бинарное изображение, т.е. изображение состоящее из 0 (фон) и 1 (объекты). На вашем рисунке фон белый, объекты черные и красные.
Пробегаете по картинке слева направо, сверху вниз. Как только встречается переход с фона на объект, начинаете обход контура, координаты точек контура пишете в лист, на бинарном помечаете -1 те точки, которые вы обошли, чтобы второй раз к ним не возвращаться, никаких рекурсий здесь не надо.
_>Создаете бинарное изображение, т.е. изображение состоящее из 0 (фон) и 1 (объекты). На вашем рисунке фон белый, объекты черные и красные. _>Пробегаете по картинке слева направо, сверху вниз. Как только встречается переход с фона на объект, начинаете обход контура, координаты точек контура пишете в лист, на бинарном помечаете -1 те точки, которые вы обошли, чтобы второй раз к ним не возвращаться, никаких рекурсий здесь не надо.
Картинка не чёрно -бело-красная, там идёт градация серого, та картинка для примера была.
Раньше немного большой портрет. Но как я понял принцип тот-же.
Здравствуйте, revaldo666, Вы писали:
R>Всем привет.Прошу помощи.Подскажите алгоритм. Мне нужно загрузить картинку и разбить её на блоки (по цвету) должно работать примерно по принципу заливки в графических редакторах. Как это возможно реализовать? R>ПС: картинка представляет из себя градацию серого цвета.(практически чёрно белая)