Перебор пикселей на изображениях занимает очень много времени

Перебор пикселей на изображениях занимает очень много времени

label1 и label3 содержать путь к изображениямю Суть всей программы в поиске объекта,изображенном на 2 рисунке(так называемый образец), на 1 изображении. В данной части программы мы находим совпадения цветов( я условился, что на изображениях отсутствуют тени и шумы) Собственно, в чем просьба к вам: 1)Как можно ускорить поиск.7 минут-не дело 2)Может, можно добавить условие, которое как раз позволит ускорить алгоритм.

Буду очень благодарен за ответ.

PS.Еще благодарнее буду, если кто сможет мне помочь через icq -592803800

Создание массива занимает много времениЗдравствуйте. Нужен совет. В процессе написания некой программы, возникла надобность в создании.

OpenXML, Dispose занимает, много времениВ программе происходит подключение к файлам несколько раз(около 60) using (var doc =.

Миллионы строк. добавление новых строк занимает очень много времениздравствуйте, столкнулся с такой проблемой: в базе данных access несколько миллионов строк, заношу.

windows 7 занимает очень много местаустановил вчера window 7,она весит 4,3гб но кода установилась то заняла на диске 100гб. что это?

Решение

Оптимизировать тут можно очень хорошо.

У вас в label1 и label3 хранятся пути к файлам? Если да, то зачем третье изображение считывается с файла, а потом заливается черным?

Погнали оптимизировать (предполагаю, что формат пикселя у вас 32 бита ARGB): 1. Третье изображение не считывать с файла (все равно заливать потом), а создать новое. Заодно убирается цикл заполнения черным цветом, т.к. новое изображение будет черным сразу же:

2. Избавляемся от всех GetPixel и SetPixel - эти методы жутко тормозные. Заменям всю эту красоту на небезопасный код. Вместо небезопасного кода можно маршаллить массивы, но с указателями проще (отметьте галочку "Разрешить небезопасный код" в свойствах проекта).

3. Распараллеливаем основной цикл - пусть все ядра процессора будут заняты делом (требуется .NET 4)

4. Соединяем все вместе:

Обратите внимание, что в основном цикле я не беру в расчет размер полосы (Stride) первого изображения, т.к. ширина первого изображения в 300 пикселей кратна четырем. Если его размер будет меняться, то придется это учесть.

Добавлено через 22 минуты Кстати, процесс ускорить можно еще больше, если проиндексировать все цвета во втором изображении. Тогда от вложенного цикла можно вообще избавиться.

Добавлено через 41 минуту Попробовал с индексированием. Время выполнения упало до 19мс

поподробнее можно? 4)В чем достигается такой преимущество данного алгоритма над Get и Set Pixel 5)Вопрос очень наглый, то буду чрезмерно вам благодарен за ответ на него: какой алгоритм вы рекомендуете для того,чтобы убрать ложные совпадения(суть всей программы в поиске объекта 2 изображения, изображенном на первом. В случае наличия двух разных по форме,но одинаковых по цвету, программа даст +1ложное срабатывание).Именно, кстати, для этого, я и взял третье изображение и сделал его бинарным(чтобы потом проще проанализировать) Буду признателен, если вы ответите на часть вопросов.

Еще более благодарен, если на все ответите)

Решение

Алгоритм точно такой же, как и у вас, я только изменил методы, через которые он реализуется.

Вот тот же код, но с комментариями:

Для быстродействия в GDI+ изображение хранится в памяти так, что адрес начала каждой строки изображения кратен четырем. В противном случае в конец строки добавляется до трех лишних байт, которые не хранят никакой информации, а просто нужны для выравнивания адресов в памяти. Наример, если у нас есть изображение шириной в 10 пикселей формата 24bpp (3 байта), то ширина строки в памяти будет равна 10 * 3 = 30. Это число не кратно четырем, потому в конец строки добавится еще два байта, чтобы адрес начала следующей строчки был кратен. Вот и строка эта нужна для того, чтобы узнать (и соответственно пропустить) количество "лишних" байт в конце строки, которые не используются для хранения какой-либо цветовой информации. Так как у нас размер пикселя равен 32-м битам (8 альфа, 8 красный, 8 зеленый, 8 синий), или 4 байтам, то в данном случае она не нужна, т.к. в любом случае количество байт в строке будет кратно четырем.

Для начала оговорюсь, что я не знаю чего вы пытаетесь добиться, - я просто оптимизировал ваш уже существующий код (алгоритм остался прежним). Из вашего оригинального кода я вижу, что пиксель в третьем изображении, соответствующий пикселю в первом изображении, изменяется на белый в том случае, если пиксель такого же цвета как первый, имеется где-то во втором изображении, причем не важно где. Для этих целей нет смысла каждый раз сканировать второе изображение - достаточно отсканировать его один раз и создать список уникальных цветов, в нем содержащися. И сохранить все уникальные цвета второго изображения в хэш-таблице, откуда их можно очень быстро достать. Потом просто проверяем, имеется ли уже в таблице цвет определенного пикселя из первого изображения. Если имеется - меняем пиксель третьего изображения на белый. В этом случае у нас нагрузка процессора меняется на нагрузку на память, т.к. мы должны где-то хранить таблицу цветов. В худшем случае (если каждый пиксель во втором изображении имеет уникальный цвет, что маловероятно) потребуется количество дополнительной памяти для таблицы, равное количеству памяти, занимаемому вторым изображением.

В том, что для доступа к информации о пикселях необходимо залочить изображение в памяти, что является довольно трудоемкой процедурой. А потом его разлочить, что тоже не дешево. При каждом обращении к GetPixel или SetPixel происходит замыкание памяти, получение/изменение данных пикселя, размыкание памяти. В моем варианте изображение замыкается и размыкается ровно один раз за всю процедуру его обработки. Все остальное время мы имеем прямой доступ к памяти, где оно хранится.

Простите, но пятый вопрос не понял. Если можно, то поясните подробнее.

kolorotur, Передо мной ставилась задача обнаружение объекта на изображении.(я условился, что шумы отсутствуют, цвет соответствует цвету на образце) В целом, этот банальный перебор позволяет решить эту задачу. Однако он построен на принципе:совпал цвет-значит это нужный объект. Но ведь это не всегда так будет:отдельные пикселя могут совпасть, или вообще какой то объект точно такого же цвета.

Поэтому пытаемся отсеить ненужное на 3 изображении Если убирать отдельные пикселя-здесь все понятно:смотрим, что вокруг него.Если имеется много соседей, то очевидно, что это часть объекта,если нет-убираем.

А вот если у нас будет "инородный" объект, здесь придется покапаться.Лично я пока пришел к такому алгоритму: маркируем каждый объект уникальной меткой на 3 изображении,изображение с образцом превращаем в бинарное изображение:фон делаем 0, объект 1. Далее рассматриваем свойства объектов.Я бы выбрал вот такие:находим у всех объектов на 2 и 3 изображении точки "экстремума"(вершины объекта),центр,расстояние между центром и вершинами.Далее проверяем отношение расстояний между центром и противоположными вершинами:очевидно, что отношение это будет приблизительно равно, даже если будет масштабирование. Вот я бы хотел у вас поинтересоваться:как вы смотрите на эту проблему и как вы бы ее решили

📎📎📎📎📎📎📎📎📎📎