2015-08-24 75 views
0

我正在嘗試檢測肩膀。 在彩色圖片中您可以看到2個圓圈,大圓圈與4個點的邊緣圖片相交。 我使邊緣更細,並將所有邊緣點(x,y)放入數組中。 現在我試圖找到使用圓方程的交點:(x1 - x)+(y1 - y) - r^2 = 0. 問題是,方程只有零次(有時從不)。我四捨五入的中心點和圓的半徑,所以我可以得到一個特定的像素...沒有幫助!檢查圖像點是否與圓相交

色圖: enter image description here

邊緣圖: enter image description here

代碼:

GET圈:

%% 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 
+0

所以基本上,你有img的邊緣,在同一個座標系上有一個圓,你想找到所有的相交? – GameOfThrows

+0

正確!我有一種感覺,方程將永遠不會返回零...這不是代碼問題 –

+0

由於座標系中的分辨率,可能永遠不會返回零。通過matlab繪圖和手動估計交叉點(我爲什麼會建議這麼做?)還有很多方法,或者你可以看看polyxpoly,將你的邊緣變成多段線 - http://uk.mathworks.com/help/ map/ref/polyxpoly.html – GameOfThrows

回答

0

最好記錄邊緣與圓相交的邊緣段。對於

S =(X1 - x)的該區段值的初始和結束點+(Y1 -y) - R^2

將具有不同的符號(零爲精確重合)。

+0

與圖像座標系統說512像素* 512像素時,可能會錯過交叉點(即使這些線實際相交)。 – GameOfThrows

+1

對OP沒什麼幫助,但是''R'有幾個非常好的映射包,可以直接做這種事情。 –

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'); 

X1 = 1.8113; -3.0529; -3.5942; 2.7387

yi = 3.5662; 2.5771; -1.7535; -2.9094

To add insults to my simulation

正如你所看到的,沒關係的數據資源多低,它總是插和評估的交點,這是你想要什麼樣的理想(因爲您可能想要更改圖像的分辨率)。 polyxpoly使用標準座標系,因此對於圖像像素座標系非常容易適應。