├── Data ├── Airport.mat ├── Beach.mat ├── HYDICE_urban.mat ├── San_Diego.mat └── Urban.mat ├── README.md ├── demo.m └── functions ├── ConvertFromZeroToOneThousand.m ├── EMAP_xdk.m ├── ImGray2Pseudocolor.m ├── NormalizeData.m ├── PCA_img.m ├── RF.m ├── RRX_detect.m ├── ReadData.m ├── attribute_profile.mexa64 ├── attribute_profile.mexglx ├── attribute_profile.mexw32 ├── attribute_profile.mexw64 ├── attribute_profile_readme.txt ├── bwareafilt.m ├── bwpropfilt.m ├── morph_detect.m ├── roc.m └── scale_new.m /Data/Airport.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/Data/Airport.mat -------------------------------------------------------------------------------- /Data/Beach.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/Data/Beach.mat -------------------------------------------------------------------------------- /Data/HYDICE_urban.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/Data/HYDICE_urban.mat -------------------------------------------------------------------------------- /Data/San_Diego.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/Data/San_Diego.mat -------------------------------------------------------------------------------- /Data/Urban.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/Data/Urban.mat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AED-algorithm 2 | It's an implementation and simulation of "Hyper-spectral Anomaly Detection With Attribute and Edge-Preserving Filters" paper simulation in matlab 3 | -------------------------------------------------------------------------------- /demo.m: -------------------------------------------------------------------------------- 1 | clc, clear 2 | close all 3 | %%%% Load the hyperspectral image and the ground truth 4 | % addpath('./Dataset') 5 | addpath(genpath('.\functions')); 6 | 7 | image = 2; 8 | [data, map] = ReadData(num2str(image)); 9 | % path = './Dataset/'; 10 | % inputs = 'San'; 11 | % location = [path, inputs]; 12 | % load (location); 13 | %%%% Data normalization 14 | data2 = NormalizeData(data); 15 | %%%% Reduce the dimension of the data 16 | numb_dimension = 3; 17 | f0 = PCA_img(data, numb_dimension); 18 | f0 = NormalizeData(f0); 19 | g0 = PCA_img(data, numb_dimension); 20 | g0 = NormalizeData(g0); 21 | %%%% Set attribute filter optimal parameters 22 | tic 23 | if image == 5 24 | para = 5; 25 | elseif image == 2 26 | para = 64; 27 | else 28 | para = 25; 29 | end 30 | type = 'a'; 31 | %%%% Attribute filter 32 | d0 = morph_detect(f0, para, type); 33 | 34 | %%%% Postprocessing with edge-preserving filtering 35 | if image == 1 || image == 5 36 | r0 = RRX_detect(g0, d0, data2, 5, 1, 2, 100); 37 | else 38 | r0 = RRX_detect(g0, d0, data2, 5, 0.5, 2, 100); 39 | end 40 | toc 41 | %%%% Evaluate the results 42 | r0 = mat2gray(r0); 43 | [PD0 PF0] = roc(map(:), r0(:)); 44 | area0 = -sum((PF0(1:end-1)-PF0(2:end)).*(PD0(2:end)+PD0(1:end-1))/2); 45 | result_img = ImGray2Pseudocolor(r0, 'hot', 255); 46 | figure, imshow(r0); 47 | 48 | -------------------------------------------------------------------------------- /functions/ConvertFromZeroToOneThousand.m: -------------------------------------------------------------------------------- 1 | function Output = ConvertFromZeroToOneThousand( InMatBand,... 2 | WriteFile ) 3 | %% Init 4 | if ischar(InMatBand) 5 | [~, ~, ext] = fileparts(InMatBand); 6 | if isempty(ext) 7 | InMatBand = enviread(InMatBand); 8 | else 9 | InMatBand = imread(InMatBand); 10 | end 11 | end 12 | 13 | [row, col, Bands] = size(InMatBand); 14 | Output = zeros(row,col,Bands); %% Preallocate 15 | if Bands == 1 16 | TempRE = reshape(InMatBand, row*col, 1 ); 17 | TempRE = ((TempRE-mean(TempRE))/std(TempRE)+3)*1000/6; 18 | TempRE(TempRE<0) = 0; 19 | TempRE(TempRE>1000) = 1000; 20 | Output = reshape(TempRE, row, col, 1); 21 | else 22 | for i=1:Bands 23 | TempRE = reshape(InMatBand(:,:,i), row*col, 1 ); 24 | TempRE = ((TempRE-mean(TempRE))/std(TempRE)+3)*1000/6; 25 | TempRE(TempRE<0) = 0; 26 | TempRE(TempRE>1000) = 1000; 27 | Output(:,:,i) = reshape(TempRE, row, col, 1); 28 | end 29 | end 30 | 31 | if WriteFile 32 | enviwriteMURA(InMatBand, 'Normalized'); 33 | end 34 | end -------------------------------------------------------------------------------- /functions/EMAP_xdk.m: -------------------------------------------------------------------------------- 1 | %%%%%%% 2 | % This function computes the stacked vector EMAP. 3 | % The first EAP vector is untouched, instead the original features of the other EAP 4 | % vectors are deleted to avoid multiple presence of original features. 5 | % 6 | % INPUT: 7 | % 1- InputImage = Path of the original image 8 | % 2- OutputImage = Path of the output image 9 | % 3- PCA = Do you also want the computation of PCA? (true/false) 10 | % 4- TypeOfAttribute = Type of vector e.g. 'a' (see "Attribute supported" section botton) 11 | % 5- ValueOfThreshold = Value of threshold for that type of vector 12 | % 6- TypeOfVector = Type of vector e.g. 'i'(see "Attribute supported" section botton) 13 | % 7- ValueOfThreshold = Value of threshold for that type of vector 14 | % 8- .... = .... 15 | % 9- .... = .... 16 | % 17 | % Attributes supported: 18 | % Area: 'a', 'area'; 19 | % Length of the diagonal of the bounding box: 'd', 'diagonal'; 20 | % Moment of inertia: 'i', 'inertia'; 21 | % Standard deviation: 's', 'std'. 22 | % 23 | % For Area attribute ('a') the value/values of threshold are expressed in 24 | % percentage %. Such percentage is referred to the size of the image. 25 | % 26 | % For Standard Deviation attribute ('s') if an automatic computation is 27 | % required, the following field ValueOfThreshold should be filled with the 28 | % path of the training set (see example) 29 | % 30 | % OUTPUT: 31 | % EMAPOutput: Constructed Profile 32 | % TimeProfile: Time spent by the algorithm to compute the profile 33 | % Bands: Number of bands at the input 34 | % FeatOtput: Number of features at the output 35 | % 36 | % EXAMPLE 1 37 | % EMAP('PaviaPCA','PaviaEMAP', false, 'a', [10 15], 'd', [50 100 500]); 38 | % 39 | % EXAMPLE 2 40 | % EMAP('PaviaPCA','PaviaEMAP', false, 'a', [10 15], 's', 'Pavia_training.tif'); 41 | % 42 | % EXAMPLE 3 43 | % EMAP('PaviaPCA','PaviaEMAP', false, 'a', [10 15 20], 'd', [50 100 500], 's', 150); 44 | % 45 | % Mattia Pedergnana 46 | % mattia@mett.it 47 | % 15/08/2011 48 | %%%%%%% 49 | 50 | function [EMAPOutput, TimeProfile, Bands, FeatOtput] = EMAP_xdk(varargin) 51 | % InputImage,... 52 | % OutputImage,... 53 | % PCA,... 54 | % VectorAttributes,... 55 | % MatrixLambda 56 | % LambdaTot(:,1) = [0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7]; 57 | % LambdaTot(:,2) = [2.5 5 7.5 10 12.5 15 17.5 20 22.5 25 27.5 0 0 0]; 58 | if nargin < 6 59 | help EMAP_help 60 | error('You must specify at least six inputs.'); 61 | end 62 | if mod((nargin-4),2) ~= 0 63 | help EMAP_help 64 | error('Number of parameters/attributes wrong.'); 65 | end 66 | WBar = waitbar(0,'Wait.. I am computing the EAP vector for you.. be happy :)'); 67 | InputImage = varargin{1}; 68 | OutputImage = varargin{2}; 69 | PCA = varargin{3}; 70 | WriteOutput = varargin{4}; 71 | VectorAttributes = ''; 72 | long = 0; 73 | 74 | 75 | % Collect Name Attributes 76 | for i=5:2:nargin 77 | VectorAttributes = [VectorAttributes varargin{i}]; 78 | end 79 | 80 | % Collect Value Attributes - Evaluate the longest 81 | for i=6:2:nargin 82 | if ischar(varargin{i}) 83 | In_TRAIN = varargin{i}; 84 | else 85 | if length(varargin{i}) > long; 86 | long = length(varargin{i}); 87 | end 88 | end 89 | end 90 | 91 | 92 | % Collect Value Attributes - Populate the matrix 93 | if i == 6 && ischar(varargin{i}) % just automat stand dev 94 | MatrixLambda = 0; 95 | else 96 | pos = 1; 97 | for i=6:2:nargin 98 | if ischar(varargin{i}) 99 | MatrixLambda(:,pos) = padarray(0,[0 long-1],'post'); 100 | else 101 | HowManyZeros = long - length(varargin{i}); 102 | if HowManyZeros > 0 103 | MatrixLambda(:,pos) = padarray(varargin{i},[0 HowManyZeros],'post'); 104 | else 105 | MatrixLambda(:,pos) = varargin{i}; 106 | end 107 | end 108 | pos = pos + 1; 109 | end 110 | end 111 | 112 | if ischar(InputImage) 113 | [~, ~, ext] = fileparts(InputImage); 114 | WriteInSameDirectory = true; 115 | if isempty(ext) 116 | % I = enviread(InputImage); 117 | I_med = freadenvi(InputImage); 118 | [line column band] = size(I_med); 119 | I = zeros(column,line,band); 120 | for index = 1:band 121 | I(:,:,index) = I_med(:,:,index)'; 122 | end 123 | clear I_med; 124 | else 125 | I = imread(InputImage); 126 | end 127 | else 128 | I = InputImage; 129 | WriteInSameDirectory = false; 130 | end 131 | 132 | if PCA 133 | PCs= PCA_img(I, 'first'); 134 | else 135 | PCs = I; 136 | end 137 | 138 | [row, col, Bands] = size(PCs); % Number of PCs 139 | NumberOfEAP = length(VectorAttributes); % Number of EAPs 140 | FirstEAP = true; % It is necessary to avoid multiple presence of same PCs in EMAP vector. 141 | 142 | for j = 1:NumberOfEAP 143 | % if VectorAttributes(j) == 'a' 144 | % AreaTot = row*col; 145 | % Lambda = MatrixLambda(:,j)*AreaTot/100; 146 | % Lambda = Lambda(Lambda ~= 0); 147 | % else 148 | Lambda = MatrixLambda(:,j); 149 | % end 150 | 151 | Auto = false; 152 | 153 | if max(Lambda) == 0 && min(Lambda) ==0 ... 154 | && VectorAttributes(j) == 's' 155 | Auto = true; 156 | end 157 | 158 | if VectorAttributes(j) == 's' && Auto == false 159 | Percentage = Lambda; 160 | end 161 | % Compute the EAP 162 | for i=1:Bands 163 | waitbar((((j-1)*Bands)+i)/(Bands*NumberOfEAP)); 164 | PC_int16 = ConvertFromZeroToOneThousand(PCs(:,:,i),false); 165 | if VectorAttributes(j) == 's' && Auto == false 166 | Lambda = ComputeMean(PC_int16, Percentage); 167 | end 168 | 169 | if Auto 170 | [~, ~, ~, Lambda] = StandardDeviationAndMeanTraining(PC_int16, In_TRAIN, false); 171 | end 172 | PC_int16 = int16(PC_int16); 173 | Lambda = double(sort(nonzeros(Lambda))'); 174 | disp(['Feature Number = ' num2str(i)]); 175 | disp(['Lambda = ' num2str(Lambda)]); 176 | disp(['Number of thin/thick = ' num2str(length(Lambda))]); 177 | disp(['Attribute = ' VectorAttributes(j)]); 178 | disp('==================================================='); 179 | 180 | 181 | 182 | AP = attribute_profile(PC_int16, VectorAttributes(j), Lambda); 183 | 184 | % Find out the position of PC's band 185 | [~, ~, WhereIsPC] = size(AP); 186 | WhereIsPC = (WhereIsPC+1)/2; 187 | 188 | if (~FirstEAP) 189 | AP(:,:,WhereIsPC) = []; %http://www.mathworks.com/help/techdoc/math/f1-85766.html#f1-85977 190 | end 191 | 192 | if(i ~= 1) 193 | EAP_exit = cat(3, EAP_exit, AP); 194 | else 195 | EAP_exit = AP; 196 | end 197 | end 198 | 199 | % Compute the EMAP 200 | if(j ~= 1) 201 | EMAPOutput = cat(3, EMAPOutput, EAP_exit); 202 | else 203 | EMAPOutput = EAP_exit; 204 | FirstEAP = false; 205 | end 206 | 207 | end 208 | [~, ~, FeatOtput] = size(EMAPOutput); 209 | % TimeProfile = toc; 210 | %% Write OUT in the same directory of IN 211 | if WriteOutput 212 | if WriteInSameDirectory 213 | [pathstr, ~, ext] = fileparts(InputImage); 214 | if isempty(ext) 215 | hdr = [InputImage '.hdr']; 216 | else 217 | hdr = InputImage; 218 | end 219 | fullPathAndPath = which(hdr); 220 | [pathstr, ~, ~] = fileparts(fullPathAndPath); 221 | OutputImage = [pathstr '\' OutputImage]; 222 | end 223 | enviwriteMURA(EMAPOutput, OutputImage); 224 | end 225 | close(WBar); 226 | end -------------------------------------------------------------------------------- /functions/ImGray2Pseudocolor.m: -------------------------------------------------------------------------------- 1 | function rgb = ImGray2Pseudocolor(gim, map, n) 2 | % IMGRAY2PSEUDOCOLOR transform a gray image to pseudocolor image 3 | % GIM is the input gray image data 4 | % MAP is the colormap already defined in MATLAB, for example: 5 | % 'Jet','HSV','Hot','Cool','Spring','Summer','Autumn','Winter','Gray', 6 | % 'Bone','Copper','Pink','Lines' 7 | % N specifies the size of the colormap 8 | % rgb is the output COLOR image data 9 | % 10 | % Main codes stolen from: 11 | % http://www.alecjacobson.com/weblog/?p=1655 12 | % %% rgb = ind2rgb(gray2ind(im,255),jet(255)); % 13 | % 14 | 15 | 16 | [nr,nc,nz] = size(gim); 17 | rgb = zeros(nr,nc,3); 18 | 19 | if ( ~IsValidColormap(map) ) 20 | disp('Error in ImGray2Pseudocolor: unknown colormap!'); 21 | elseif (~(round(n) == n) || (n < 0)) 22 | disp('Error in ImGray2Pseudocolor: non-integer or non-positive colormap size'); 23 | else 24 | fh = str2func(ExactMapName(map)); 25 | 26 | rgb = ind2rgb(gray2ind(gim,n),fh(n)); 27 | rgb = uint8(rgb*255); 28 | end 29 | 30 | if (nz == 3) 31 | rgb = gim; 32 | disp('Input image has 3 color channel, the original data returns'); 33 | end 34 | 35 | function y = IsValidColormap(map) 36 | 37 | y = strncmpi(map,'jet',length(map)) | strncmpi(map,'hsv',length(map)) |... 38 | strncmpi(map,'hot',length(map)) | strncmpi(map,'cool',length(map)) |... 39 | strncmpi(map,'spring',length(map)) | strncmpi(map,'summer',length(map)) |... 40 | strncmpi(map,'autumn',length(map)) | strncmpi(map,'winter',length(map)) |... 41 | strncmpi(map,'gray',length(map)) | strncmpi(map,'bone',length(map)) |... 42 | strncmpi(map,'copper',length(map)) | strncmpi(map,'pink',length(map)) |... 43 | strncmpi(map,'lines',length(map)); 44 | 45 | function emapname = ExactMapName(map) 46 | 47 | if strncmpi(map,'jet',length(map)) 48 | emapname = 'jet'; 49 | elseif strncmpi(map,'HSV',length(map)) 50 | emapname = 'HSV'; 51 | elseif strncmpi(map,'hot',length(map)) 52 | emapname = 'hot'; 53 | elseif strncmpi(map,'cool',length(map)) 54 | emapname = 'cool'; 55 | elseif strncmpi(map,'spring',length(map)) 56 | emapname = 'spring'; 57 | elseif strncmpi(map,'summer',length(map)) 58 | emapname = 'summer'; 59 | elseif strncmpi(map,'autumn',length(map)) 60 | emapname = 'autumn'; 61 | elseif strncmpi(map,'winter',length(map)) 62 | emapname = 'winter'; 63 | elseif strncmpi(map,'gray',length(map)) 64 | emapname = 'gray'; 65 | elseif strncmpi(map,'bone',length(map)) 66 | emapname = 'bone'; 67 | elseif strncmpi(map,'copper',length(map)) 68 | emapname = 'copper'; 69 | elseif strncmpi(map,'pink',length(map)) 70 | emapname = 'pink'; 71 | elseif strncmpi(map,'lines',length(map)) 72 | emapname = 'lines'; 73 | end 74 | -------------------------------------------------------------------------------- /functions/NormalizeData.m: -------------------------------------------------------------------------------- 1 | function [ data ] = NormalizeData( data ) 2 | % NORMALIZEDATA Summary of this function goes here 3 | % Detailed explanation goes here 4 | [M N D]=size(data); 5 | data=reshape(data,[M*N D]); 6 | data=scale_new(data); 7 | data=reshape(data,[M N D]); 8 | end 9 | 10 | -------------------------------------------------------------------------------- /functions/PCA_img.m: -------------------------------------------------------------------------------- 1 | function [PC, out_param] = PCA_img(varargin) 2 | % Compute the Principal Component Analyis on a multispectral image. 3 | % 4 | % [PC, PAR] = PCA_img(D) 5 | % [PC, PAR] = PCA_img(D, OP) 6 | % 7 | % INPUT 8 | % D 3d matrix (e.g., multi- or hyperspectral image). 9 | % OP Variable specifying the computation of the PCs. 10 | % OP can be of different types: 11 | % 12 | % string: 'all' give in output all the PCs; 13 | % 'first' give in output the first PCs that explain more than 99% of the total variance; 14 | % 15 | % numeric: specify the number of PCs; 16 | % 17 | % struct: struct of options 18 | % OP.option : can either be 'first' or 'all' 19 | % see above for explanation. 20 | % 21 | % OP.is_std : if true perform PCA on 22 | % Standardized data (data with unit 23 | % variance). 24 | % 25 | % OUTPUT 26 | % PC 3d matrix of the computed PCs. 27 | % PAR Struct reporting the parameters of the processing. 28 | % 29 | % 30 | % Mauro Dalla Mura 31 | % Remote Sensing Laboratory 32 | % Dept. of Information Engineering and Computer Science 33 | % University of Trento 34 | % E-mail: dallamura@disi.unitn.it 35 | % Web page: http://www.disi.unitn.it/rslab 36 | 37 | % Parse inputs 38 | if nargin == 1 39 | data_set = varargin{1}; 40 | option = 'first'; % default 41 | is_std = false; % default 42 | elseif nargin == 2 43 | data_set = varargin{1}; 44 | in_param = varargin{2}; 45 | 46 | if (~isstruct(in_param)) 47 | option = in_param; 48 | is_std = false; % default 49 | else 50 | if (isfield(in_param, 'option')) 51 | option = in_param.option; % number of PCs 52 | else 53 | option = 'first'; 54 | end 55 | if (isfield(in_param, 'is_std')) 56 | is_std = in_param.is_std; % number of PCs 57 | else 58 | is_std = false; 59 | end 60 | end 61 | end 62 | 63 | out_param.option = option; 64 | out_param.is_std = is_std; 65 | 66 | if (isnumeric(option) && (option > 0)) % Take the first N PCs 67 | nPCs = option; 68 | elseif (ischar(option) && strcmp(option, 'all')) % Take all the PCs 69 | nPCs = size(data_set,3); 70 | elseif (ischar(option) && strcmp(option, 'first')) % Take the first PCs that explain more than 99% of variance 71 | nPCs = -1; 72 | else 73 | error('option = {[first], all, N}\n'); 74 | end 75 | % ------------------------------------------------------------------------ 76 | 77 | % Reshape data in N patterns x M features 78 | X = double(reshape(data_set, size(data_set,1)*size(data_set,2), size(data_set,3))); 79 | 80 | % Subtract the mean vector from the data 81 | mu = mean(X); 82 | for i=1:size(data_set,3) 83 | X(:,i) = X(:,i)-mu(i); 84 | end 85 | 86 | V = cov(X); 87 | if (is_std) % Perform PCA on Standardized data (data with unit variance). 88 | SD = sqrt(diag(V)); 89 | R = V./(SD*SD'); % Correlation Matrix 90 | [eigvec, latent, totvar] = pcacov(R); 91 | else 92 | [eigvec, latent, totvar] = pcacov(V); 93 | end 94 | 95 | % the direction of the eigenvectors might not be the one desired (visually) 96 | % if not, remove the following line 97 | % eigvec = -eigvec; 98 | 99 | if (nPCs == -1) % Find the number of PCs that explain 99% of var 100 | for i=1:length(totvar) 101 | if (sum(totvar(1:i)) > 99) 102 | nPCs = i; 103 | break; 104 | end 105 | end 106 | end 107 | 108 | % Compute the nPCs PCs and reshape them in the original format of the 109 | % data_set 110 | for i=1:nPCs 111 | PC(:,:,i) = reshape(X*eigvec(:,i), size(data_set,1), size(data_set,2)); % PCs' data have double data range 112 | end 113 | 114 | out_param.torvar = totvar; 115 | out_param.nPCs = nPCs; 116 | 117 | % % scale the PCs to an int range 118 | % for i=1:4 119 | % tmp = PC(:,:,i); 120 | % tmp = (tmp - min(tmp(:)))/(max(tmp(:))-min(tmp(:))); 121 | % PC_int(:,:,i) = uint16(1000*tmp); 122 | % end 123 | % 124 | % % write PCs 125 | % for i=1:4 126 | % imwrite(PC_int(:,:,i), ['path\PC_',int2str(i),'.png'], 'png'); 127 | % imwrite(imadjust(PC_int(:,:,i)), ['path\adj_PC_',int2str(i),'.png'], 'png'); 128 | % end -------------------------------------------------------------------------------- /functions/RF.m: -------------------------------------------------------------------------------- 1 | % RF Domain transform recursive edge-preserving filter. 2 | % 3 | % F = RF(img, sigma_s, sigma_r, num_iterations, joint_image) 4 | % 5 | % Parameters: 6 | % img Input image to be filtered. 7 | % sigma_s Filter spatial standard deviation. 8 | % sigma_r Filter range standard deviation. 9 | % num_iterations Number of iterations to perform (default: 3). 10 | % joint_image Optional image for joint filtering. 11 | % 12 | % 13 | % 14 | % This is the reference implementation of the domain transform RF filter 15 | % described in the paper: 16 | % 17 | % Domain Transform for Edge-Aware Image and Video Processing 18 | % Eduardo S. L. Gastal and Manuel M. Oliveira 19 | % ACM Transactions on Graphics. Volume 30 (2011), Number 4. 20 | % Proceedings of SIGGRAPH 2011, Article 69. 21 | % 22 | % Please refer to the publication above if you use this software. For an 23 | % up-to-date version go to: 24 | % 25 | % http://inf.ufrgs.br/~eslgastal/DomainTransform/ 26 | % 27 | % 28 | % THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES 29 | % OF ANY KIND, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | % OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | % THIS SOFTWARE. 35 | % 36 | % Version 1.0 - August 2011. 37 | 38 | function F = RF(img, sigma_s, sigma_r, num_iterations, joint_image) 39 | 40 | I = double(img); 41 | 42 | if ~exist('num_iterations', 'var') 43 | num_iterations = 3; 44 | end 45 | 46 | if exist('joint_image', 'var') && ~isempty(joint_image) 47 | J = double(joint_image); 48 | 49 | if (size(I,1) ~= size(J,1)) || (size(I,2) ~= size(J,2)) 50 | error('Input and joint images must have equal width and height.'); 51 | end 52 | else 53 | J = I; 54 | end 55 | 56 | [h w num_joint_channels] = size(J); 57 | 58 | %% Compute the domain transform (Equation 11 of our paper). 59 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60 | 61 | % Estimate horizontal and vertical partial derivatives using finite 62 | % differences. 63 | dIcdx = diff(J, 1, 2); 64 | dIcdy = diff(J, 1, 1); 65 | 66 | dIdx = zeros(h,w); 67 | dIdy = zeros(h,w); 68 | 69 | % Compute the l1-norm distance of neighbor pixels. 70 | for c = 1:num_joint_channels 71 | dIdx(:,2:end) = dIdx(:,2:end) + abs( dIcdx(:,:,c) ); 72 | dIdy(2:end,:) = dIdy(2:end,:) + abs( dIcdy(:,:,c) ); 73 | end 74 | 75 | % Compute the derivatives of the horizontal and vertical domain transforms. 76 | dHdx = (1 + sigma_s/sigma_r * dIdx); 77 | dVdy = (1 + sigma_s/sigma_r * dIdy); 78 | 79 | % We do not integrate the domain transforms since our recursive filter 80 | % uses the derivatives directly. 81 | %ct_H = cumsum(dHdx, 2); 82 | %ct_V = cumsum(dVdy, 1); 83 | 84 | % The vertical pass is performed using a transposed image. 85 | dVdy = dVdy'; 86 | 87 | %% Perform the filtering. 88 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89 | N = num_iterations; 90 | F = I; 91 | 92 | sigma_H = sigma_s; 93 | 94 | for i = 0:num_iterations - 1 95 | 96 | % Compute the sigma value for this iteration (Equation 14 of our paper). 97 | sigma_H_i = sigma_H * sqrt(3) * 2^(N - (i + 1)) / sqrt(4^N - 1); 98 | 99 | F = TransformedDomainRecursiveFilter_Horizontal(F, dHdx, sigma_H_i); 100 | F = image_transpose(F); 101 | 102 | F = TransformedDomainRecursiveFilter_Horizontal(F, dVdy, sigma_H_i); 103 | F = image_transpose(F); 104 | 105 | end 106 | 107 | F = cast(F, class(img)); 108 | 109 | end 110 | 111 | %% Recursive filter. 112 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 113 | function F = TransformedDomainRecursiveFilter_Horizontal(I, D, sigma) 114 | 115 | % Feedback coefficient (Appendix of our paper). 116 | a = exp(-sqrt(2) / sigma); 117 | 118 | F = I; 119 | V = a.^D; 120 | 121 | [h w num_channels] = size(I); 122 | 123 | % Left -> Right filter. 124 | for i = 2:w 125 | for c = 1:num_channels 126 | F(:,i,c) = F(:,i,c) + V(:,i) .* ( F(:,i - 1,c) - F(:,i,c) ); 127 | end 128 | end 129 | 130 | % Right -> Left filter. 131 | for i = w-1:-1:1 132 | for c = 1:num_channels 133 | F(:,i,c) = F(:,i,c) + V(:,i+1) .* ( F(:,i + 1,c) - F(:,i,c) ); 134 | end 135 | end 136 | 137 | end 138 | 139 | %% 140 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 141 | function T = image_transpose(I) 142 | 143 | [h w num_channels] = size(I); 144 | 145 | T = zeros([w h num_channels], class(I)); 146 | 147 | for c = 1:num_channels 148 | T(:,:,c) = I(:,:,c)'; 149 | end 150 | 151 | end 152 | -------------------------------------------------------------------------------- /functions/RRX_detect.m: -------------------------------------------------------------------------------- 1 | function [d] = RRX_detect(f0,d0,data,sigma_s,sigma_r,r,lamda) 2 | %RRX_DETECT Summary of this function goes here 3 | % Detailed explanation goes here 4 | % level = graythresh(d0); 5 | % d0 = im2bw(d0,level); 6 | for i=1:size(d0,3) 7 | se = strel('square',r); 8 | di = d0(:,:,i); 9 | d1 = imdilate(di,se); 10 | % d1=di; 11 | % d2 = imerode(d0,se); 12 | level = graythresh(d1); 13 | d1 = im2bw(d1,level); 14 | % surround measure 15 | % [idx,idy]=find_bond(d1); 16 | % d1 =~(imfill(~d1,[idx,idy])); 17 | d1 = bwareafilt(d1,[1 size(d0,1)*size(d0,2)/lamda]); 18 | di(d1==0)=0; 19 | % d(:,:,i) = RF(double(di), 100, 0.2, 3, f0); 20 | % end 21 | % d=sum(d,3); 22 | d(:,:,i) =di; 23 | end 24 | d=sum(d,3); 25 | d=mat2gray(d); 26 | d = RF(double(d), sigma_s,sigma_r, 3, f0); 27 | % d = guidedfilter(f0,double(d),10,0.1^4); 28 | % for i=1:size(d,3) 29 | % se = strel('square',1); 30 | % di = d(:,:,i); 31 | % d1 = imdilate(di,se); 32 | % % d2 = imerode(d0,se); 33 | % level = graythresh(d1); 34 | % d1 = im2bw(d1,level); 35 | % % surround measure 36 | % % [idx,idy]=find_bond(d1); 37 | % % d1 =~(imfill(~d1,[idx,idy])); 38 | % d1 = bwareafilt(d1,[1 size(d0,1)*size(d0,2)/100]); 39 | % di(d1==0)=0; 40 | % % d(:,:,i) = RF(double(di), 100, 0.2, 3, f0); 41 | % % end 42 | % % d=sum(d,3); 43 | % d(:,:,i) =di; 44 | % end 45 | % d=sum(d,3); 46 | % d = RF(double(d), 100, 0.2, 3, f0); 47 | % d1 = im2bw(d1,0.6); 48 | % RX measure 49 | % r0 = RRX(d1,data); 50 | 51 | 52 | end 53 | function result=RRX(d1,data) 54 | cc=bwlabel(d1); 55 | se2 = strel('square',4); 56 | ww=imdilate(cc,se2); 57 | ss=(ww-cc); 58 | result=zeros(size(d1,1),size(d1,2)); 59 | % r0 = RRX(d1,data); 60 | for i=1:max(cc(:)) 61 | [object_x,object_y]=find(cc==i); 62 | X=data(object_x,object_y,:); 63 | [backgrd_x,backgrd_y]=find(ss==i); 64 | Y=data(backgrd_x,backgrd_y,:); 65 | result(object_x,object_y)=RX_xy(X,Y); 66 | end 67 | 68 | end 69 | function [idx,idy]=find_bond(d) 70 | [r,c]=size(d); 71 | idx0=zeros(r,c); 72 | idx0(:,1)=1; 73 | idx0(:,r)=1; 74 | idx0(1,:)=1; 75 | idx0(c,:)=1; 76 | [idx,idy]=find(idx0==1); 77 | end 78 | 79 | function D=RX_xy(X,Y) 80 | [rows_x,columns_x bands]=size(X); 81 | [rows_y,columns_y bands]=size(Y); 82 | X=reshape(X, rows_x*columns_x, bands); 83 | Y=reshape(Y, rows_y*columns_y, bands); 84 | % RX detection 85 | X=X'; 86 | Y=Y'; 87 | [N M] = size(X); 88 | 89 | Y_mean = mean(Y.').'; 90 | 91 | X = abs(X - repmat(Y_mean, [1 M])); 92 | 93 | Sigma = (X * X')/M; 94 | 95 | Sigma_inv = inv(Sigma); 96 | for m = 1:M 97 | D(m) = X(:, m)' * Sigma_inv * X(:, m); 98 | end 99 | % map reshape 100 | D = reshape(D,[rows_x columns_x]); 101 | end 102 | 103 | -------------------------------------------------------------------------------- /functions/ReadData.m: -------------------------------------------------------------------------------- 1 | function [data map] = ReadData(data_name) 2 | %READDATA Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | switch lower(data_name) 6 | case '1' 7 | load('./data/San_Diego'); 8 | case '2' 9 | load('./data/Airport'); 10 | case '3' 11 | load('./data/Beach'); 12 | case '4' 13 | load('./data/Urban'); 14 | case '5' 15 | load('./data/HYDICE_urban'); 16 | end 17 | end 18 | 19 | -------------------------------------------------------------------------------- /functions/attribute_profile.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/functions/attribute_profile.mexa64 -------------------------------------------------------------------------------- /functions/attribute_profile.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/functions/attribute_profile.mexglx -------------------------------------------------------------------------------- /functions/attribute_profile.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/functions/attribute_profile.mexw32 -------------------------------------------------------------------------------- /functions/attribute_profile.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yousefan/AED-algorithm/d3b7844ab545188dc0dcbe586a4dfe078cf602f2/functions/attribute_profile.mexw64 -------------------------------------------------------------------------------- /functions/attribute_profile_readme.txt: -------------------------------------------------------------------------------- 1 | --------------------------------------- 2 | --- Morphological Attribute Profile --- 3 | --------------------------------------- 4 | 5 | Description 6 | ----------- 7 | This routine computes an Attribute Profile (AP) of a 2D image as presented in [1]. 8 | An AP is an array of images resulting from filtering the input image with a sequence of morphological attribute filters. 9 | The AP is composed by the concatenation of an attribute thinning and attribute thickening profile. 10 | The attribute thinning (thickening) profile is generated by the sequential application of attribute thinning (thickening) filters with progressively relaxed criteria (i.e., progressively coarser effect on the image). 11 | This approach leads to a increasing simplification of the input image obtained by removing either bright (in the thinning profile) or dark (in the thickening profile) regions. Dark and bright with respect to the surrounding gray-level. This effect is due to the sequence of thresholds (lambdas) used by the filters. 12 | The AP is composed by the concatenation of the attribute thickening profile computed in decreasing order (the coarser image is the first), the original input image, and the attribute thickening profile in increasing order. 13 | Thus if N is the number of thresholds considered in the analysis, the AP will be composed by 2N+1 images. 14 | For further information on APs please refer to [1]. 15 | The code computing the attribute profiles have been implemented using the C++ library Olena 1.0 (available at http://www.lrde.epita.fr/cgi-bin/twiki/view/Olena/Olena100). 16 | 17 | 18 | [1] M. Dalla Mura, J. A. Benediktsson, B. Waske, and L. Bruzzone, 19 | "Morphological attribute profiles for the analysis of very high resolution images," 20 | IEEE Transactions on Geoscience and Remote Sensing, vol.48, no.10, pp.3747-3762, Oct. 2010. 21 | 22 | 23 | Installation 24 | ------------ 25 | Note: The routine is provided as precompiled mex file. Supported platforms are: Win32, Linux32, Linux64. 26 | 27 | Include the directory containing the compiled mex file in a location where Matlab can find it. 28 | For a quick test, set the folder as the Current Directory of Matlab. 29 | For a more extensive use, it is suggested to include the folder in the Matlab search path (in Matlab, File->Set path->Add folder...). 30 | 31 | Usage 32 | ----- 33 | 34 | AP = ATTRIBUTE_PROFILE(I, A, L) 35 | AP = ATTRIBUTE_PROFILE(I, A, L, C) 36 | AP = ATTRIBUTE_PROFILE(I, A, L, C, F) 37 | 38 | INPUT 39 | I: 2D input image. Data type supported: uint8, int8, uint16, int16, uint32, int32, uint64, int64. 40 | A: Attribute type. String. 41 | Attribute supported: 42 | Area: 'a', 'area'; 43 | Length of the diagonal of the bounding box: 'd', 'diagonal'; 44 | Moment of inertia: 'i', 'inertia'; 45 | Standard deviation: 's', 'std'. 46 | L: Values of lambda. Array of double. 47 | C: Connectivity. Scalar. Either 4 (default) or 8. 48 | F: Filtering rule. String. 49 | Rules supported: 50 | Min: 'min' (default for attributes 'a', 'd'); 51 | Max: 'max'; 52 | Direct: 'direct'; 53 | Sub: 'sub' (default for attributes 'i', 's'). 54 | 55 | OUTPUT 56 | AP: Attribute Profile. Array of 2D images of the same data type of the input image. 57 | 58 | -- 59 | Version 1.0 60 | 14 May 2010 61 | 62 | Mauro Dalla Mura - dallamuradisi.unitn.it 63 | 64 | Remote Sensing Laboratory 65 | Dept. of Information Engineering and Computer Science 66 | University of Trento 67 | 68 | Faculty of Electrical Engineering and Computer Science 69 | University of Iceland 70 | -------------------------------------------------------------------------------- /functions/bwareafilt.m: -------------------------------------------------------------------------------- 1 | function bw2 = bwareafilt(varargin) 2 | %bwareafilt Extract objects from binary image by size. 3 | % BW2 = BWAREAFILT(BW, RANGE) extracts all connected components (objects) 4 | % from a binary image where the area is in RANGE, producing another 5 | % binary image BW2. RANGE is a 2-by-1 vector of minimum and maximum 6 | % sizes (inclusive). Objects that do not meet the criterion are removed. 7 | % The default connectivity is 8. 8 | % 9 | % BW2 = BWAREAFILT(BW, N) keeps the N largest objects. In the event of a 10 | % tie for N-th place, only the first N objects are part of BW2. The 11 | % default connectivity is 8. 12 | % 13 | % BW2 = BWAREAFILT(BW, N, KEEP) retains the N largest objects if KEEP is 14 | % 'largest' (the default) or the N smallest if KEEP is 'smallest'. 15 | % 16 | % BW2 = BWAREAFILT(BW, ..., CONN) specifies the desired connectivity. 17 | % Connectivity can either be 4, 8 or a 3x3 matrix of 0s and 1s. The 18 | % 1-valued elements define neighborhood locations relative to the center 19 | % element of CONN. CONN must be symmetric about its center element. 20 | % 21 | % Examples 22 | % -------- 23 | % % Find the ten largest objects. 24 | % BW = imread('text.png'); 25 | % BW2 = bwareafilt(BW, 5); 26 | % figure; imshow(BW2); title('Five largest letters') 27 | % 28 | % See also BWAREAOPEN, BWCONNCOMP, BWPROPFILT, CONNDEF, REGIONPROPS. 29 | 30 | % Copyright 2014 The MathWorks, Inc. 31 | 32 | [bw, p, direction, conn] = parse_inputs(varargin{:}); 33 | bw2 = bwpropfilt(bw, 'area', p, direction, conn); 34 | 35 | %-------------------------------------------------------------------------- 36 | function [bw, p, direction, conn] = parse_inputs(varargin) 37 | 38 | narginchk(2,4) 39 | 40 | bw = varargin{1}; 41 | p = varargin{2}; 42 | 43 | validateattributes(p, {'numeric'}, {'nonnegative'}, mfilename, '', 2) 44 | 45 | direction = ''; 46 | conn = conndef(ndims(bw),'maximal'); 47 | 48 | if (nargin == 3) 49 | 50 | if (isnumeric(varargin{3})) 51 | conn = varargin{3}; 52 | else 53 | direction = varargin{3}; % Let bwpropfilt validate it. 54 | end 55 | 56 | elseif (nargin == 4) 57 | 58 | direction = varargin{3}; 59 | conn = varargin{4}; 60 | 61 | end 62 | -------------------------------------------------------------------------------- /functions/bwpropfilt.m: -------------------------------------------------------------------------------- 1 | function bw2 = bwpropfilt(varargin) 2 | %bwpropfilt Extract objects from binary image using properties. 3 | % BW2 = BWPROPFILT(BW, ATTRIB, RANGE) extracts all connected components 4 | % (objects) from a binary image where the attribute string ATTRIB has 5 | % values in RANGE, producing another binary image BW2. RANGE is a 2-by-1 6 | % vector of low and high values. (The minimum and maximum values are 7 | % considered to be in the range.) Objects that do not meet the criterion 8 | % are removed. The default connectivity is 8. 9 | % 10 | % BW2 = BWPROPFILT(BW, ATTRIB, N) sorts the objects based on ATTRIB and 11 | % keeps the N largest values. In the event of a tie for N-th place, only 12 | % the first N objects are part of BW2. 13 | % 14 | % BW2 = BWPROPFILT(BW, ATTRIB, N, KEEP) sorts the objects based on 15 | % ATTRIB, keeping the N largest values if KEEP is 'largest' (the default) 16 | % and the N smallest if KEEP is 'smallest'. 17 | % 18 | % BW2 = BWPROPFILT(BW, I, ATTRIB, ...) sorts objects based on the 19 | % intensity values in the grayscale image I and the property ATTRIB. 20 | % 21 | % ATTRIB can have one of these values: 22 | % 23 | % 'Area' 'ConvexArea' 'Eccentricity' 24 | % 'EquivDiameter' 'EulerNumber' 'Extent' 25 | % 'FilledArea' 'MajorAxisLength' 'MinorAxisLength' 26 | % 'Orientation' 'Perimeter' 'PerimeterOld' 27 | % 'Solidity' 28 | % 29 | % If a grayscale image is also provided, ATTRIB can have one of these 30 | % additional values: 31 | % 32 | % 'MaxIntensity' 'MeanIntensity' 'MinIntensity' 33 | % 34 | % BW2 = BWPROPFILT(BW, ..., CONN) specifies the desired connectivity. 35 | % Connectivity can either be 4, 8 or a 3x3 matrix of 0s and 1s. The 36 | % 1-valued elements define neighborhood locations relative to the center 37 | % element of CONN. CONN must be symmetric about its center element. 38 | % 39 | % 40 | % Examples 41 | % -------- 42 | % % Find regions without holes (Euler number == 1). 43 | % BW = imread('text.png'); 44 | % BW2 = bwpropfilt(BW, 'EulerNumber', [1 1]); 45 | % figure; imshow(BW); title('Original image') 46 | % figure; imshow(BW2); title('Regions with Euler Number == 1') 47 | % 48 | % % Find the ten largest perimeters. 49 | % BW = imread('text.png'); 50 | % BW2 = bwpropfilt(BW, 'perimeter', 10); 51 | % figure; imshow(BW2); title('Largest perimeters') 52 | % 53 | % See also BWAREAFILT, BWAREAOPEN, BWCONNCOMP, CONNDEF, REGIONPROPS. 54 | 55 | % Copyright 2014-2015 The MathWorks, Inc. 56 | 57 | [bw, I, attrib, p, direction, conn] = parse_inputs(varargin{:}); 58 | 59 | CC = bwconncomp(bw,conn); 60 | 61 | if isempty(I) 62 | props = regionprops(CC, attrib); 63 | else 64 | props = regionprops(CC, I, attrib); 65 | end 66 | 67 | if isempty(props) 68 | bw2 = bw; 69 | return; 70 | end 71 | 72 | allValues = [props.(attrib)]; 73 | 74 | switch numel(p) 75 | case 1 76 | % Find the top "p" regions. 77 | p = min(p, numel(props)); 78 | 79 | switch direction 80 | case {'smallest'} 81 | [~, idx] = sort(allValues, 'ascend'); 82 | otherwise 83 | [~, idx] = sort(allValues, 'descend'); 84 | end 85 | 86 | % Take care of ties. 87 | minSelected = allValues(idx(p)); 88 | switch direction 89 | case {'smallest'} 90 | regionsToKeep = allValues <= minSelected; 91 | otherwise 92 | regionsToKeep = allValues >= minSelected; 93 | end 94 | 95 | if (numel(find(regionsToKeep)) > p) 96 | regionsToKeep = find(regionsToKeep, p, 'first'); 97 | warning(message('images:bwfilt:tie')) 98 | end 99 | 100 | case 2 101 | % Find regions within the range. 102 | regionsToKeep = (allValues >= p(1)) & (allValues <= p(2)); 103 | end 104 | 105 | idxToKeep = CC.PixelIdxList(regionsToKeep); 106 | idxToKeep = vertcat(idxToKeep{:}); 107 | 108 | bw2 = false(size(bw)); 109 | bw2(idxToKeep) = true; 110 | 111 | %-------------------------------------------------------------------------- 112 | function [bw, I, attrib, p, direction, conn] = parse_inputs(varargin) 113 | 114 | narginchk(3,6) 115 | 116 | % Binary image 117 | bw = varargin{1}; 118 | validateattributes(bw, {'logical'}, {'nonsparse', '2d'}, mfilename, 'BW', 1); 119 | 120 | % Intensity image (optional) 121 | if isnumeric(varargin{2}) 122 | I = varargin{2}; 123 | validateattributes(I, {'double', 'single', 'uint8', 'int8', 'uint16', 'int16', 'uint32', 'int32'}, ... 124 | {'nonsparse', '2d'}, mfilename, 'I', 2); 125 | argOffset = 1; 126 | else 127 | I = []; 128 | argOffset = 0; 129 | end 130 | 131 | % Attribute 132 | attrib = validatestring(varargin{2 + argOffset}, {'Area' 133 | 'ConvexArea' 134 | 'Eccentricity' 135 | 'EquivDiameter' 136 | 'EulerNumber' 137 | 'Extent' 138 | 'FilledArea' 139 | 'MajorAxisLength' 140 | 'MaxIntensity' 141 | 'MeanIntensity' 142 | 'MinIntensity' 143 | 'MinorAxisLength' 144 | 'Orientation' 145 | 'Perimeter' 146 | 'PerimeterOld' 147 | 'Solidity'}, ... 148 | mfilename, 'ATTRIB', 2 + argOffset); 149 | 150 | % [min max] range or "top n" 151 | p = varargin{3 + argOffset}; 152 | switch numel(p) 153 | case 1 154 | validateattributes(p, {'double'}, {'finite', 'row', 'nonsparse', 'integer', 'positive', 'real'}, ... 155 | mfilename, 'P', 3 + argOffset); 156 | case 2 157 | validateattributes(p, {'numeric'}, {'row', 'nonsparse', 'nondecreasing','real'}, ... 158 | mfilename, 'P', 3 + argOffset); 159 | otherwise 160 | error(message('images:bwfilt:wrongNumelForP')) 161 | end 162 | p = double(p); 163 | 164 | % End of required arguments. 165 | direction = 'largest'; 166 | conn = conndef(ndims(bw),'maximal'); 167 | 168 | % Ensure KEEP and CONN are in the right order if they're both specified. 169 | if ((nargin - argOffset) < 4) 170 | return 171 | elseif ((nargin - argOffset) == 5) 172 | validateattributes(varargin{4 + argOffset}, {'char'}, {'nonsparse'}, ... 173 | mfilename, 'KEEP', 4 + argOffset); % Nonsparse because we have to put something. 174 | validateattributes(varargin{5 + argOffset}, {'numeric'}, {'real'}, ... 175 | mfilename, 'CONN', 5 + argOffset); 176 | end 177 | 178 | % Largest/smallest flag (optional) 179 | if ischar(varargin{4 + argOffset}) 180 | direction = varargin{4 + argOffset}; 181 | 182 | if (~isempty(direction)) 183 | direction = validatestring(direction, ... 184 | {'largest', 'smallest'}, ... 185 | mfilename, 'ATTRIB', 4 + argOffset); 186 | 187 | if (numel(p) > 1) 188 | error(message('images:bwfilt:directionRequiresScalarN')) 189 | end 190 | end 191 | 192 | argOffset = argOffset + 1; 193 | end 194 | 195 | % Connectivity (optional) 196 | if (nargin >= 4 + argOffset) 197 | conn = varargin{4 + argOffset}; 198 | end 199 | iptcheckconn(conn, mfilename, 'CONN', 4 + argOffset) 200 | -------------------------------------------------------------------------------- /functions/morph_detect.m: -------------------------------------------------------------------------------- 1 | function [ d ] = morph_detect( f0,para,type) 2 | %PREDETECTION Summary of this function goes here 3 | % Detailed explanation goes here 4 | bands_number=size(f0,3); 5 | switch lower(type) 6 | case 'a' 7 | x=EMAP_xdk(f0,'',false, '', 'a', para); 8 | [d_feature b_feature] = dirfea(x,bands_number); 9 | % d = mat2gray(d_feature+b_feature); 10 | d=b_feature; 11 | case 'd' 12 | x=EMAP_xdk(f0,'',false, '', 'd', para); 13 | d_feature=(abs(x(:,:,1)-x(:,:,2))); 14 | b_feature=(abs(x(:,:,3)-x(:,:,2))); 15 | d = mat2gray(d_feature+b_feature); 16 | case 'i' 17 | x=EMAP_xdk(f0,'',false, '', 'i', para); 18 | d_feature=(abs(x(:,:,1)-x(:,:,2))); 19 | b_feature=(abs(x(:,:,3)-x(:,:,2))); 20 | d = mat2gray(d_feature+b_feature); 21 | case 's' 22 | x=EMAP_xdk(f0,'',false, '', 's', para); 23 | d_feature=(abs(x(:,:,1)-x(:,:,2))); 24 | b_feature=(abs(x(:,:,3)-x(:,:,2))); 25 | d = mat2gray(d_feature+b_feature); 26 | end 27 | end 28 | function [spectral_feature spatial_feature] = dirfea(x,bands_number) 29 | 30 | for i=1:bands_number 31 | spatial_feature(:,:,i)=x(:,:,i*3-2)-x(:,:,i*3); 32 | if i==1 33 | spectral_feature(:,:,i)=zeros(size(x,1),size(x,2)); 34 | else 35 | spectral_feature(:,:,i)=abs(x(:,:,i*3-1)-x(:,:,(i-1)*3-1)); 36 | end 37 | end 38 | spectral_feature=double(mat2gray(spectral_feature)); 39 | spatial_feature=double(mat2gray(spatial_feature)); 40 | end 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /functions/roc.m: -------------------------------------------------------------------------------- 1 | function [tp, fp] = roc(t, y) 2 | % 3 | % ROC - generate a receiver operating characteristic curve 4 | % 5 | % [TP,FP] = ROC(T,Y) gives the true-positive rate (TP) and false positive 6 | % rate (FP), where Y is a column vector giving the score assigned to each 7 | % pattern and T indicates the true class (a value above zero represents 8 | % the positive class and anything else represents the negative class). To 9 | % plot the ROC curve, 10 | % 11 | % PLOT(FP,TP); 12 | % XLABEL('FALSE POSITIVE RATE'); 13 | % YLABEL('TRUE POSITIVE RATE'); 14 | % TITLE('RECEIVER OPERATING CHARACTERISTIC (ROC)'); 15 | % 16 | % See [1] for further information. 17 | % 18 | % [1] Fawcett, T., "ROC graphs : Notes and practical 19 | % considerations for researchers", Technical report, HP 20 | % Laboratories, MS 1143, 1501 Page Mill Road, Palo Alto 21 | % CA 94304, USA, April 2004. 22 | % 23 | % See also : ROCCH, AUROC 24 | % 25 | % File : roc.m 26 | % 27 | % Date : Friday 9th June 2005 28 | % 29 | % Author : Dr Gavin C. Cawley 30 | % 31 | % Description : Generate an ROC curve for a two-class classifier. 32 | % 33 | % References : [1] Fawcett, T., "ROC graphs : Notes and practical 34 | % considerations for researchers", Technical report, HP 35 | % Laboratories, MS 1143, 1501 Page Mill Road, Palo Alto 36 | % CA 94304, USA, April 2004. 37 | % 38 | % History : 10/11/2004 - v1.00 39 | % 09/06/2005 - v1.10 - minor recoding 40 | % 05/09/2008 - v2.00 - re-write using algorithm from [1] 41 | % 42 | % Copyright : (c) G. C. Cawley, September 2008. 43 | % 44 | % This program is free software; you can redistribute it and/or modify 45 | % it under the terms of the GNU General Public License as published by 46 | % the Free Software Foundation; either version 2 of the License, or 47 | % (at your option) any later version. 48 | % 49 | % This program is distributed in the hope that it will be useful, 50 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 51 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 52 | % GNU General Public License for more details. 53 | % 54 | % You should have received a copy of the GNU General Public License 55 | % along with this program; if not, write to the Free Software 56 | % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 57 | % 58 | ntp = size(y,1); 59 | % sort by classeifier output 60 | [y,idx] = sort(y, 'descend'); 61 | t = t(idx) > 0; 62 | % generate ROC 63 | P = sum(t); 64 | N = ntp - P; 65 | fp = zeros(ntp+2,1); 66 | tp = zeros(ntp+2,1); 67 | FP = 0; 68 | TP = 0; 69 | n = 1; 70 | yprev = -realmax; 71 | for i=1:ntp 72 | if y(i) ~= yprev 73 | tp(n) = TP/P; 74 | fp(n) = FP/N; 75 | yprev = y(i); 76 | n = n + 1; 77 | end 78 | if t(i) == 1 79 | TP = TP + 1; 80 | else 81 | FP = FP + 1; 82 | end 83 | end 84 | tp(n) = 1; 85 | fp(n) = 1; 86 | fp = fp(1:n); 87 | tp = tp(1:n); 88 | % bye bye... 89 | -------------------------------------------------------------------------------- /functions/scale_new.m: -------------------------------------------------------------------------------- 1 | function [data M m] =scale_new(data,M,m) 2 | % 3 | % function data =rescale(data) 4 | % 5 | % This function rescale the input data between 0 and 1 6 | % 7 | % INPUT 8 | % 9 | % data: the data to rescale 10 | % max: the maximum value of the ouput data 11 | % min: the minimum value of the output data 12 | % 13 | % OUTPUT 14 | % 15 | % data: the rescaled data 16 | [Nb_s Nb_b]=size(data); 17 | if nargin==1 18 | M=max(data,[],1); 19 | m=min(data,[],1); 20 | end 21 | 22 | data = (data-repmat(m,Nb_s,1))./(repmat(M-m,Nb_s,1)); 23 | 24 | --------------------------------------------------------------------------------