【问题标题】:Comparing two images using OpenGL使用 OpenGL 比较两个图像
【发布时间】:2013-06-17 10:43:06
【问题描述】:

我正在编写一个程序来绘制一些应该模仿输入(光栅)图像的多边形。绘制形状后,我需要将渲染图像与输入图像进行比较,然后决定是否达到目标。目前我正在使用 CIMG 库进行绘制。整个程序在 CPU 上运行。我尝试使用使用 OpenGL 进行绘图的 SFML - 渲染速度非常快,但是将图像从 GPU 复制到 CPU(与输入图像进行匹配)需要很长时间。 我想:

  • 在 GPU 上渲染多边形
  • 将输入(光栅)图像发送到 GPU
  • 使用简单的“逐个像素”比较在 GPU 上比较图像: (r1-r2)^2+(g1-g2)^2+(b1-b2)^2
  • 发送比较结果(一个数字) 到 CPU

不幸的是,我不知道它(比较两个图像)是否可以通过 OpenGL 实现。如果可能的话,我将学习 OpenGL 或任何其他可以快速完成任务的库。

【问题讨论】:

  • 您可以使用 GPGPU 风格的编程在 OpenGL 中完成。在您的情况下,可能是一个片段着色器来比较单个像素值,然后另一个着色器通过来计算最大差异。但这听起来不像是合理的解决方案。确实可以从 GPU 到 CPU 检索图像的像素完美副本。您原来的 GPU->CPU 复制代码一定是错误的。我会努力修复它,而不是在 GPU 端编写比较代码。
  • 从 GPU 复制到 CPU 效果很好,但我需要很长时间,我重复此操作数千次,因此加快此操作对我来说很重要。
  • 我明白了。目前还不太清楚“摧毁一切”是什么意思。在这种情况下,您可以尝试使用片段着色器方法。
  • 顺便说一句,输出是什么?差异的总和?
  • 对不起,你是对的——我可以写得更清楚。是的,应该从比较中输出差异总和。

标签: c++ performance opengl graphics


【解决方案1】:

这里概述了一种可能的方法。它们实际上只是帮助您入门的提示。

  1. 将图像渲染为纹理(我称之为Render)并将原始图像复制到另一个纹理中(我称之为Orig)。禁用任何纹理过滤。

  2. 创建一个将计算差异的片段着色器。在伪代码中:

    vec3 render = texture2D(Render, fragmentPosition.xy);
    vec3 orig = texture2D(Orig, fragmentPosition.xy);
    gl_FragColor.r = (render - orig).dot(render - orig);
    

    在图像大小的四边形上运行这个片段着色器,将输出发送到另一个纹理(我称之为Difference)。您可能需要启用矩形纹理。

  3. 创建另一个片段着色器来计算部分和:

    float sum = 0;
    for (row = 0; row < imageHeight; ++row) {
      sum += texture2D(Difference, vec2(fragmentPosition.x, row));
    }
    gl_FragColor.r = sum;
    

    在四边形大小的image_width x 1 上运行此片段着色器,将输出发送到另一个纹理 (PartialSum)。

  4. 要么将PartialSum 回读到 CPU(它要小得多)并在那里求和,要么创建一个单片段四边形并运行修改后的求和着色器以得到一个数字,而不是读回。

【讨论】:

    猜你喜欢
    • 2013-12-30
    • 2011-06-18
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2013-05-26
    相关资源
    最近更新 更多