Computer vision 质心算法

Computer vision 质心算法,computer-vision,glsl,Computer Vision,Glsl,我正在为2D光栅实现一个简单的质心/质心算法。这在CPU上相当简单,但事实证明很难移植到GPU。 我的CPU版本类似于: float sumX = 0., sumY = 0., c = 0. for y in imageH: for x in imageW: if image[x, y] > threshold: sumX += x sumY += y c += 1. Point2D cent

我正在为2D光栅实现一个简单的质心/质心算法。这在CPU上相当简单,但事实证明很难移植到GPU。 我的CPU版本类似于:

float sumX = 0., sumY = 0., c = 0.
for y in imageH:
    for x in imageW:
        if image[x, y] > threshold:
            sumX += x
            sumY += y
            c += 1.
 Point2D centroid = Point2D( sumX / c, sumY / c )
我的GPU版本(带backbuffers/pingpong的GLSL)目前不起作用,如果满足条件,基本上应该对相邻像素求和(输入纹理可以有一个由黑白形状组成的位掩码图像,因为现在一个形状就足够了,我将从那里开始)

vec2 pixSize=1./决议
vec4 originalTexture=纹理(myTex,uv);
if(frame==0&&originalTex.r>treshold)
{
gl_FragColor=vec4(gl_FragCoord,0,0.);
其他的
{

对于(int y=-1;y这是一个直接的归约问题

使用这些值创建一个三通道纹理T

if(image[x,y] > threshold) {
    T[x,y,0] = x;
    T[x,y,1] = y;
    T[x,y,2] = 1;
} else {
    T[x,y,0] = T[x,y,1] = T[x,y,2] = 0;
}
然后将纹理减少一个常数因子,直到得到一个1x1像素。这需要
O(log(max(w,h))
GPU友好的步骤,因此非常有效。下面是一些幻灯片。事实上,即使是
glGenerateMipmap()
之类的东西也可以工作,尽管它使用的确切过滤器是特定于实现的

接下来,将纹理减少到单个像素后,通过以下方式提取质心:

x = T[0,0,0]/T[0,0,2];
y = T[0,0,1]/T[0,0,2];
完成了

编辑:使用片段着色器进行简单的因子2缩减,操作如下:

layout(binding = 0) uniform sampler2D TEX;
void main() {
    vec2 uv = 2*gl_FragCoord.xy/textureSize(TEX, 0);
    gl_FragColor = texture(TEX, uv);
}

您需要使用双线性缩小过滤器和(0,0,0,0)钳制到边框环绕模式将上一个纹理绑定到TEX。将下一个纹理层设置为渲染目标。

这是一个直接的缩减问题

使用这些值创建一个三通道纹理T

if(image[x,y] > threshold) {
    T[x,y,0] = x;
    T[x,y,1] = y;
    T[x,y,2] = 1;
} else {
    T[x,y,0] = T[x,y,1] = T[x,y,2] = 0;
}
然后将纹理减少一个常数因子,直到得到一个1x1像素。这需要
O(log(max(w,h))
GPU友好的步骤,因此非常有效。下面是一些幻灯片。事实上,即使是
glGenerateMipmap()
之类的东西也可以工作,尽管它使用的确切过滤器是特定于实现的

接下来,将纹理减少到单个像素后,通过以下方式提取质心:

x = T[0,0,0]/T[0,0,2];
y = T[0,0,1]/T[0,0,2];
完成了

编辑:使用片段着色器进行简单的因子2缩减,操作如下:

layout(binding = 0) uniform sampler2D TEX;
void main() {
    vec2 uv = 2*gl_FragCoord.xy/textureSize(TEX, 0);
    gl_FragColor = texture(TEX, uv);
}
您需要使用双线性缩小过滤器和(0,0,0,0)钳制到边框环绕模式将上一个纹理绑定到TEX。将下一个纹理层设置为渲染目标

  • 为每个对象渲染具有唯一颜色的ROI 2D纹理

  • 对于每个对象(唯一颜色),在指定位置渲染像素

    使用GLSL着色器计算具有“相同”颜色的所有像素的CoM

  • glReadPixels
    在每个对象的指定位置

  • 将颜色转换回二维位置

  • 我刚才为了好玩而破坏了我的天真GLSL实现:

    //---------------------------------------------------------------------------
    //顶点
    //---------------------------------------------------------------------------
    #版本420核心
    //---------------------------------------------------------------------------
    vec4顶点中的布局(位置=0);
    vec4颜色的布局(位置=3);
    平放vec4列;//对象颜色
    统一mat4 mvp;//纹理分辨率
    void main()
    {
    col=颜色;
    gl_位置=mvp*顶点;
    }
    //---------------------------------------------------------------------------
    
    CPU sise C++/OpenGL/VCL代码:

    //---------------------------------------------------------------------------
    //碎片
    //---------------------------------------------------------------------------
    #版本420核心
    //---------------------------------------------------------------------------
    vec4列中的平面;//对象颜色
    out vec4 gl_FragColor;//片段输出颜色
    均匀采样2D txr;//要模糊的纹理
    均匀浮点xs,ys;//纹理分辨率
    //---------------------------------------------------------------------------
    void main()
    {
    浮点数x,y,dx,dy,xx,yy,nn;
    vec3 dc;
    dx=1.0/(xs-1.0);xx=0.0;
    dy=1.0/(ys-1.0);yy=0.0;nn=0.0;
    对于(x=0.0;x>8)和(255))>>8;
    }
    //渲染图像(旧API)
    glBegin(GL_QUADS);
    GL3F(1.0,1.0,1.0);
    glTexCoord2f(0.0,1.0);glVertex2i(0,0);
    glTexCoord2f(0.0,0.0);glVertex2i(0,ys);
    glTexCoord2f(1.0,0.0);glVertex2i(xs,ys);
    glTexCoord2f(1.0,1.0);glVertex2i(xs,0);
    格伦德();
    glBindTexture(GL_TEXTURE_2D,0);
    glDisable(GL_纹理_2D);
    //渲染计算CoM
    r=10;
    glLineWidth(5.0);
    GL3F(0.1,0.1,0.1);
    glBegin(GL_行);
    for(i=0;iHandleType=bmDIB;//允许直接访问像素
    bmp->PixelFormat=pf32bit;//将pixel设置为32bit,使int与pixel的大小相同
    xs=bmp->Width;//分辨率应为2的幂
    ys=bmp->高度;
    txr=new int[xs*ys];//创建线性帧缓冲区
    对于(adr=0,y=0;y扫描线[y];
    对于(x=0;x txr[]
    c、 c32=pp[x];c.db[3]=0;
    q=c.db[2];
    c、 db[2]=c.db[0];
    c、 db[0]=q;
    txr[adr]=c.c32;
    对于(i=0;i=0)
    {
    obj[objs].col=c.c32;
    obj[objs].x=0;
    obj[objs].y=0;
    objs++;
    }
    }
    }
    glGenTextures(1,&txr\u img);
    glEnable(GL_纹理_2D);//将其复制到gfx卡
    glBindTexture(GL_TEXTURE_2D,txr_img);
    glPixelStorei(GLU解包对齐,4);
    glTexParameteri(GL_纹理_2D、GL_纹理_包裹、GL_夹具);
    glTexParameteri(GL_纹理2D、GL_纹理包裹、GL_夹具);
    glTexParameteri(GL_纹理2D,GL_纹理MAG_过滤器,GL_最近);
    glTexParameteri(GL\u纹理\u 2D,GL\u纹理\u最小\u过滤器,GL\u最近);
    glTexEnvf(GL_纹理_环境,GL_纹理_环境模式,GL_调制);
    //glTexEnvf(GL_纹理,GL_纹理