MatLab:二值图像的角点检测
MatLab: Corner Detection on Binary Image
我正在尝试找到一种在 MatLab 中找到此二值图像角点的方法
我一直在尝试找到一种方法来在该图像上拟合三角形并找到顶点。我试过寻找角点,但它 return 的值并不总是正确的。
有什么办法可以锐化边缘,使角函数可以 return 获得更好的结果吗?
感谢任何意见!谢谢!
哪种策略看起来更简单有效?我可以使用哪些现有的 MatLab 函数?
让我们尝试一种更代数的方法,而不是图像处理方法。
您有白色像素 - 平面上的 2D 点,并且您希望找到三个半平面(直线)以最好地将这些点与平面的其余部分分开。
那么,让我们开始吧
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');
求最小面积外接三角形
首先计算 blob 的凸包。
然后尝试船体三边的所有不同选择,通过计算成对交集来扩展边,并保持正面积最小的三角形。
我正在尝试找到一种在 MatLab 中找到此二值图像角点的方法
我一直在尝试找到一种方法来在该图像上拟合三角形并找到顶点。我试过寻找角点,但它 return 的值并不总是正确的。
有什么办法可以锐化边缘,使角函数可以 return 获得更好的结果吗?
感谢任何意见!谢谢!
哪种策略看起来更简单有效?我可以使用哪些现有的 MatLab 函数?
让我们尝试一种更代数的方法,而不是图像处理方法。
您有白色像素 - 平面上的 2D 点,并且您希望找到三个半平面(直线)以最好地将这些点与平面的其余部分分开。
那么,让我们开始吧
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');
求最小面积外接三角形
首先计算 blob 的凸包。
然后尝试船体三边的所有不同选择,通过计算成对交集来扩展边,并保持正面积最小的三角形。