[5] | 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 |
---|