0

我正在尝试使用霍夫变换检测二进制图像中的圆圈。

当我使用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 库的源代码,但我很难提取对我有帮助的特定函数。

谁能提供更好的源代码示例,或帮助我理解为什么效率如此低下?代码 main.cpp 和 kernel.cl 压缩在 rar 文件http://www.files.com/set/527152684017e 使用 opencv lib 读取和显示图像 >

4

2 回答 2

1

重复调用sin()andcos()计算成本很高。由于您只使用相同的 180 个值调用这些函数,因此theta您可以通过预先计算这些值并将它们存储在数组中来加快处理速度。

更稳健的方法是使用中点圆算法通过简单的整数运算来找到这些圆的周长。

于 2013-10-29T20:13:28.093 回答
0

您正在做的是仅在 1 个工作项中运行一个巨大的 CPU 代码块,结果正如预期的那样,是一个缓慢的内核。

详细答案:您使用工作项 ID 的唯一地方就是像素值,如果满足该条件,那么您将运行一大块代码。有些工作项会触发这个,有些则不会。触发它的那些将间接使所有工作组运行该代码,这会减慢您的速度。

此外,未进入该条件的工作项将处于空闲状态。根据图像的不同,它们中的 99% 可能是空闲的。

我会重写你的算法,使每个像素使用 1 个工作组。如果满足条件,工作组将运行算法,如果不满足,则整个工作组将跳过。并且在工作组进入条件的情况下,您将有许多工作项可以玩。这将允许重新设计代码,以便内部 for 循环并行运行。

于 2013-10-30T13:12:22.160 回答