简体   繁体   English

计算 GPU 上的图像相似度 [OpenGL/OcclusionQuery]

[英]Count image similarity on GPU [OpenGL/OcclusionQuery]

OpenGL. OpenGL。 Let's say I've drawn one image and then the second one using XOR.假设我已经绘制了一张图像,然后使用 XOR 绘制了第二张图像。 Now I've got black buffer with non-black pixels somewhere, I've read that I can use shaders to count black [ rgb(0,0,0) ] pixels ON GPU?现在我在某处有一个带有非黑色像素的黑色缓冲区,我读到我可以使用着色器来计算 GPU 上的黑色 [ rgb(0,0,0) ] 像素?

I've also read that it has to do something with OcclusionQuery.我还读到它必须对 OcclusionQuery 做一些事情。 http://oss.sgi.com/projects/ogl-sample/registry/ARB/occlusion_query.txt http://oss.sgi.com/projects/ogl-sample/registry/ARB/occlusion_query.txt

Is it possible and how?有可能吗? [any programming language] [任何编程语言]

If you've got other idea on how to find similarity via OpenGL/GPU - that would be great too.如果您对如何通过 OpenGL/GPU 找到相似性有其他想法 - 那也很棒。

I'm not sure how you do the XOR bit (at least it should be slow; I don't think any of current GPUs accelerate that), but here's my idea:我不确定你是如何做 XOR 位的(至少它应该很慢;我认为当前的任何 GPU 都没有加速),但这是我的想法:

  1. have two input images有两个输入图像
  2. turn on occlusion query.打开遮挡查询。
  3. draw the two images to the screen (ie full screen quad with two textures set up), with a fragment shader that computes abs(texel1-texel2), and kills the pixel ( discard in GLSL) if the pixels are the same (difference is zero or below some threshold).两个图像绘制到屏幕(即全屏四与设置了两个纹理),具有片段着色器,其计算ABS(texel1-texel2),并杀死像素(丢弃在GLSL)如果像素是相同的(差零或低于某个阈值)。 Easiest is probably just using a GLSL fragment shader, and there you just read two textures, compute abs() of the difference and discard the pixel.最简单的可能只是使用 GLSL 片段着色器,然后您只需读取两个纹理,计算差异的 abs() 并丢弃像素。 Very basic GLSL knowledge is enough here.非常基本的 GLSL 知识就足够了。
  4. get number of pixels that passed the query.获取通过查询的像素数。 For pixels that are the same, the query won't pass (pixels will be discarded by the shader), and for pixels that are different, the query will pass.对于相同的像素,查询不会通过(像素将被着色器丢弃),对于不同的像素,查询将通过。

At first I though of a more complex approach that involves depth buffer, but then realized that just killing pixels should be enough.起初我想到了一种更复杂的方法,涉及深度缓冲,但后来意识到仅仅杀死像素就足够了。 Here's my original though (but the above one is simpler and more efficient):这是我的原版(但上面的更简单,更有效):

  1. have two input images有两个输入图像
  2. clear screen and depth buffer清除屏幕和深度缓冲区
  3. draw the two images to the screen (ie full screen quad with two textures set up), with a fragment shader that computes abs(texel1-texel2), and kills the pixel ( discard in GLSL) if the pixels are different.将两个图像绘制到屏幕上(即设置了两个纹理的全屏四边形),使用计算 abs(texel1-texel2) 的片段着色器,并在像素不同时杀死像素(在 GLSL 中丢弃)。 Draw the quad so that it's depth buffer value is something close to near plane.绘制四边形,使其深度缓冲值接近近平面。
  4. after this step, depth buffer will contain small depth values for pixels that are the same, and large (far plane) depth values for pixels that are different.在此步骤之后,深度缓冲区将包含相同像素的小深度值,以及不同像素的大(远平面)深度值。
  5. turn on occlusion query, and draw another full screen quad with depth closer than far plane, but larger than the previous quad.打开遮挡查询,并绘制另一个全屏四边形,其深度比远平面更近,但比前一个四边形大。
  6. get number of pixels that passed the query.获取通过查询的像素数。 For pixels that are the same, the query won't pass (depth buffer is already closer), and for pixels that are different, the query will pass.对于相同的像素,查询不会通过(深度缓冲区已经接近),对于不同的像素,查询会通过。 You'd use SAMPLES_PASSED_ARB to get this.你会使用 SAMPLES_PASSED_ARB 来获得这个。 There's an occlusion query example at CodeSampler.com to get your started. CodeSampler.com上有一个遮挡查询示例,可以帮助您入门。

Of course all this requires GPU with occlusion query support.当然,这一切都需要具有遮挡查询支持的 GPU。 Most GPUs since 2002 or so do support that, with exception of some low-end ones (in particular, Intel 915 (aka GMA 900) and Intel 945 (aka GMA 950)).自 2002 年左右以来,大多数 GPU 都支持这一点,但一些低端 GPU(特别是 Intel 915(又名 GMA 900)和 Intel 945(又名 GMA 950))除外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM