Computer vision 质心算法
我正在为2D光栅实现一个简单的质心/质心算法。这在CPU上相当简单,但事实证明很难移植到GPU。 我的CPU版本类似于: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
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_纹理