Search code examples
matlabcomputational-geometryrounded-cornersmatlab-cvstcorner-detection

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?


Solution

  • 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