GPU加速哈里斯角点检测

时间:2015-12-10 11:23:10

标签: image-processing computer-vision glsl feature-detection

我正在尝试使用GLSL来实现Harris角点检测。但它不能正常工作(我猜)。首先它没有检测到所有角落并且它检测到很多不是角落的点,另一个大问题是阈值对于每个图像非常具体。使用Harris探测器可能是正常的吗?

感谢所有帮助。

着色器通行证:

1st:标准直通。

第二:我将图像转换为灰度图像。

第3名: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);

不是最好看的代码 - 只是希望它现在可以使用

第4和第5名:标准高斯模糊

第6步:计算Harris响应。 如果它是一个角落,我用洋红色绘制那个像素。

        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和阈值的更复杂的数字 enter image description here

当响应检查多达1000时的结果。看起来似乎没有用。 enter image description here

以下是最大限制的代码。             void main(){

        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);
    }

1 个答案:

答案 0 :(得分:0)

您需要在Harris响应中查找局部最大值,而不仅仅是阈值。使用3x3或5x5框扩展响应,然后查找原始响应和扩张版本是否相等的像素。