2

Я пытаюсь использовать GLSL для реализации обнаружения Harris Corner. Но это не работает должным образом (я угадываю). Во-первых, он не обнаруживает всех углов и обнаруживает множество точек, которые не являются углами, другая большая проблема заключается в том, что порог очень специфичен для каждого изображения. Может быть, это нормально с детектором Харриса?GPU Ускоренный детектор угла Harris

Вся помощь приветствуется.

Shader Передает:

1-й: Стандартный транзит.

2nd: Я превращаю изображение в полутоновое изображение.

3rd: Sobel фильтрует изображение и передает интенсивность градиента x, y и произведение интенсивностей xy.

uniform sampler2D texture; 
    varying vec2 vUV; 

    void main() { 

     vec2 uv = vUV; 
     // Offset used to get access to neighbours 
     float w = 1.0/800.0; 
     float h = 1.0/600.0; 

     vec3 temp; 
     vec3 sum = vec3(0.0); 
     // Sobel - Edge Detection 
     // y gradient 
     vec3 texel0 = texture2D(texture, uv + vec2(-w, h)).xyz; 
     vec3 texel1 = texture2D(texture, uv + vec2(-w, 0)).xyz; 
     vec3 texel2 = texture2D(texture, uv + vec2(-w, -h)).xyz; 

     vec3 texel6 = texture2D(texture, uv + vec2(w, h)).xyz; 
     vec3 texel7 = texture2D(texture, uv + vec2(w, 0)).xyz; 
     vec3 texel8 = texture2D(texture, uv + vec2(w, -h)).xyz; 

     vec3 vertEdge = 1.0 * texel0 + (2.0*texel1) + 1.0 * texel2 - 
         (1.0 * texel6 + (2.0*texel7) + 1.0 * texel8); 
     // x gradient 
     vec3 texe0 = texture2D(texture, uv + vec2(-w,h)).xyz; 
     vec3 texe1 = texture2D(texture, uv + vec2(0, h)).xyz; 
     vec3 texe2 = texture2D(texture, uv + vec2(w, h)).xyz; 

     vec3 texe6 = texture2D(texture, uv + vec2(-w,-h)).xyz; 
     vec3 texe7 = texture2D(texture, uv + vec2(0,-h)).xyz; 
     vec3 texe8 = texture2D(texture, uv + vec2(w,-h)).xyz; 

     vec3 horizEdge = 1.0 * texe0 + (2.0*texe1) + 1.0 * texe2 - 
         (1.0 * texe6 + (2.0*texe7) + 1.0 * texe8); 

     // Gradient intensity values 
     float iy = (vertEdge.r + vertEdge.g + vertEdge.b) /3.0; 
     float ix = (horizEdge.r + horizEdge.g + horizEdge.b) /3.0; 
     // Absolute to get negative values 
     iy = abs(iy); 
     ix = abs(ix); 
     float gradProcduct = ix * iy; 


     gl_FragColor = vec4(ix,iy,gradProcduct, 0.0); 

Не самый красивый код - просто хочу работать сейчас

четвёртое и пятое: Стандартный Gaussian Blur

шестых: Расчет Harris Response. Если это угол, я рисую этот пиксель в пурпуре.

 void main() { 

     vec2 uv = vUV; 
     float w = 1.0/800.0; 
     float h = 1.0/600.0; 

     float threshold = 0.05; 

     vec4 gradientInfo = texture2D(texture, uv); 

     /************** Harris Reponse ********************** 
     R is calculated as R = det(M)- K(Trace(M)) which leads to 
     R = Ix^2*Ix^y - Ixy^2-K(ix^2+iy^2)^2 
     Ix = X-gradient intesity 
     Iy = Y-gradient intesity 
     Ixy = product of the X- and Y-gradient intensities 
     *********************************************************/ 
     float R =  pow(gradientInfo.r,2.0)*pow(gradientInfo.g,2.0) 
        - pow(gradientInfo.b,2.0) 
        - threshold * pow((pow(gradientInfo.r,2.0)+pow(gradientInfo.g,2.0)),2.0); 
     vec4 test; 
     //if(R > 0.000000000005) 
     if(R > 0.0000000000750){ 
       // Extremley small values, ugly soloution for now to be able to use R in maxSupress 
      test = vec4(1.0, 0.0, 1.0, R*1000000000.0); 
     } 
     else 
      test = vec4(vec3(gradientInfo.xyz),0.0); 


     gl_FragColor = vec4(test); 
    } 

Результаты

Результат на простой квадрат enter image description here

Результат на более сложной фигуры с тем же R и Threshold enter image description here

И в результате, когда проверка ответа mulitplied на 1000. На самом деле это не работает. enter image description here

Ниже приведен код максимального подавления. пустота основной() {

 vec2 uv = vUV; 
     float vOffset = 1.0/800.0; 
     float hOffset = 1.0/600.0; 
     vec4 neighbourPixels[9]; 

     vec3 result; 
     int check = 0; 
     vec3 previous = texture2D(texture2, uv).xyz; 
     vec4 current = texture2D(texture, uv); 
     float temp = current.a; 
     vec4 neighbourArray[25]; 

     if(current.a > 0.0){ 

      for(int i = -2; i<3;i++){ 
       for(int j = -2; j<3;j++){ 
        if(temp < texture2D(texture, vUV.xy+vec2(i,j)*vec2(vOffset,hOffset)).a){ 
          //result = vec3(1.0,0.0,1.0); 
          check = 1; 
          break; 
        }  
       } 
       if(check==1){ 
        break; 
       }  
      } 
      if(check==1){ 
       result = vec3(1.0,0.0,0.0); 
      } 
      else{ 
       result = vec3(0.0,1.0,1.0); 
      } 

     } 
     else{ 
      result = previous.xyz; 
     } 

     gl_FragColor = vec4(result, 0.0); 
    } 

ответ

0

Вы должны искать локальные максимумы в ответ Харрис, а не просто пороговой. Разбавьте ответ с помощью блока 3x3 или 5x5, затем найдите пиксели, независимо от того, совпадают ли исходный отклик и расширенная версия.

+0

Я делаю это на следующем шаге. Но это не устраняет «ложные углы». –

+0

Пожалуйста, покажите код следующего шага. –

+0

Я добавил код для максимального подавления. –