Как вычесть одно растровое изображение из другого в C # /. NET? - PullRequest
6 голосов
/ 29 декабря 2008

У меня есть две битовые карты, созданные различными вариациями алгоритма. Я хотел бы создать третье растровое изображение, вычитая одно из другого, чтобы показать различия.

Как это можно сделать в .NET? Я просмотрел класс Graphics и все его параметры, включая класс ImageAttributes, и у меня есть догадка, что он включает в себя функциональность цветовой матрицы или таблиц переназначения.

Кто-нибудь имеет ссылку на пример кода или может указать мне правильное направление? Поиск в Google мало что показывает, если только мой google-fu не подведет меня сегодня.

Ответы [ 5 ]

7 голосов
/ 29 декабря 2008

Реальный вопрос в том, какие различия вы хотите показать? Если вам просто нужно работать со значениями цвета RGB, лучше всего, на мой взгляд, просто сканировать оба растровых изображения и сравнивать значения цвета с помощью GetPixel, а также использовать SetPixel для создания растрового изображения «разницы». Возможно, вы просто хотите вычесть значения и использовать их в качестве нового значения цвета для третьего растрового изображения. Или, возможно, вы хотите рассчитать яркость и использовать это. Еще лучше, если у вас есть три метрики для сравнения, присвойте каждый из них компонентам R G и B цвета. Я использовал этот подход для фрактальной раскраски раньше.

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

3 голосов
/ 29 декабря 2008

Проверьте этот проект. Это детектор движения, созданный Андреем Кирилловым. Он реализует несколько фильтров для получения различий между двумя изображениями и использует их для расчета движений Это действительно хорошо сделано, и его легко изменить и использовать в вашем собственном приложении.

http://www.codeproject.com/KB/audio-video/Motion_Detection.aspx

2 голосов
/ 29 декабря 2008

Это можно сделать, вызвав функцию API BitBlt . Вот пример кода:

http://www.codeproject.com/KB/GDI-plus/Bitblt_wrapper_class.aspx

В примере используется растровый код операции SRCCOPY; чтобы получить различия между двумя растровыми изображениями, вместо этого вы захотите использовать SRCPAINT или что-то еще (GOOGLE должен предоставить список кодов).

GetPixel и SetPixel (для класса Bitmap) невероятно медленны. Использование LockBits будет намного быстрее, но вам все равно придется писать собственный код.

Обновление: это лучшая ссылка:

http://www.pinvoke.net/default.aspx/gdi32.BitBlt

и включает в себя все возможные троичные растровые операции (вероятно, вы ищете SRCPAINT или SRCAND.)

1 голос
/ 29 декабря 2008

Сначала определите вычитание ;-p Как вы хотите, чтобы ответ выглядел?

Наиболее эффективный способ сделать это, вероятно, LockBits - это должно быть намного быстрее, чем множество GetPixel вызовов, но вам нужно будет самостоятельно декодировать байты. Легко, если это просто что-то вроде 32bpp ARGB, но сложно для некоторых более сложных случаев.

0 голосов
/ 29 декабря 2008

Я где-то читал, что язык, используемый в Adobe Pixel Bender , вдохновлен тем, что однажды сделала Microsoft. Не помню, где я это читал. Я думаю, что, возможно, Microsoft «что-то» обернуто во что-то, что может использовать проект .Net. Избыток за вычитание двух изображений, но все равно.

...