Harris角点探测器将对角线边缘检测为角

时间:2017-03-15 18:27:18

标签: computer-vision glsl corner-detection

我试图在WebGL / GLSL中实现Harris角点检测器(较大的CV算法的第一部分)。据我所知,我的高斯和索贝尔算子按预期工作(即它是模糊的,索贝尔给出了我图像强度的导数)。

我遇到的问题是Harris角点探测器对角线边缘的响应太高 - 根据探测器,任何对角线边缘都是角落。当然,这是不正确的,但我不确定为什么。无论我如何调整响应公式,它似乎都有这个问题。

这是我的着色器代码:

precision mediump float;

// the texture I am trying to detect the corners in
// (fed from a live video source)
uniform sampler2D sampler2d;

// the Gaussian / Sobel kernels are precalculated and passed as textures
uniform sampler2D gaussian_x;
uniform sampler2D gaussian_y;

// stdev for the Gaussian
#define sigma (3.0)
#define sigma_ceil (3.0)

// pixel_w and pixel_h represent the size of pixels in tex coords
#define pixel_w (1.0 / 960.0)
#define pixel_h (1.0 / 540.0)

const float offset_start = -(sigma_ceil * 3.0);
const float offset_end   = ((sigma_ceil * 3.0) + .5);
const float pixel_gauss  = 1.0 / (sigma_ceil * 2.0 + 1.0);

varying vec4 fPosition;
varying vec2 fTexCoord;

void main(){
  vec2 texCoord = vec2(fTexCoord.s, fTexCoord.t);

  vec3 total_x = vec3(0, 0, 0);
  vec3 total_y = vec3(0, 0, 0);

  for (float x = offset_start; x < offset_end; x += 1.0){
    for (float y = offset_start; y < offset_end; y += 1.0){
      total_x += texture2D(sampler2d, vec2(texCoord.s + x * pixel_w, texCoord.y + y * pixel_h)).rgb
        * ((texture2D(gaussian_x, vec2((x - offset_start) * pixel_gauss, (y - offset_start) * pixel_gauss)).rgb
           - vec3(0.5)) * .1)
        * 255.0
        ;
      total_y += texture2D(sampler2d, vec2(texCoord.s + x * pixel_w, texCoord.y + y * pixel_h)).rgb
        * ((texture2D(gaussian_y, vec2((x - offset_start) * pixel_gauss, (y - offset_start) * pixel_gauss)).rgb
           - vec3(0.5)) * .1)
        * 255.0
        ;
    }
  }

  float total_xf = (total_x.r + total_x.g + total_x.b) / 3.0;
  float total_yf = (total_y.r + total_y.g + total_y.b) / 3.0;

  float a = (total_xf * total_xf); // Ix2
  float b = (total_yf * total_yf); // Iy2
  float c = (total_xf * total_yf); // Ixy
  float det = (a * b) - c;
  float trc = a + b;

  float res = det - 0.04 * (trc * trc);

  res += .5; // to see when it goes negative

  gl_FragColor = vec4(res, res, res, 1);
}

在此之后我会进行非最大限制抑制和阈值处理,但这一步的结果似乎已经错了。两个高斯采样器从这样的纹理中采样:

Gaussian / Sobel kernels

这些是预先计算的,是我从每个像素中减去.5的原因(因为灰色像素实际上代表0重量)。 .1和255因素使我可以看到图像,我尝试了许多不同的值,但我认为它们不是问题。

我也尝试使用res = det / trc近似值,但结果似乎更糟。问题依然存在。使用标准棋盘图案,如下所示:

Calibration pattern

当我将它水平显示到相机时,结果就是这样:

Result (horizontal)

我不确定水平边缘发生了什么,但是垂直边缘是黑色的(正如预期的那样),并且角落显示非常白色的像素,这会在阈值处理时产生预期的结果。但是,当我对角转动图案时:

enter image description here

所有边缘现在都是白色的。我一直在调整各种各样的值,对高斯人使用更高的stdev等,但似乎没有任何东西产生预期的结果。难道只是哈里斯探测器检测到对角线边缘是角落吗?我怀疑,看到其他一些实现。

任何想法可能是什么问题?

(另外,在你建议openCV之前......这是在WebGL中运行的,我想/应该自己实现这个算法。)

0 个答案:

没有答案