user3315340
user3315340

Reputation: 155

MatLab: Corner Detection on Binary Image

I am trying to find a way to find the corner points on this binary image in MatLab

Binary Image

I have been trying to find a way to fit a triangle over this image and finding the vertices. I have tried finding corners but the values it returns are not always correct.
Is there any way I can sharpen the edges so that the corner function can return better results?

I appreciate any input! Thanks!

enter image description here

What strategy seems easier and more efficient? What existing MatLab functions could I use?

Upvotes: 5

Views: 1149

Answers (2)

user1196549
user1196549

Reputation:

You can find the minimum area circumscribed triangle.

First compute the convex hull of the blob.

Then try all distinct choices of three sides of the hull, extend the sides by computing the pairwise intersections and keep the triangle with the smallest positive area.

enter image description here

Upvotes: 1

Shai
Shai

Reputation: 114786

Instead of image processing approach, let's try a more algebraic approach.

You have white pixels - 2D points on a plane, and you wish to find three half-planes (straight lines) that best separate these points from the rest of the plane.

So, let's start

img=imread('https://i.sstatic.net/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

For stability we subtract the mean of all points - centering the white pixels around the origin:

mm = mean([x y],1); 
mA = bsxfun(@minus, [x y], mm);

Now, a line can be described by two parameters, all the points (x, y) that satisfy L(1)*x + L(2)*y = 1. In order to find a line that all the points are strictly to one side of it, this inequality must hold for all points (x,y) of the set: L(1)*x + L(2)*y <= 1. We can force these inequalities and search for the most tight half plane L that fulfill this constraint using quadprog:

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

Note how by changing the quadratic optimization target f, we are able to get different half planes separating the white pixels.

Once we have the three lines, we can get the intersection points (shifting them back from the origin by 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';

You can use see the results

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

enter image description here

Upvotes: 3

Related Questions