Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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
openGL中两种纹理的比较_Opengl_Opengl Es - Fatal编程技术网

openGL中两种纹理的比较

openGL中两种纹理的比较,opengl,opengl-es,Opengl,Opengl Es,我是OpenGL新手,我期待着比较两种纹理,了解它们之间有多相似。我知道如何使用两个位图图像来实现这一点,但我确实需要使用一种方法来比较两种纹理 问题是:当我们比较两幅图像时,有没有办法比较两种纹理?喜欢逐像素比较两幅图像吗 您可以将两个纹理绑定到着色器,并通过绘制四边形或类似的方式访问每个像素 // Equal pixels are marked green. Different pixels are shown in red color. void mainImage( out vec4 f

我是OpenGL新手,我期待着比较两种纹理,了解它们之间有多相似。我知道如何使用两个位图图像来实现这一点,但我确实需要使用一种方法来比较两种纹理


问题是:当我们比较两幅图像时,有没有办法比较两种纹理?喜欢逐像素比较两幅图像吗

您可以将两个纹理绑定到着色器,并通过绘制四边形或类似的方式访问每个像素

// Equal pixels are marked green. Different pixels are shown in red color.
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy;

    vec4 a = texture2D(iChannel0,uv);
    vec4 b = texture2D(iChannel1,uv);

    if(a != b)
        fragColor = vec4(1,0,0,1);
    else
        fragColor = vec4(0,1,0,1);
}
可以在上测试着色器


或者您也可以将两个纹理绑定到计算着色器,并通过迭代访问每个像素。

您可以将两个纹理绑定到着色器,并通过绘制四边形或类似的方式访问每个像素

// Equal pixels are marked green. Different pixels are shown in red color.
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy;

    vec4 a = texture2D(iChannel0,uv);
    vec4 b = texture2D(iChannel1,uv);

    if(a != b)
        fragColor = vec4(1,0,0,1);
    else
        fragColor = vec4(0,1,0,1);
}
可以在上测试着色器


或者,您也可以将这两种纹理绑定到计算着色器,并通过迭代访问每个像素。

实际上,您所要求的是不可能的,或者至少不像在GPU上完成的那样简单。问题是GPU的设计目的是在最短的时间内完成尽可能多的小任务。不包括遍历数据数组(如像素),因此获取整数或浮点值可能有点困难

您可以尝试一个非常有趣的程序,但我不能说结果是否适合您:

您可以首先创建两个输入纹理之间存在差异的新纹理,然后继续对结果进行下采样,直到1x1像素纹理,并获取该像素的值,以查看其差异有多大

为了实现这一点,最好使用固定大小的目标缓冲区,例如256x256,即POT(二的幂)。如果您没有使用固定的大小,那么根据图像大小,结果可能会有很大的不同

因此,在第一个过程中,您可以将两个纹理重绘为第三个纹理(使用FBO-frame buffer对象)。您将使用的着色器很简单:

vec4 a = texture2D(iChannel0,uv);
vec4 b = texture2D(iChannel1,uv);
fragColor = abs(a-b);
现在你有了一个纹理,它代表了每像素、每种颜色分量的两幅图像之间的差异。如果两幅图像相同,结果将是一幅完全黑色的图片

现在,您需要创建一个新的FBO,该FBO在本例中的每个维度(128x128)上按一半比例缩放。要绘制到此缓冲区,您需要使用
GL_NEAREST
作为纹理参数,这样就不会对texel提取进行插值。然后对每个新像素求和源图像的4个最近像素:

vec4 originalTextCoord = varyingTextCoord;
vec4 textCoordRight = vec2(varyingTextCoord.x+1.0/256, varyingTextCoord.y);
vec4 textCoordBottom = vec2(varyingTextCoord.x, varyingTextCoord.y+1.0/256);
vec4 textCoordBottomRight = vec2(varyingTextCoord.x+1.0/256, varyingTextCoord.y+1.0/256);

fragColor = texture2D(iChannel0, originalTextCoord) + 
texture2D(iChannel0, textCoordRight) + 
texture2D(iChannel0, textCoordBottom) + 
texture2D(iChannel0, textCoordBottomRight);
256值来自源纹理,因此应该是统一的,以便可以重用相同的着色器

画好后,你需要降到64,32,16。。。然后将像素读回CPU并查看结果

现在不幸的是,这个过程可能会产生非常不想要的结果。由于颜色只是简单地相加在一起,这将对所有不够相似的图像产生溢出(导致白色像素,或者更确切地说,对于不透明的图像,
(1,1,1,0)
)。这可以通过在第一个着色器过程中使用比例来克服,将输出除以足够大的值。但这可能还不够,可能需要在第二个着色器中进行平均(将所有
texture2D
调用乘以
.25

最终结果可能还是有点奇怪。CPU上有4个颜色分量,代表图像差分的总和或平均值。我猜你可以把它们总结一下,然后选择你认为图像很相似的东西。但是如果你想对你得到的结果有更多的感觉,你可能想把整个像素当作一个32位的浮点值(这有点棘手,但是你可以在SO中找到答案)。通过这种方式,您可以在没有溢出的情况下计算值,并从算法中获得非常精确的结果。这意味着您将编写浮点值,就像它是一种颜色,从第一个着色器输出开始,并在每次其他绘制调用(获取texel,将其转换为float,求和,将其转换回vec4并指定为输出)中继续一样,
GL\u NEAREST
在这里是必不可少的

如果没有,您可以优化程序,使用
GL_LINEAR
而不是
GL_NEAREST
,并简单地继续重新绘制差分纹理,直到达到单个像素大小(不需要4个坐标)。这将产生一个不错的像素,它表示差分纹理中所有像素的平均值。这是两幅图像中像素之间的平均差值。而且这个过程应该很快


然后,如果你想做一个稍微聪明一点的算法,你可以在创建差异纹理上做一些奇迹。简单地减去颜色可能不是最好的方法。模糊其中一幅图像,然后将其与另一幅图像进行比较,会更有意义。对于那些非常相似的图像,这将失去精度,但对于其他所有图像,它将为您提供更好的结果。例如,如果像素与另一个图像(模糊图像)的权重相差30%,则可以说您感兴趣,因此您将丢弃并缩放每个组件的30%,例如
result.r=clamp(abs(a.r-b.r)-30.0/100.0,0,1.0/((100.0-30.0)/100.0)

事实上,您似乎要求的是不可能的,或者至少不像在GPU上完成的那样容易。问题是GPU的设计目的是在最短的时间内完成尽可能多的小任务。不包括遍历数据数组(如像素),因此获取整数或浮点值可能有点困难

您可以尝试一个非常有趣的程序,但我不能说结果是否适合您:

您可以首先创建两个输入纹理之间存在差异的新纹理,然后继续对结果进行下采样,直到1x1像素纹理,并获取该像素的值,以查看其差异有多大

达成