source: prextra/neighbh.m @ 5

Last change on this file since 5 was 5, checked in by bduin, 14 years ago
File size: 4.4 KB
RevLine 
[5]1function J = neighbh(a,nbtype)
2% J = neighbh(sz,nbtype)
3% J = neighbh(a,nbtype)
4%
5% Compute the indices of the pixels that are in the neighborhood of a
6% pixel. This is done for all pixels in a whole image and returned in
7% the index array J. The pixels are enumerated in this standard order
8% (for an 3x5 image):
9%     1   4   7  10  13
10%     2   5   8  11  14
11%     3   6   9  12  15
12% When there is no neighbor (i.e. the pixel is on the boundary), index 0
13% is returned.
14% Then J becomes for a '4NN' neighborhood:
15%     0  0  2  4      % pixel 1 have neighbors 2 and 4...
16%     0  1  3  5      % pixel 3 has 3 neighbors..
17%     0  2  0  6
18%     1  0  5  7
19%     2  4  6  8
20%     and so on ...
21%
22% We can define neighborhood types nbtype:
23%   '4NN'   4-nearest neighborhood
24%   '8NN'   8-nearest neighborhood
25%   '9NN'   9-nearest neighborhood
26%  '25NN'  25-nearest neighborhood
27% It is also possible to give your own definition of the neighborhood.
28% You should give the indices w.r.t. the origin, for example:
29%   nbtype = [-3 0;
30%             +3 0;
31%              0 -1];
32%
33
34if isdataset(a)
35        if ~chckcoord(a)
36                error('Does not look like an image dataset');
37        end
38        sz = getobjsize(a);
39else
40        if ~(size(a)==[1 2])
41                error('I want to have the size of the image');
42        end
43        sz = a;
44end
45% The total number of pixels in the image:
46N = prod(sz);
47% The definitions of the predefined neighborhoods:
48if ischar(nbtype)
49        switch nbtype
50        case '4NN'
51                % left    up     down    right
52                pos = [-1 0; 0 -1; 0  1; 1 0];
53        case '8NN'
54                pos = [-1 -1; -1 0; -1 1; 0 -1; 0 1; 1 -1; 1 0; 1 1];
55        case '9NN'
56                pos = [-1 -1; -1 0; -1 1; 0 -1; 0 0; 0 1; 1 -1; 1 0; 1 1];
57        case '25NN'
58                pos = [-2 -2; -2 -1; -2  0; -2  1; -2  2; -1 -2; -1 -1;...
59                         -1  0; -1  1; -1  2; 0 -2; 0 -1; 0  0; 0  1; 0  2; ...
60                          1 -2; 1 -1; 1  0; 1  1; 1  2; 2 -2; 2 -1; 2  0;...
61                          2  1; 2  2];
62        case '4star'
63                %      left   up   down right
64                pos = [-2 0; 0 -2; 0  2; 2 0];
65        case '4cross'
66                %      upleft  upright downleft downright
67                pos = [-2 -2;   2 -2;   -2  2;   2 2];
68        otherwise
69                error('This neighborhood is not defined');
70        end
71else
72        if size(nbtype,2)~=2
73                error('The neighborhood definition should be a nx2 matrix.');
74        end
75        pos = nbtype;
76end
77% convert these neighborhood positions into changes in indices:
78dx = sz(1)*pos(:,1)' + pos(:,2)';
79% in horizontal limits (lower and upper):
80ckhorz = -pos(:,1)';
81I = find(ckhorz<0);
82ckhorz(I)=ckhorz(I)+sz(2)+1;
83% and in vertical limits (lower and upper):
84ckvert = -pos(:,2)';
85I = find(ckvert<0);
86ckvert(I)=ckvert(I)+sz(1)+1;
87
88% Setup the general parameters
89D = length(dx);
90
91% Define the pixels, and compute their coordinates:
92I = (1:N)';
93hcoord = floor((I-1)/sz(1))+1;
94vcoord = mod(I-1,sz(1))+1;
95
96% here the results will be stored:
97J = zeros(N,D);
98
99% and here we go:
100for i=1:D
101        % Here the main work of constructing the J matrix is performed,
102        % it is actually just these two lines. The trick is to shift the I
103        % vector up or down and store it alongside the already created matrix
104        % J.
105
106        if dx(i)>0   % look at pixels in the + direction
107
108                J(:,i) = [I((1+dx(i)):end); zeros(dx(i),1)];
109
110        else         % look at pixels in the - direction
111
112                J(:,i) = [zeros(-dx(i),1); I(1:end+dx(i))];
113
114        end
115        % Unfortunately, most of the work is actually in the checking of the
116        % bounds:
117        % Check for the horizontal bounds:
118        % look at the pixels left:
119        if pos(i,1)<0
120                if ckhorz(i)
121                        excp = find(hcoord<=ckhorz(i));
122                        J(excp,i) = 0;
123                end
124        else  % and pixels right
125                if ckhorz(i)
126                        excp = find(hcoord>=ckhorz(i));
127                        J(excp,i) = 0;
128                end
129        end
130        % Check for the vertical bounds:
131        % look at the pixels *above*:
132        if pos(i,2)<0
133                if ckvert(i)
134                        excp = find(vcoord<=ckvert(i));
135                        J(excp,i) = 0;
136                end
137        else   % otherwise the pixels below:
138                if ckvert(i)
139                        excp = find(vcoord>=ckvert(i));
140                        J(excp,i) = 0;
141                end
142        end
143end
144
145return
146
147
148function out = chckcoord(a)
149% out = chckcoord(a)
150%
151% check if dataset a contains pixels regularly sampled from an image
152% It looks a the objsize and maybe the X- and Y-coordinates.
153
154out = 1;
155
156sz = getobjsize(a);
157
158% first check if we even have some 2D objsize
159if length(sz)==1
160        out = 0;
161        return
162end
163
164featlab = getfeatlab(a);
165% now check the possible X coordinate:
166xcoord = strmatch('X',featlab);
167if ~isempty(xcoord)
168        cx = +a(:,xcoord);
169        dx = diff(cx(1:sz(1)));
170        if std(dx)~=0
171                out = 0;
172                return
173        end
174end
175% now check the possible Y coordinate:
176ycoord = strmatch('Y',featlab);
177if ~isempty(ycoord)
178        cy = +a(:,ycoord);
179        dy = diff(cy(1:sz(1):end));
180        if std(dy)~=0
181                out = 0;
182                return
183        end
184end
185
186return
Note: See TracBrowser for help on using the repository browser.