Subversion Repositories seema-scanner

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
209 jakw 1
% ========================================================================================= 
2
% Author: Andre A. Boechat
3
% File: hough_ellipse.m
4
% Date: February 27, 2014, 10:12:22 AM
5
% Description: Implementation of the classical Hough Transform algorithm to detect 
6
% ellipses.
7
% 
8
% Reference: 
9
% [1] Y. Xie and Q. Ji, “A new efficient ellipse detection method,” Pattern
10
% Recognition, 2002. Proceedings. 16th …, vol. 2, pp. 957–960, 2002.
11
%
12
% [2] http://en.wikipedia.org/wiki/Hough_transform
13
% [3] http://en.wikipedia.org/wiki/Randomized_Hough_transform
14
% ========================================================================================= 
15
%
16
% Usage:
17
% [PARAMETERS] = hough_ellipse(IMG, MIN2A = 10, MIN_VOTES = 10)
18
%
19
% Inputs:
20
% IMG is the inputs image. Images composed of only edges are better.
21
% MIN2A is the minimum length of the major axis (default 10).
22
% MIN_VOTES is the minimum number of votes on a "b" value (half-length of the minor 
23
%   axis) to validate the existence of an ellipse.
24
%
25
% Outputs:
26
% PARAMETERS is the parameters of the best fitted ellipse on the image and is 
27
%   composed of [x0 y0 a b alpha] (ellipse's center, major and minor 
28
%   half-length axis and orientation, respectively).
29
% 
30
% 
31
% Possible improvement: to return a matrix with all best fitted ellipses on the 
32
% image. It adds another loop to the algorithm.
33
 
34
function [parameters] = hough_ellipse(img, min2a, min_votes)
35
 
36
    [width height] = size(img);
37
    %% Finding all nonzero pixels of the image, possible ellipse's pixels.
38
    [ys xs] = find(img);
39
    pixels = [xs ys];
40
    %% Accumulator for the minor axis' half-length. The indexes correspond to the
41
    %% possible b values. 
42
    %% TODO: the data structure can be improved (tree with the possible values?).
43
    acc = zeros(1, max(width, height)/2);
44
    %% ij1, ij2 are indexes of (x1, y1) and (x2, y2), following the reference [1].
45
    for ij1 = 1:(length(xs)-1)
46
        for ij2 = length(xs):-1:(ij1+1)
47
            x1 = pixels(ij1, 1);
48
            y1 = pixels(ij1, 2);
49
            x2 = pixels(ij2, 1);
50
            y2 = pixels(ij2, 2);
51
            d12 = norm([x1 y1] - [x2 y2]);
52
            acc = acc * 0;
53
            if  x1 - x2 && d12 > min2a
54
                %% Center
55
                x0 = (x1 + x2)/2;
56
                y0 = (y1 + y2)/2;
57
                %% Half-length of the major axis.
58
                a = d12/2;
59
                %% Orientation.
60
                alpha = atan((y2 - y1)/(x2 - x1));
61
                %% Distances between the two points and the center.
62
                d01 = norm([x1 y1] - [x0 y0]);
63
                d02 = norm([x2 y2] - [x0 y0]);
64
                for ij3 = 1:length(xs)
65
                    %% The third point must be a different point, obviously.
66
                    if (ij3 == ij1) && (ij3 == ij2)
67
                        continue;
68
                    end
69
                    x3 = pixels(ij3, 1);
70
                    y3 = pixels(ij3, 2);
71
                    d03 = norm([x3 y3] - [x0 y0]);
72
                    %% Distance f
73
                    if  d03 >= a
74
                        continue;
75
                    end
76
                    f = norm([x3 y3] - [x2 y2]);
77
                    %% Estimating the half-length of the minor axis.
78
                    cos2_tau = ((a^2 + d03^2 - f^2) / (2 * a * d03))^2;
79
                    sin2_tau = 1 - cos2_tau;
80
                    b = round(sqrt((a^2 * d03^2 * sin2_tau) /...
81
                                (a^2 - d03^2 * cos2_tau)));
82
                    %% Changing the score of the accumulator, if b is a valid value.
83
                    %% NOTE: the accumulator's length gives us the biggest expected
84
                    %% value for b, which means, in this current implementation,
85
                    %% we wouldn't detect ellipses whose half of minor axis is
86
                    %% greater than the image's size (look at the acc's declaration).
87
                    if b > 0 && b <= length(acc)
88
                        acc(b) = acc(b)+1;
89
                    end
90
                    end
91
                %% Taking the highest score.
92
                [sv si] = max(acc);
93
                if sv > min_votes
94
                    %% Ellipse detected!
95
                    %% The index si gives us the best b value.
96
                    parameters = [x0 y0 a si alpha];
97
                    return;
98
                end
99
                    end
100
                    end
101
                    end
102
    printf("No ellipses detected!\n");
103
end
104