我正在尝试使用霍夫变换检测二进制图像中的圆圈。
当我使用Opencv的内置函数进行圆形霍夫变换时,可以找到圆圈。
现在我尝试编写自己的“内核”代码来进行霍夫变换,但速度非常慢:
kernel void hough_circle(read_only image2d_t imageIn, global int* in,const int w_hough,__global int * circle)
{
sampler_t sampler=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
int gid0 = get_global_id(0);
int gid1 = get_global_id(1);
uint4 pixel;
int x0=0,y0=0,r;
int maxval=0;
pixel=read_imageui(imageIn,sampler,(int2)(gid0,gid1));
if(pixel.x==255)
{
for(int r=20;r<150;r+=2)
{
// int r=100;
for(int theta=0; theta<360;theta+=2)
{
x0=(int) round(gid0-r*cos( (float) radians( (float) theta) ));
y0=(int) round(gid1-r*sin( (float) radians( (float) theta) ));
if((x0>0) && (x0<get_global_size(0)) && (y0>0)&&(y0<get_global_size(1)))
atom_inc(&in[w_hough*y0+x0]);
}
if(maxval<in[w_hough*y0+x0])
{
maxval=in[w_hough*y0+x0];
circle[0]=gid0;
circle[1]=gid1;
circle[2]=r;
}
}
}
}
opencv的hough opencl库有源代码,但是我很难提取一个能帮助我的特定函数。
任何人都可以提供更好的源代码示例,或者帮助我理解为什么这么低效? rar文件http://www.files.com/set/527152684017e中的代码main.cpp和kernel.cl压缩 使用opencv lib读取和显示图像&gt;
答案 0 :(得分:1)
重复调用sin()
和cos()
计算成本很高。由于您只使用相同的180个theta
值调用这些函数,因此可以通过预先计算这些值并将它们存储在数组中来加快速度。
更强大的方法是使用midpoint circle algorithm通过简单的整数运算来查找这些圆的周长。
答案 1 :(得分:0)
你正在做的是只在一个工作项中运行一个巨大的CPU代码块,结果如预期的那样,是一个很慢的内核。
详细答案: 唯一的地方是你使用工作项ID只是为了像素值,如果满足条件,那么你运行一大堆代码。一些工作项将触发其中一些不会。触发它的那些将间接地使所有工作组运行该代码,这将减慢你的速度。
此外,未进入该条件的工作项将处于空闲状态。根据图像,可能有99%的图像闲置。
我会重写你的算法,每个像素使用1个工作组。 如果满足条件,工作组将运行算法,如果不满足,则整个工作组将跳过。在工作组进入条件的情况下,您将拥有许多工作项。这将允许重新设计代码,使内部for循环并行运行。