如何获取检测到的圆的X和Y?

时间:2019-05-24 05:25:30

标签: android opencv opencv4android

我想在和图片中提取圆,所以我用以下代码提取它们:

Mat circles = new Mat();
Imgproc.HoughCircles(adaptiveThresh, circles, Imgproc.HOUGH_GRADIENT, 1.0, (double) adaptiveThresh.rows() / 40, 100.0, 30.0, 20, 30);

然后我用下面的代码遍历它们:

for (int x = 0; x < circles.cols(); x++) {
    double[] c = circles.get(0, x);
    Point center = new Point(Math.round(c[0]), Math.round(c[1]));
    int radius = (int) Math.round(c[2]);
    Imgproc.circle(source, center, radius, new Scalar(0, 0, 255), 3);
}

但是我想从左上到右下对它们进行排序,问题是我无法访问x的{​​{1}}和y
如何根据从左上到右下的行对它们进行排序?

2 个答案:

答案 0 :(得分:0)

您的问题可能令人困惑。可能是(1)排序到图像左上角的圆的距离。 (2)排序从每个圆的左上角到图像角落左上角的距离?

我假设您想找到最接近左上角情况(1)的圆。

这是我的答复。

来自C ++示例(我想您正在使用android,不是很熟悉)。您可以使用下面的示例代码进行转换。

   for( size_t i = 0; i < circles.size(); i++ )
      {
          Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
          int radius = cvRound(circles[i][2]);
          // circle center
          circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
          // circle outline
          circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
       }

中心应该是您想要的点。

只需使用街区距离从左上到右下对它们进行排序

void sort_points (std::vector<Vec3f> &array)
{
    std::cout<<"Elements in the array: "<<array.size()<<std::endl;

    //comparisons will be done n times
    for (int i = 0; i < array.size(); i++)
    {
        //compare elemet to the next element, and swap if condition is true
        for(int j = 0; j < array.size() - 1; j++)
        {   
            if ((array[j][0]+array[j][1]) > (array[j+1][0]+ array[j+1][1])
                Swap(&array[j], &array[j+1]);
        }
    }
}



int main(argc,argv)
// ...................//do your stuff

    vector<Vec3f> circles; //detected circle

   // ... //do the detection 

    sort_points(circles);
    //circles here is fully sorted from city block distance
    std::cout<<circles<<std::endl; // print out all sorted circile

// ...................//do your stuff

}

如果是第二种情况,只需更改

if ((array[j][0]+array[j][1]-2*array[j][2]) > (array[j+1][0]+ array[j+1][1]-2*array[j+1][2])

答案 1 :(得分:0)

这是您需要做的:

  1. 首先,声明一个Circle类(用于封装circle属性以进行排序)
class Circle {
    int cX;
    int cY;
    int radius;
    double distance;
}
  1. 现在遍历HoughCircles结果,创建一个Circle实例,然后将其添加到列表中
List<Circle> circleList = new ArrayList<>();
//start point, it is used to calculate the distance
Point p1 = new Point(0, 0);
for (int x = 0; x < circles.cols(); x++) {
    double[] c = circles.get(0, x);
    Point center = new Point(Math.round(c[0]), Math.round(c[1]));
    int radius = (int) Math.round(c[2]);
    Imgproc.circle(source, center, radius, new Scalar(0, 0, 255), 3);

    // here create the Circle instance
    Circle circle = new Circle();
    cricle.cX = center.x;
    circle.cY = center.y;
    circle.radius= radius;

    double D = Math.sqrt(Math.pow(abs(p1.x - circles.x), 2) + Math.pow(abs(p1.y - circles.y), 2));
    circle.distance = D;

    // add the circle instance to the list
    circleList.add(circle);
}
  1. 现在对列表中的圆圈进行排序,使用从小到大的距离
circleList.sort(new Comparator<File>() {
    @Override
    public int compare(Circle c1, Circle c2) {
        return Double.compare(c1.distance, c2.distance);
    }
});

现在,您可以使用圈子列表来做您想做的事情。

希望有帮助!