检查图像点是不是与圆相交

Posted

技术标签:

【中文标题】检查图像点是不是与圆相交【英文标题】:Check if image points intersects with a circle检查图像点是否与圆相交 【发布时间】:2015-08-24 10:26:48 【问题描述】:

我正在尝试检测肩膀。 在彩色图片中您可以看到 2 个圆圈,大圆圈与边缘图片相交 4 个点。 我使边缘变薄并将所有边缘点(x,y)放在一个数组中。 现在我正在尝试使用圆方程找到交点:(x1 - x) + (y1 -y) - r^2 = 0。 问题是,方程只有一次为零(有时永远不会)。我将圆的中心点和半径四舍五入,这样我就可以得到一个特定的像素......没有帮助!

彩色图片:

边缘图片:

代码:

得到圈子:

%% im - colored image.
%  x1,y1,x2,y2,x3,y3 - are the right eye left eye and chin points.
%  The function calculates a new circule and sends its center points and 
%  radius back.



function [cx,cy,newRadius] = calcFaceCircle(im,x1,y1,x2,y2,x3,y3) 


m1 = (y1 - y3)/(x1-x3);
m2 = (y2 - y3)/(x2-x3);

d = sqrt((x2-x1)^2 + (y2-y1)^2);

centerX = ((m1*m2*(y2-y1) + m2*(x2 + x3) - m1*(x1 + x3))/(2*(m2-m1)));
centerY = (-(1/m1)*(centerX - (x3 + x2)/2) + (y3 + y2)/2);

radius = (sqrt((x1 - centerX)^2 + (y1 - centerY)^2));
%% new circle radius
newRadius = round(radius * 1.65);


newCircleX = (x1+x2)/2; 
newCircleY = (y1+y2)/2;
%% new circle center points
cx = round(newCircleX + sqrt(newRadius^2-(d/2)^2)*(y1-y2)/d);
cy = round(newCircleY + sqrt(newRadius^2-(d/2)^2)*(x2-x1)/d);

%% display the image with circles and points
figure(01);
imshow(im);
hold on; 

ang=0:0.01:2*pi; 
xp=radius*cos(ang);
yp=radius*sin(ang);
plot(x1,y1,'.');
plot(x2,y2,'.');
plot(x3,y3,'.');

plot(centerX+xp,centerY+yp);

xp=newRadius*cos(ang);
yp=newRadius*sin(ang);
plot(cx+xp,cy+yp);

hold off;

end

肩膀:

%% 
%edgeFun - array of edge image points (x,y).
%  x - circle's center X.
%  y - circle's center Y.
%  r - circle's radios
%
% The function calculates the interection points between edgeFunc and the
% circle.
% The funciton returns the first intersection and last intersection.

function [xL,xR] = getCropInfo(edgeFunc,x,y,r)

j=1;
flag = 0;
xL = -1;
xR = -1;
count = 0;

if(x > 0 && y > 0 && r > 0)


    X = edgeFunc(:,2);     

    [edgeX,edgeY] = size(X);


    for i = 1:edgeX
        x1 = edgeFunc(i,2);
        y1 = edgeFunc(i,1); 

        % check if the points intersect with the circle
        if((floor((x-x1)^2 + (-y+y1)^2 - r^2) == 0))
            if(flag == 0)  % check if first intersection point found
                disp('found');
                flag = 1;
                xL = i;  % first point
            end

            j = i;  % last point
            count = count + 1;
        end

        xR = j;

    end


else

    return;

end
if(count == 4)
    disp('ok');

end

【问题讨论】:

所以基本上,你有img的边缘,和同一个坐标系上的一个圆,你想找到所有的交点? 正确!我有一种感觉,方程永远不会返回零......这不是代码问题 由于坐标系中的分辨率,可能永远不会返回零。有一些方法可以通过 matlab 绘图和手动估计相交(为什么我什至建议这样做?)或者您可以查看 polyxpoly,将边缘变成折线 - uk.mathworks.com/help/map/ref/polyxpoly.html 好的,所以 polyxpoly(x1,y1,x2,y2) as x1,y1 是圆坐标?我怎么得到那个?在链接上:[latc, lonc] = scircle1(lat0, lon0, km2deg(rad)); ,但 km2deg 以 KM 为单位接收无线电,但我的无线电以像素为单位。 你的圆也需要是一条折线,如果你看第一个例子,你基本上需要以x和y的格式给出你的圆的完整坐标。 【参考方案1】:

为了让您的生活更轻松,我尝试了代码:

x1 = [-4,-3,-2,-1,0,1,2,3]; %//My edge, which is no where as handsome as yours
y1 = [-5,3,6,5,5,6,3,-5];

ang = 1:0.1:2*pi;
xp=4*cos(ang);  %//My circle, which is no where as good looking as yours
yp=4*sin(ang);

[xi,yi] = polyxpoly(x1,y1,xp,yp);  //Evaluate the intersects by interpolation

figure 
plot(x1,y1,'r')
hold on
plot(xp,yp,'b')

mapshow(xi,yi,'DisplayType','point','Marker','o');

xi = 1.8113; -3.0529; -3.5942; 2.7387

yi = 3.5662; 2.5771; -1.7535; -2.9094

如您所见,无论数据的分辨率有多低,它总是会插值并评估交点,这正是您想要的(因为您可能想要更改图像的分辨率) . polyxpoly 使用标准坐标系,因此很容易适应图像像素坐标系。

【讨论】:

【参考方案2】:

最好记录边缘与圆相交的边缘段。对于此类段值的起点和终点,

S = (x1 - x) + (y1 -y) - r^2

会有不同的符号(零表示完全吻合)。

【讨论】:

如果图像坐标系为 512 像素 * 512 像素,则可能会错过交点(即使线实际相交)。 对 OP 的帮助不大,但是有几个非常好的 R 映射包可以直接完成这类事情。

以上是关于检查图像点是不是与圆相交的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ElasticSearch 中的形状中获取相交点

opencv-霍夫直线变换与圆变换

hdu1174(3维射线与圆是否相交)

围绕 y 轴旋转两个图像,使它们的边界相交

判断线段与圆是否相交

OpenCV曲线拟合与圆拟合