Как вычесть одно растровое изображение из другого в C#/.NET?

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

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

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

5 ответов


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

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


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

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


Это можно сделать, PInvoking передача битового блока функции API. Вот пример кода:

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

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

GetPixel и SetPixel (в классе Bitmap) невероятно медленные. С Помощью Lockbits Прямой будет намного быстрее, но вам все равно придется писать свой собственный код.

Update: это лучшая ссылка:

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

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


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

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


Я где-то читал, что язык, используемый в Компания Adobe Пиксель Бендер вдохновлен чем-то, что Microsoft когда-то. Не помню, где я ее читал. Я думаю, что, возможно, что Microsoft "что-то" обернуто во что-то, что может использовать проект .Net. Перебор для вычитания двух изображений, но, в любом случае.