Подтвердить что ты не робот

Алгоритм демозаизации, содержащий понижающую дискретизацию

Введение. На чем я работаю.

Привет всем! Я работаю над алгоритмом Demosaicing, который я использую для преобразования изображений с шаблоном Bayer в изображения, представляющие красный, зеленый и синий каналы. Я хочу, чтобы алгоритм имел следующие свойства:

  • Он сохраняет как можно больше необработанной информации.

  • Он не скрывает детали изображения, даже если это означает отсутствие шумоподавления.

  • Он производит как можно меньше артефактов.
  • Если размер мозаичного изображения равен N x N, три цветных изображения должны иметь размер N/2 x N/2.
  • Алгоритм должен быть быстрым. Чтобы "быстро" перейти в контекст, позвольте мне сказать следующее: я соглашусь на то, что по крайней мере в два раза быстрее, чем алгоритм OpenCV, который использует билинейную интерполяцию.

То, что я достиг до сих пор.

До сих пор я придумал алгоритм, который использует билинейную интерполяцию и создает три изображения с половинным размером изображения мозаики. Алгоритм приблизительно в 3-4 раза быстрее, чем алгоритм OpenCV cvtColor, который выполняет преобразование CV_BayerBG2BGR (билинейная интерполяция).

См. эскиз шаблона Bayer ниже, чтобы получить представление о том, как он работает. Я выполняю интерполяцию в точках, отмеченных кружками. Цифры представляют коэффициенты, по которым множится множитель, лежащий в основе, чтобы получить интерполированное значение в точке, отмеченной черным кругом.

введите описание изображения здесь

Ниже вы можете увидеть результаты моего алгоритма. Я также добавил результаты обоих алгоритмов демозаизации, доступных в OpenCV (билинейная интерполяция и переменное число градиентов). Обратите внимание, что хотя результаты моего алгоритма выглядят очень плохо в сравнении, результаты билинейной интерполяции OpenCV выглядят почти точно так же, если я их уменьшаю. Это, конечно, ожидается, так как основной алгоритм один и тот же.

введите описание изображения здесь

... так наконец: вопрос.

Мое текущее решение дает приемлемые результаты для моего проекта, и это также приемлемо быстро. Тем не менее, я бы хотел использовать алгоритм с удвоением медленности, если это приведет к улучшению любого из 5 критериев, перечисленных выше. Тогда возникает вопрос: как улучшить мой алгоритм без существенного снижения производительности?

У меня достаточно опыта программирования для этой задачи, поэтому я специально не прошу фрагменты кода - приветствуются ответы любого рода (код, ссылки, предложения, особенно те, которые основаны на прошлом опыте).

Дополнительная информация:

  • Я работаю на С++.
  • Алгоритм сильно оптимизирован, он использует инструкции SSE и непараллелен.
  • Я работаю с большими изображениями (размером несколько МБ); кэш-осведомленность и избежание нескольких проходов через изображение очень важны.

Я не ищу общий совет по программированию (например, оптимизацию вообще и т.д.), но, с другой стороны, некоторые ответы на конкретные задачи более чем приветствуются. Заранее благодарю вас.

4b9b3361

Ответ 1

Я немного озадачен вашим алгоритмом и не буду комментировать его... но поставить некоторые вещи в перспективу...

OpenCV - это библиотека, которая содержит много общих вещей для выполнения заданий и иногда намеренно не оптимизирована по производительности, есть компромисс с точки зрения затрат и "достаточно хороший, лучше, чем лучше". Есть люди, которые продают оптимизированные по производительности библиотеки, реализующие некоторые функции OpenCV, иногда с тем же API. Я не использовал его, но у OpenCV есть cv::gpu::cvtColor(), который мог бы достичь ваших целей, исходя из того, что он реализован для демонстрации, и что у вас есть подходящий графический процессор.

Учитывая билинейную демозаизацию, менее оптимизированная, но оптимизированная реализация ЦП может работать намного быстрее, чем у OpenCV, я бы оценил выше 250 Мп/с на одном основном ядре процессора.

Теперь, чтобы уточнить путь оптимизации...

Во-первых, поскольку demosaicing - это локальная операция, понимание кэша действительно не является серьезной проблемой.

Оптимизированная по производительности реализация будет иметь разные пути кода в зависимости от размеров изображения, типа шаблона Bayer, наборов инструкций, поддерживаемых процессором (и их скоростью/задержкой), для такого простого алгоритма он станет много кода.

Существуют инструкции SIMD для выполнения перетасовки, арифметики, включая усреднение, потоковые записи памяти, которые вы найдете полезными. Обзор Intel не так уж плохо ориентироваться, и Agner Fog site также полезен для любого вида оптимизации реализации. AVX и AVX2 предоставляют несколько интересных инструкций для обработки пикселов.

Если вы больше похожи на человека 80/20 (хорошо для вас!), вы оцените работу с инструментом, например Halide, который может генерировать оптимизированный код трафарета, как бриз (по модулю кривой обучения, которая уже возвращает вас на несколько дней с 1-часовой наивной реализации или 10 минут с использованием OpenCV) и особенно обрабатывает граничные условия (границы изображения).

Вы можете получить немного больше (или взять альтернативный путь), используя встроенные функции компилятора для доступа к определенным инструкциям процессора, на данный момент ваш код теперь в 4 раза дороже (с точки зрения стоимости разработки), и, вероятно, вы получите 99% насколько ручная сборка ($$$ x4 снова).

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

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