0001 function [R, pixinds] = slpixneighbors(img, filtersize, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 if nargin < 2
0054 raise_lackinput('slpixneighbors', 2);
0055 end
0056
0057 [h0, w0, k] = size(img);
0058
0059 [filtsiz, bmg0] = slfiltersize(filtersize);
0060
0061 opts.output = 'cols';
0062 opts.roi = 'full';
0063 opts.mask = [];
0064 opts.samplestep = [1, 1];
0065 opts.pad = 'replicate';
0066 opts = slparseprops(opts, varargin{:});
0067
0068 if ~ismember(opts.output, {'cols', 'rects'})
0069 error('sltoolbox:invalidarg', ...
0070 'Invalid output form: %s', opts.output);
0071 end
0072
0073 if ischar(opts.roi)
0074 switch opts.roi
0075 case 'full'
0076 roi0 = [1, h0, 1, w0];
0077 case 'confined'
0078 roi0 = [1+bmg0(1), h0-bmg0(2), 1+bmg0(3), w0-bmg0(4)];
0079 otherwise
0080 error('sltoolbox:invalidarg', ...
0081 'Invalid ROI option: %s', opts.roi);
0082 end
0083 else
0084 roi0 = opts.roi;
0085 if ~(isnumeric(roi0) && isvector(roi0) && length(roi0) == 4)
0086 error('sltoolbox:invalidarg', 'Invalid form of roi');
0087 end
0088 end
0089
0090 mask = opts.mask;
0091 if ~isempty(mask)
0092 if ~isequal(size(mask), [h0 w0])
0093 error('sltoolbox:invalidarg', ...
0094 'The size of mask is not consistent with the image size');
0095 end
0096 end
0097
0098 ss = opts.samplestep;
0099 if ~isvector(ss) || length(ss) ~= 2
0100 error('sltoolbox:invalidarg', ...
0101 'The sample step should be a length-2 vector');
0102 end
0103
0104
0105
0106 R = [];
0107 pixinds = [];
0108
0109
0110
0111 if roi0(2) < roi0(1) || roi0(4) < roi0(3)
0112 return;
0113 end
0114
0115
0116
0117 [psiz, roi, bmg] = slcalcpadsize([h0 w0], roi0, bmg0);
0118 h = psiz(1); w = psiz(2);
0119
0120 if any(bmg > 0)
0121 img = slpadimg(img, bmg, opts.pad);
0122 if ~isempty(mask)
0123 mask = slpadimg(mask, bmg, false);
0124 end
0125 end
0126
0127
0128
0129 inds_i = (roi(1):ss(1):roi(2))';
0130 ni = length(inds_i);
0131 inds_j = roi(3):ss(2):roi(4);
0132 nj = length(inds_j);
0133 if ni <= 0 || nj <= 0;
0134 return;
0135 end
0136 I = inds_i(:, ones(1, nj));
0137 J = inds_j(ones(ni, 1), :);
0138 inds = sub2ind([h w], I, J);
0139 clear I J;
0140
0141 if isempty(mask)
0142 inds = inds(:);
0143 else
0144 if islogical(mask)
0145 inds = inds(mask(inds));
0146 else
0147 inds = inds(mask(inds) > 0);
0148 end
0149 end
0150 if isempty(inds)
0151 return;
0152 end
0153
0154 pixinds = inds';
0155 clear inds;
0156 n = length(pixinds);
0157
0158
0159 [fh, fw, fcx, fcy] = sltakeval(filtsiz);
0160 fs_i = (1-fcx:fh-fcx)';
0161 fs_j = 1-fcy:fw-fcy;
0162
0163 fI = fs_i(:, ones(1, fw), ones(k,1));
0164 fJ = fs_j(ones(fh, 1), :, ones(k,1));
0165 if k == 1
0166 rel_inds = fI + h * fJ;
0167 else
0168 fs_k = reshape(0:k-1, [1,1,k]);
0169 fK = fs_k(ones(fh,1), ones(fw,1), :);
0170 rel_inds = fI + h * fJ + (h*w) * fK;
0171 end
0172
0173 d = fh * fw * k;
0174 rel_inds = rel_inds(:);
0175
0176 indsmap = pixinds(ones(d,1), :);
0177 indsmap = sladdvec(indsmap, rel_inds, 1);
0178
0179
0180
0181 R = img(indsmap);
0182 clear indsmap;
0183
0184 if strcmp(opts.output, 'rects')
0185 if k == 1
0186 R = reshape(R, [fh, fw, n]);
0187 else
0188 R = reshape(R, [fh, fw, k, n]);
0189 end
0190 end
0191
0192
0193
0194 if nargout >=2 && any(bmg > 0)
0195 [I, J] = ind2sub([h w], pixinds);
0196 I = I - bmg(1);
0197 J = J - bmg(3);
0198 pixinds = sub2ind([h0, w0], I, J);
0199 end
0200
0201
0202
0203
0204