opengl-es - 如何在 OpenGL ES 着色器中使用 3x3 单应矩阵?

标签 opengl-es computer-vision textures shader homography

我有一个 3x3 单应矩阵,它可以与 OpenCV 的 warpPerspective 一起正常工作,但出于性能原因,我需要在 GPU 上进行变形。最好的方法是什么?我尝试在顶点着色器中进行乘法运算以获得纹理坐标,然后渲染一个四边形,但我得到了奇怪的扭曲。我不确定是不是插值没有按我预期的那样工作。附加输出进行比较(它涉及两个不同但足够接近的镜头)。

扭曲和其他图像与 GPU 的绝对差异:

enter image description here

OpenCV 中扭曲和其他图像的合成:

enter image description here

编辑:

以下是我的着色器:任务是图像校正(使外线变成扫描线)+ 绝对差异。

// Vertex Shader

static const char* warpVS = STRINGIFY
(
 uniform highp mat3 homography1;
 uniform highp mat3 homography2;
 uniform highp int width;
 uniform highp int height;
 attribute highp vec2 position;
 varying highp vec2 refTexCoords;
 varying highp vec2 curTexCoords;

 highp vec2 convertToTexture(highp vec3 pixelCoords) {
   pixelCoords /= pixelCoords.z;  // need to project
   pixelCoords /= vec3(float(width), float(height), 1.0);
   pixelCoords.y = 1.0 - pixelCoords.y;  // origin is in bottom left corner for textures
   return pixelCoords.xy;
 }

 void main(void)
 {
   gl_Position = vec4(position / vec2(float(width) / 2.0, float(height) / 2.0) - vec2(1.0), 0.0, 1.0);
   gl_Position.y = -gl_Position.y;
   highp vec3 initialCoords = vec3(position, 1.0);
   refTexCoords = convertToTexture(homography1 * initialCoords);
   curTexCoords = convertToTexture(homography2 * initialCoords);
 }

 );

// Fragment Shader

static const char* warpFS = STRINGIFY
(
 varying highp vec2 refTexCoords;
 varying highp vec2 curTexCoords;
 uniform mediump sampler2D refTex;
 uniform mediump sampler2D curTex;
 uniform mediump sampler2D maskTex;

 void main(void)
 {
   if (texture2D(maskTex, refTexCoords).r == 0.0) {
     discard;
   }

   if (any(bvec4(curTexCoords[0] < 0.0, curTexCoords[1] < 0.0, curTexCoords[0] > 1.0, curTexCoords[1] > 1.0))) {
     discard;
   }

   mediump vec4 referenceColor = texture2D(refTex, refTexCoords);
   mediump vec4 currentColor = texture2D(curTex, curTexCoords);

   gl_FragColor = vec4(abs(referenceColor.r - currentColor.r), 1.0, 0.0, 1.0);
 }

 );

最佳答案

我认为您只需要按像素进行投影即可。使 refTexCoords 和 curTexCoords 至少为 vec3,然后在查找纹理之前在像素着色器中执行/z。最好使用 textureProj GLSL 指令。

你想在顶点着色器中做所有线性的事情,但是像投影这样的事情需要在每个像素的片段着色器中完成。

此链接可能对某些背景有所帮助:http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/

关于opengl-es - 如何在 OpenGL ES 着色器中使用 3x3 单应矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26167030/

相关文章:

android - Android 上 GLSL 中的数组

Android:使用 OpenGL 双 channel 渲染到 SurfaceTexture

java - OpenGL ES 1.0 安卓 : Unable to load multiple textures

matlab - 寻找图像中的凹坑

android - Opengl es 2.0 3d

android - 纹理仅显示为黑色

用于查找一组中最相似图像的图像比较算法

python-2.7 - 指纹增强

javascript - 纹理未加载到 webgl 中。从 2D Canvas 读取和操作,存储在数组中

c++ - 如何使用 DirectX11 着色器将纹理应用到正交平面