找到一个点到椭圆的距离,无论它是在椭圆的内部还是外部

时间:2012-06-14 21:23:28

标签: c++ opencv

我想找到图像中每个像素坐标到椭圆的距离。

为了找到距离,我使用下面的公式,其中p是像素的点,h是椭圆。 x,y是像素坐标,x(c),y(c)是椭圆中心,θ是椭圆角,α和β分别是椭圆的长轴和短轴。

enter image description here

确定每个点到椭圆的距离的代码如下所示。如果距离,则D < 1然后它表示该点在椭圆内,在这种情况下我将其变为灰色。如果D> 1然后它意味着该点在椭圆之外,在这种情况下我保持原样。下面是我得到的输出图像。出于某种原因,我认为我的距离计算是正确的,但我的轮换有问题。对我来说,一切看起来都正确,我无法看到问题。请帮忙。我需要的是椭圆中的所有像素都应该是灰色的,但对我来说灰色区域形成一个椭圆,但似乎我在某处旋转时出错了。

Mat distance2ellipse(Mat image, RotatedRect ellipse){
float distance = 2.0f;
float angle = ellipse.angle;
Point ellipse_center = ellipse.center;
float major_axis = ellipse.height;
    float minor_axis = ellipse.width;
Point pixel;
float a,b,c,d;

for(int x = 0; x < image.cols; x++)
{
    for(int y = 0; y < image.rows; y++) 
    {
        Scalar intensity = image.at<uchar>(Point(x, y));
        pixel.x=x;
        pixel.y=y;
        a = (cos(angle*PI/180)*(pixel.x-ellipse_center.x))/(major_axis);
        b = (sin(angle*PI/180)*(pixel.y-ellipse_center.y))/(minor_axis);
        c = (sin(angle*PI/180)*(pixel.x-ellipse_center.x))/(major_axis);
        d = (cos(angle*PI/180)*(pixel.y-ellipse_center.y))/(minor_axis);

        distance = sqrt(pow((a-b),2)+pow((c+d),2));

        if(distance<1)
        {
                image.at<uchar>(Point(x,y)) = 140;
        }
    }
}
return image;}

这是我得到的输出。灰色区域应为粉红色椭圆。 enter image description here

3 个答案:

答案 0 :(得分:3)

  

出于某种原因,我认为我的距离计算是正确的

不是。某点与椭圆之间的距离是一个超越方程。它不能通过基本技术解决(这就是你所做的)。您需要使用根查找技术。

Google是你的朋友。这是一个PDF文件,它提供了一种算法并提供了实现它的代码:http://www.geometrictools.com/Documentation/DistancePointEllipseEllipsoid.pdf

修改
根据以下评论,我的答案与OP想要的内容正交。

lexma,你的椭圆看起来不正确的原因是因为对于一个相对于x轴旋转了某个角度θ的椭圆,你有一个错误的等式。确定某个点(x,y)是否在椭圆内部或外部的问题相当简单。

  1. 将(x,y)坐标转换为(u,v),使椭圆以原点为中心,沿着u轴使用长轴,沿着v轴进行微调。

    u = cos(θ)(x-x c )+ sin(θ)(y-y c
    v = -sin(θ)(x-x c )+ cos(θ)(y-y c

  2. 计算指标

    d 2 =(u /α) 2 +(v /β) 2

  3. 比较一个。如果d 2 小于1,则该点位于椭圆内;如果正好是1,则该点位于椭圆内;如果大于1,则该点位于椭圆内。

答案 1 :(得分:0)

我不确定这是问题,但行

distance = sqrt(pow((a-b),2)+pow((c+d),2));

看起来不正确。标准距离公式使用两个增量而不是一个。 这意味着该行应如下所示:

distance = sqrt(pow((a-b),2)+pow((c-d),2));

请注意,第二部分是c-d而不是c+d

答案 2 :(得分:0)

尽管this paper中的解决方案确实太昂贵,只是为了确定一个点位于椭圆内部,内部或外部,它仍然可以帮助那些使用谷歌来到这里的人,误导了第一部分头。 (像我一样)