Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 双线性插值-DirectX与GDI+;_C#_Image Processing_3d_Directx_Gdi+ - Fatal编程技术网

C# 双线性插值-DirectX与GDI+;

C# 双线性插值-DirectX与GDI+;,c#,image-processing,3d,directx,gdi+,C#,Image Processing,3d,Directx,Gdi+,我有一个C#应用程序,我已经为它编写了GDI+代码,它使用位图/TextureBrush渲染来呈现2D图像,可以应用各种图像处理功能。此代码是应用程序中的一个新路径,模拟现有DX9代码,它们共享一个公共库来执行所有向量和矩阵(例如ViewToWorld/WorldToView)操作。我的测试台由DX9输出图像组成,我将其与新GDI+代码的输出进行比较 一个简单的测试用例,渲染到与位图尺寸匹配的视口(即没有缩放或平移)确实匹配像素完美(没有二进制差异)-但一旦图像放大(放大),我会得到5-10%像

我有一个C#应用程序,我已经为它编写了GDI+代码,它使用位图/TextureBrush渲染来呈现2D图像,可以应用各种图像处理功能。此代码是应用程序中的一个新路径,模拟现有DX9代码,它们共享一个公共库来执行所有向量和矩阵(例如ViewToWorld/WorldToView)操作。我的测试台由DX9输出图像组成,我将其与新GDI+代码的输出进行比较

一个简单的测试用例,渲染到与位图尺寸匹配的视口(即没有缩放或平移)确实匹配像素完美(没有二进制差异)-但一旦图像放大(放大),我会得到5-10%像素的微小差异。差值的大小为1(偶尔为2)/256。我怀疑这是由于插值差异造成的

问题:对于DX9正交投影(和标识世界空间),相机垂直并以纹理四边形为中心,在使用设置时,是否有理由期望生成与GDI+TextureBrush填充矩形/多边形相同的输出

对于这种(放大)情况,DX9代码使用的是(MinFilter,MipFilter设置类似):
Device.SetSamplerState(0,SamplerStageStates.MagFilter,(int)TextureFilter.Linear)

GDI+路径正在使用:
g.InterpolationMode=InterpolationMode.双线性

我原以为“双线性插值”是一个相当具体的过滤器定义,但后来我注意到GDI+中还有另一个选项用于“高质量双线性”(我已经尝试过了,没有任何区别——考虑到“为收缩添加预滤波”的描述,这是有意义的)

后续问题:在DirectX和GDI+之间期望像素完美的输出匹配是否合理(假设传入的所有外部坐标相等)?若否,原因为何

澄清:我使用的图像是不透明的灰度(R=G=B,A=1),使用Format32bppPArgb


最后,我还可以使用其他一些API(Direct2D、WPF、GDI等)——这个问题通常适用于比较任意两个API中“等效”双线性插值输出图像的输出。谢谢

DirectX主要在GPU中运行,DX9可能运行着色器。GDI+在完全不同的算法上运行。我认为,期望两者能够提供完全匹配的像素输出是不合理的

我希望DX9比GDI+有更好的质量,这是对旧GDI的一步改进,但不是很多。长期以来,人们一直认为GDI+在抗锯齿线以及在图像缩放中保持质量方面存在问题(这似乎是您的问题)。为了在质量上与最新一代GPU纹理处理类似,您需要转到WPF图形。这提供了类似于DX的质量

WPF还使用GPU(如果可用)并返回到软件渲染(如果没有GPU),因此GPU和软件渲染之间的输出相当接近


编辑:虽然这已经被选为答案,但这只是一个早期的解释,并没有真正解决真正的原因。读者可以参考对问题和答案的评论中列出的讨论

你为什么假设他们使用相同的公式

即使它们使用相同的公式,并且您接受实现是不同的,您会期望输出是相同的吗

一天结束时,代码被设计用于感知,而不是数学上精确的感知。如果你愿意的话,你可以通过CUDA得到这个

如果你得到的是像素完美匹配,我会非常惊讶,而不是惊讶于你得到了不同的结果

它们代表颜色的方式是不同的。。。我知道nvidia使用浮点数(可能是双精度)来表示颜色,而GDI使用int表示颜色

在DX9着色器2.0中,当颜色的实现从int切换到24位和32位浮点时出现

尝试比较ati/amd渲染和nvidia渲染,您可以清楚地看到颜色非常不同。 我第一次注意到这是在地震2。。。这两张卡之间的差异是惊人的——当然,这是由于很多原因造成的,其中最不重要的是它们的bilinier interp实现

编辑:在我回答后,关于规范是如何制定的信息。不管怎样,我认为用来存储它的数据类型是不同的,不管你怎么指定它。此外,float的实现可能会有所不同。我可能错了,但我很确定c#实现的float与nvidia使用的c编译器不同。(假设GDI+不只是将浮点值转换为等效的int…)


即使我在这一点上错了,我通常也会认为一个算法的两个不同实现是相同的,这是一个例外。它们被视为速度,因此,视错觉的差异将直接转化为图像质量的差异,因为这种速度将来自不同的捷径/近似方法。

有两种可能的四舍五入差异。第一个是显而易见的,当RGB值被计算为任意一侧值的一部分时。第二个更微妙,当计算确定两点之间的分数时使用的比率


事实上,如果两种不同的算法实现是完全相同的,我会非常惊讶,有那么多地方会出现+/-1的差异。如果没有这两种方法的具体实现细节,就不可能比这更精确。

我不明白。当使用插值时,如何期望像素完美值?插值的目的是改变像素值。如果你的观点是DX和GDI+的插值方式不同:不,它们没有。不同