不要采用图像处理方法,我们尝试一种更代数的方法。
您有白色像素-二维平面上的点,并且希望找到三个最好地将这些点与平面其余部分分离的半平面(直线)。
因此,让我们开始吧。
img=imread('http://i.stack.imgur.com/DL2Cq.png'); %// read the image
bw = img(:,:,1) > 128; %// convert to binary mask
[y x] = find(bw); %// get the x-y coordinates of white pixels
n=numel(x); %// how many do we have
mm = mean([x y],1);
mA = bsxfun(@minus, [x y], mm);
现在,一条直线可以用两个参数来描述,所有满足 L(1)*x + L(2)*y = 1
的点 (x, y)
都在该直线上。为了找到一条直线,使得所有点都位于它的一侧,这个不等式必须对集合中的所有点 (x,y)
都成立: L(1)*x + L(2)*y <= 1
。我们可以强制这些不等式,并使用quadprog
寻找最紧密的满足此约束条件的半平面 L
:
L1 = quadprog(eye(2), -ones(2,1), mA, ones(n,1));
L2 = quadprog(eye(2), ones(2,1), mA, ones(n,1));
L3 = quadprog(eye(2), [1; -1], mA, ones(n,1));
f
,我们能够得到不同的半平面来分离白色像素。mm
):x12=inv([L1';L2'])*ones(2,1)+mm';
x23=inv([L3';L2'])*ones(2,1)+mm';
x13=inv([L3';L1'])*ones(2,1)+mm';
imshow(bw,'border','tight');
hold all;
%// plot the lines
ezplot(gca, @(x,y) L1(1)*(x-mm(1))+L1(2)*(y-mm(2))-1, [1 340 1 352]);
ezplot(gca, @(x,y) L2(1)*(x-mm(1))+L2(2)*(y-mm(2))-1, [1 340 1 352]);
ezplot(gca, @(x,y) L3(1)*(x-mm(1))+L3(2)*(y-mm(2))-1, [1 340 1 352]);
%// plot the intersection points
scatter([x12(1) x23(1) x13(1)],[x12(2) x23(2) x13(2)],50,'+r');
quadprog
中玩弄一下 f
项(第二个参数)会得到不同的解决方案,对于你发送的图像,L3 = quadprog(eye(2), [-1; 1], mA, ones(n,1));
可以得到所需的解决方案。 - Shai