1 | function 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 | |
---|
34 | if isdataset(a) |
---|
35 | if ~chckcoord(a) |
---|
36 | error('Does not look like an image dataset'); |
---|
37 | end |
---|
38 | sz = getobjsize(a); |
---|
39 | else |
---|
40 | if ~(size(a)==[1 2]) |
---|
41 | error('I want to have the size of the image'); |
---|
42 | end |
---|
43 | sz = a; |
---|
44 | end |
---|
45 | % The total number of pixels in the image: |
---|
46 | N = prod(sz); |
---|
47 | % The definitions of the predefined neighborhoods: |
---|
48 | if 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 |
---|
71 | else |
---|
72 | if size(nbtype,2)~=2 |
---|
73 | error('The neighborhood definition should be a nx2 matrix.'); |
---|
74 | end |
---|
75 | pos = nbtype; |
---|
76 | end |
---|
77 | % convert these neighborhood positions into changes in indices: |
---|
78 | dx = sz(1)*pos(:,1)' + pos(:,2)'; |
---|
79 | % in horizontal limits (lower and upper): |
---|
80 | ckhorz = -pos(:,1)'; |
---|
81 | I = find(ckhorz<0); |
---|
82 | ckhorz(I)=ckhorz(I)+sz(2)+1; |
---|
83 | % and in vertical limits (lower and upper): |
---|
84 | ckvert = -pos(:,2)'; |
---|
85 | I = find(ckvert<0); |
---|
86 | ckvert(I)=ckvert(I)+sz(1)+1; |
---|
87 | |
---|
88 | % Setup the general parameters |
---|
89 | D = length(dx); |
---|
90 | |
---|
91 | % Define the pixels, and compute their coordinates: |
---|
92 | I = (1:N)'; |
---|
93 | hcoord = floor((I-1)/sz(1))+1; |
---|
94 | vcoord = mod(I-1,sz(1))+1; |
---|
95 | |
---|
96 | % here the results will be stored: |
---|
97 | J = zeros(N,D); |
---|
98 | |
---|
99 | % and here we go: |
---|
100 | for 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 |
---|
143 | end |
---|
144 | |
---|
145 | return |
---|
146 | |
---|
147 | |
---|
148 | function 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 | |
---|
154 | out = 1; |
---|
155 | |
---|
156 | sz = getobjsize(a); |
---|
157 | |
---|
158 | % first check if we even have some 2D objsize |
---|
159 | if length(sz)==1 |
---|
160 | out = 0; |
---|
161 | return |
---|
162 | end |
---|
163 | |
---|
164 | featlab = getfeatlab(a); |
---|
165 | % now check the possible X coordinate: |
---|
166 | xcoord = strmatch('X',featlab); |
---|
167 | if ~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 |
---|
174 | end |
---|
175 | % now check the possible Y coordinate: |
---|
176 | ycoord = strmatch('Y',featlab); |
---|
177 | if ~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 |
---|
184 | end |
---|
185 | |
---|
186 | return |
---|