首页 文章

找到一个点到椭圆的距离,在椭圆的内部或外部

提问于
浏览
5

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

为了找到距离,我使用下面的公式,其中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

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

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

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

    Edit
    根据以下评论,我的回答与OP想要的正交 .

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

    • 将(x,y)坐标转换为(u,v),使椭圆以原点为中心,沿u轴为长轴,沿v轴为小 .

    u = cos(θ)(x-xc)sin(θ)(y-yc)
    v = -sin(θ)(x-xc)cos(θ)(y-yc)

    • 计算指标

    d2 =(u /α)2(v /β)2

    • 与一个相比 . 如果d2小于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

  • 3

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

相关问题