Билинейная интерполяция - DirectX vs. GDI + - PullRequest
7 голосов
/ 11 марта 2011

У меня есть приложение на C #, для которого я написал код GDI +, который использует рендеринг Bitmap / TextureBrush для представления 2D-изображений, к которым могут применяться различные функции обработки изображений.Этот код является новым путем в приложении, которое имитирует существующий код DX9, и они совместно используют общую библиотеку для выполнения всех векторных и матричных операций (например, ViewToWorld / WorldToView).Мой тестовый стенд состоит из выходных изображений DX9, которые я сравниваю с выводом нового кода GDI +.

Простой тестовый пример, который визуализируется в окне просмотра, которое соответствует размерам растрового изображения (то есть без масштабирования или панорамирования) соответствует пиксель-идеальному (без двоичного различий) - но как только изображение будет увеличено (увеличено), я получу очень незначительные различия в 5-10% пикселей.Величина разницы составляет 1 (иногда 2) / 256.Я подозреваю, что это происходит из-за различий в интерполяции.

Вопрос : Для орто-проекции DX9 (и пространства единичного мира) с камерой, перпендикулярной и центрированной по текстурированному четырехугольнику, разумно лиожидать DirectX.Direct3D.TextureFilter.Linear для создания идентичного вывода для прямоугольника / многоугольника, заполненного GDI + TextureBrush, при использовании параметра System.Drawing.Drawing2D.InterpolationMode.Bilinear ?

Для этого случая (увеличения) код DX9 использует это (MinFilter, MipFilter устанавливается аналогично):
Device.SetSamplerState(0, SamplerStageStates.MagFilter, (int)TextureFilter.Linear);

, а путь GDI + использует: g.InterpolationMode = InterpolationMode.Bilinear;

Я думал, что «Билинейная интерполяция» является довольно специфическим определением фильтра, но затем я заметил, что в GDI + есть еще один параметр для «HighQualityBilinear» (который я пробовал, без разницы - что имеет смысл, учитывая описание «добавлено»предварительная фильтрация для сжатия ")

Вопрос для повторения: Разумно ли ожидать идеальный выходной пиксель матмежду DirectX и GDI + (при условии, что все переданные внешние координаты равны)?Если нет, то почему?

Уточнение: Используемые изображения - непрозрачные оттенки серого (R = G = B, A = 1) с использованием Format32bppPArgb.

НаконецЕсть ряд других API, которые я мог бы использовать (Direct2D, WPF, GDI и т. д.), и этот вопрос обычно относится к сравнению вывода «эквивалентных» билинейных интерполированных выходных изображений через любые два из них.Спасибо!

Ответы [ 3 ]

6 голосов
/ 11 марта 2011

DirectX работает в основном на GPU, а DX9 может работать с шейдерами.GDI + работает по совершенно разным алгоритмам.Я не думаю, что разумно ожидать, что эти два устройства получат точно совпадающие по пикселям выходы.

Я бы ожидал, что DX9 будет иметь лучшее качество, чем GDI +, что является шагом вперед по сравнению со старым GDI, нонемного.Давно известно, что GDI + имеет проблемы с линиями сглаживания, а также с сохранением качества при масштабировании изображения (что, по-видимому, является вашей проблемой).Чтобы получить нечто похожее по качеству, чем обработка текстур GPU последнего поколения, вам нужно перейти на графику WPF.Это дает качество, похожее на DX.

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

РЕДАКТИРОВАТЬ:Хотя это было выбрано в качестве ответа, это лишь ранняя попытка объяснить и на самом деле не обратиться к истинной причине.Читатель обращается к обсуждению, изложенному в комментариях к вопросу и ответам вместо этого.

2 голосов
/ 29 марта 2011

Почему вы предполагаете, что они используют одну и ту же формулу?

Даже если они используют одну и ту же формулу, и вы принимаете, что реализация отличается, ожидаете ли вы, что результат будет одинаковым?

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

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

то, как они представляют цвет, отличается ... Я точно знаю, что nvidia использует float (возможно, double) для представления цветов, где GDI использует int, я верю.

http://en.wikipedia.org/wiki/GPGPU

В DX9 появляется шейдер 2.0, когда реализация цвета переключается с int на 24 и 32-битные значения с плавающей запятой.

попробуйте сравнить рендеринг ati / amd с рендерингом nvidia, и вы можете ясно увидеть, что цвет сильно отличается. Я впервые заметил это в Quake 2 ... Разница между двумя картами была ошеломляющей - конечно, это связано с большим количеством вещей, наименьшей из которых является их реализация bilinier interp.

РЕДАКТИРОВАТЬ: информация о том, как спецификация была сделана случайно после моего ответа. В любом случае, я думаю, что типы данных, которые использовались для его хранения, будут разными, независимо от того, как вы их указали. Кроме того, реализация float может быть иной. Я могу ошибаться, но я почти уверен, что реализации на c # отличаются от компилятора C, который использует nvidia. (и это предполагает, что GDI + не просто конвертирует float в эквивалентный int ....)

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

0 голосов
/ 01 апреля 2011

Есть две возможности для округления разностей.Первое очевидно, когда значение RGB рассчитывается как часть значений с обеих сторон.Второе более тонкое, при расчете отношения, которое будет использоваться при определении дроби между двумя точками.

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

...