From 428d6a292a3ec6959273c42d596121b8f8903f7b Mon Sep 17 00:00:00 2001 From: Challen <273239067@qq.com> Date: Wed, 21 Dec 2016 15:15:35 +0800 Subject: [PATCH] GLCM_analysis --- GLCM_analysis/Zhang_feature.m | 22 + GLCM_analysis/codes/codes/AD_ROI.txt | 27 ++ GLCM_analysis/codes/codes/AD_ROI.xlsx | Bin 0 -> 11500 bytes .../codes/codes/AD_T1_JHU_extractROI.m | 11 + GLCM_analysis/codes/codes/Analysis_seg.m | 113 +++++ GLCM_analysis/codes/codes/Excel2Excel.m | 45 ++ GLCM_analysis/codes/codes/ROI.xlsx | Bin 0 -> 12223 bytes GLCM_analysis/codes/codes/ROI_analysis.m | 116 +++++ .../codes/codes/T1_286L_lookup_table.xlsx | Bin 0 -> 32522 bytes GLCM_analysis/codes/codes/all_ave.m | 25 ++ GLCM_analysis/codes/codes/ans_set.mat | Bin 0 -> 306 bytes GLCM_analysis/codes/codes/ave_std.m | 29 ++ GLCM_analysis/codes/codes/contrast_all.m | 25 ++ GLCM_analysis/codes/codes/createExcel.m | 28 ++ GLCM_analysis/codes/codes/create_bi.m | 27 ++ GLCM_analysis/codes/codes/create_feature.m | 50 +++ GLCM_analysis/codes/codes/cropDWI.asv | 17 + GLCM_analysis/codes/codes/cropDWI.m | 17 + GLCM_analysis/codes/codes/f.m | 47 ++ GLCM_analysis/codes/codes/filenmae.txt | Bin 0 -> 219 bytes GLCM_analysis/codes/codes/final_data.m | 18 + .../codes/codes/functions/gaussian1D.m | 8 + GLCM_analysis/codes/codes/functions/plotGMM.m | 136 ++++++ .../codes/codes/functions/weightedAverage.m | 19 + GLCM_analysis/codes/codes/gaussian1D.m | 8 + GLCM_analysis/codes/codes/matlab.mat | Bin 0 -> 257 bytes GLCM_analysis/codes/codes/method.mat | Bin 0 -> 217 bytes GLCM_analysis/codes/codes/num.mat | Bin 0 -> 410 bytes GLCM_analysis/codes/codes/plotGMM.m | 137 ++++++ GLCM_analysis/codes/codes/png_contrast.m | 7 + GLCM_analysis/codes/codes/roi_name.mat | Bin 0 -> 506 bytes GLCM_analysis/codes/codes/selectROI.mat | Bin 0 -> 470 bytes GLCM_analysis/codes/codes/select_feature.mat | Bin 0 -> 257 bytes GLCM_analysis/codes/codes/stat_header.mat | Bin 0 -> 301 bytes GLCM_analysis/codes/codes/tempread.m | 30 ++ GLCM_analysis/codes/codes/txt.mat | Bin 0 -> 214 bytes GLCM_analysis/codes/codes/weightedAverage.m | 19 + GLCM_analysis/codes/codes/write_co.mat | Bin 0 -> 715 bytes .../dtireference/GLCMS description.txt | 59 +++ GLCM_analysis/dtireference/GLCM_Features1.m | 417 +++++++++++++++++ GLCM_analysis/dtireference/GLCM_Features2.m | 368 +++++++++++++++ GLCM_analysis/dtireference/GLCM_Features3.m | 419 ++++++++++++++++++ GLCM_analysis/dtireference/GLCM_Features4.m | 369 +++++++++++++++ GLCM_analysis/dtireference/SVM.m | 23 + .../dtireference/Test_GLCM_Features.html | 257 +++++++++++ .../dtireference/Test_GLCM_Features.m | 90 ++++ .../dtireference/Test_GLCM_Features.png | Bin 0 -> 3670 bytes .../dtireference/Test_GLCM_Features_01.png | Bin 0 -> 8468 bytes .../dtireference/Test_GLCM_Features_02.png | Bin 0 -> 8120 bytes .../Vectorized4VsNonVectorized3.fig | Bin 0 -> 14723 bytes .../Vectorized4VsNonVectorized3.png | Bin 0 -> 7195 bytes GLCM_analysis/dtireference/analysisGLCMans.m | 140 ++++++ GLCM_analysis/dtireference/calculateGLCM.m | 155 +++++++ GLCM_analysis/dtireference/diffStructFields.m | 49 ++ GLCM_analysis/dtireference/finalstat.m | 29 ++ GLCM_analysis/dtireference/graycomatrix3D.m | 340 ++++++++++++++ GLCM_analysis/dtireference/header.mat | Bin 0 -> 348 bytes GLCM_analysis/dtireference/license.txt | 24 + GLCM_analysis/dtireference/method.mat | Bin 0 -> 223 bytes GLCM_analysis/dtireference/stat_ans.m | 58 +++ GLCM_analysis/dtireference/stat_header.mat | Bin 0 -> 344 bytes GLCM_analysis/dtireference/ttest.m | 44 ++ GLCM_analysis/dtireference/txt.mat | Bin 0 -> 212 bytes GLCM_analysis/dtireference/write_co.mat | Bin 0 -> 277 bytes 64 files changed, 3822 insertions(+) create mode 100644 GLCM_analysis/Zhang_feature.m create mode 100644 GLCM_analysis/codes/codes/AD_ROI.txt create mode 100644 GLCM_analysis/codes/codes/AD_ROI.xlsx create mode 100644 GLCM_analysis/codes/codes/AD_T1_JHU_extractROI.m create mode 100644 GLCM_analysis/codes/codes/Analysis_seg.m create mode 100644 GLCM_analysis/codes/codes/Excel2Excel.m create mode 100644 GLCM_analysis/codes/codes/ROI.xlsx create mode 100644 GLCM_analysis/codes/codes/ROI_analysis.m create mode 100644 GLCM_analysis/codes/codes/T1_286L_lookup_table.xlsx create mode 100644 GLCM_analysis/codes/codes/all_ave.m create mode 100644 GLCM_analysis/codes/codes/ans_set.mat create mode 100644 GLCM_analysis/codes/codes/ave_std.m create mode 100644 GLCM_analysis/codes/codes/contrast_all.m create mode 100644 GLCM_analysis/codes/codes/createExcel.m create mode 100644 GLCM_analysis/codes/codes/create_bi.m create mode 100644 GLCM_analysis/codes/codes/create_feature.m create mode 100644 GLCM_analysis/codes/codes/cropDWI.asv create mode 100644 GLCM_analysis/codes/codes/cropDWI.m create mode 100644 GLCM_analysis/codes/codes/f.m create mode 100644 GLCM_analysis/codes/codes/filenmae.txt create mode 100644 GLCM_analysis/codes/codes/final_data.m create mode 100644 GLCM_analysis/codes/codes/functions/gaussian1D.m create mode 100644 GLCM_analysis/codes/codes/functions/plotGMM.m create mode 100644 GLCM_analysis/codes/codes/functions/weightedAverage.m create mode 100644 GLCM_analysis/codes/codes/gaussian1D.m create mode 100644 GLCM_analysis/codes/codes/matlab.mat create mode 100644 GLCM_analysis/codes/codes/method.mat create mode 100644 GLCM_analysis/codes/codes/num.mat create mode 100644 GLCM_analysis/codes/codes/plotGMM.m create mode 100644 GLCM_analysis/codes/codes/png_contrast.m create mode 100644 GLCM_analysis/codes/codes/roi_name.mat create mode 100644 GLCM_analysis/codes/codes/selectROI.mat create mode 100644 GLCM_analysis/codes/codes/select_feature.mat create mode 100644 GLCM_analysis/codes/codes/stat_header.mat create mode 100644 GLCM_analysis/codes/codes/tempread.m create mode 100644 GLCM_analysis/codes/codes/txt.mat create mode 100644 GLCM_analysis/codes/codes/weightedAverage.m create mode 100644 GLCM_analysis/codes/codes/write_co.mat create mode 100644 GLCM_analysis/dtireference/GLCMS description.txt create mode 100644 GLCM_analysis/dtireference/GLCM_Features1.m create mode 100644 GLCM_analysis/dtireference/GLCM_Features2.m create mode 100644 GLCM_analysis/dtireference/GLCM_Features3.m create mode 100644 GLCM_analysis/dtireference/GLCM_Features4.m create mode 100644 GLCM_analysis/dtireference/SVM.m create mode 100644 GLCM_analysis/dtireference/Test_GLCM_Features.html create mode 100644 GLCM_analysis/dtireference/Test_GLCM_Features.m create mode 100644 GLCM_analysis/dtireference/Test_GLCM_Features.png create mode 100644 GLCM_analysis/dtireference/Test_GLCM_Features_01.png create mode 100644 GLCM_analysis/dtireference/Test_GLCM_Features_02.png create mode 100644 GLCM_analysis/dtireference/Vectorized4VsNonVectorized3.fig create mode 100644 GLCM_analysis/dtireference/Vectorized4VsNonVectorized3.png create mode 100644 GLCM_analysis/dtireference/analysisGLCMans.m create mode 100644 GLCM_analysis/dtireference/calculateGLCM.m create mode 100644 GLCM_analysis/dtireference/diffStructFields.m create mode 100644 GLCM_analysis/dtireference/finalstat.m create mode 100644 GLCM_analysis/dtireference/graycomatrix3D.m create mode 100644 GLCM_analysis/dtireference/header.mat create mode 100644 GLCM_analysis/dtireference/license.txt create mode 100644 GLCM_analysis/dtireference/method.mat create mode 100644 GLCM_analysis/dtireference/stat_ans.m create mode 100644 GLCM_analysis/dtireference/stat_header.mat create mode 100644 GLCM_analysis/dtireference/ttest.m create mode 100644 GLCM_analysis/dtireference/txt.mat create mode 100644 GLCM_analysis/dtireference/write_co.mat diff --git a/GLCM_analysis/Zhang_feature.m b/GLCM_analysis/Zhang_feature.m new file mode 100644 index 0000000..265aa01 --- /dev/null +++ b/GLCM_analysis/Zhang_feature.m @@ -0,0 +1,22 @@ +clc;clear all;close all; +load D:\ZCL\课题-纹理特征\codes\codes\select_feature.mat; +load D:\ZCL\课题-纹理特征\codes\codes\selectROI.mat; +load D:\ZCL\课题-纹理特征\codes\codes\method.mat; +path = 'D:\ZCL\课题-纹理特征\graymatrixdata\graymatrixdata\original_excel_data\NC'; +cd(path); +method(4)={'Trace'}; +savemat = zeros(17,231); +savemat(2:17,1)=1:16; +num = 1; +for i = 1:4 + cd(char(method(i))); %进入第i个方法 + for j = 1:23 %23个区域 + for k =1:10 + %savemat(1,k*j+1)=char(select_feature(k)); + savemat(2:17,num+1)=xlsread (char(strcat(roi(j),'.xlsx')),char(strcat(select_feature(k))),'A21:A36'); + num=num+1; + end + end + save savemat + cd (path); %返回目录 +end \ No newline at end of file diff --git a/GLCM_analysis/codes/codes/AD_ROI.txt b/GLCM_analysis/codes/codes/AD_ROI.txt new file mode 100644 index 0000000..eb70bc9 --- /dev/null +++ b/GLCM_analysis/codes/codes/AD_ROI.txt @@ -0,0 +1,27 @@ +Hippocampus 75 76 282 284 +splenium of corpus callosum 127 128 +Genu of corpus callosum left 123 124 +Parietal_R 24 28 30 32 34 +Temporal_L 35 37 39 41 43 +Occipital_L 51 53 55 57 59 +Occipital_R 52 54 56 58 60 +Insula_L 71 +Insula_R 72 +GP_L globus pallidus left 81 +Thalamus_L 83 +Thalamus_R 84 +FrontalLateralVentricle_L 171 +PosteriorLateralVentricle_L 173 174 +InferiorLateralVentricle_R 180 +FrontalLateralVentricle_R 176 +PosteriorLateralVentricle_R 178 179 +PeripheralFrontalWM_L 186 188 190 192 194 196 198 200 202 204 206 210 +PeripheralFrontalWM_R 187 189 191 193 195 197 199 201 203 205 207 211 +PeripheralParietalWM_L 155 208 212 214 216 218 +PeripheralParietalWM_R 156 209 213 215 217 219 +PeripheralTemporalWM_L 220 222 224 226 228 230 +ALIC 131 132 +PLIC 133 134 +Caud 77 78 +Thal 83 84 +Ventrical 171 172 173 174 175 176 177 178 179 180 181 285 286 diff --git a/GLCM_analysis/codes/codes/AD_ROI.xlsx b/GLCM_analysis/codes/codes/AD_ROI.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..85016b25b1cc59466f67d6d64854e8487b29f6e8 GIT binary patch literal 11500 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 & seg<=181|seg==285|seg==286); + +mkdir('D:\JHU_AD\codes\ventricle2'); +cd('D:\JHU_AD\codes\ventricle2'); + +volume=numel(loc); +save volume volume; +mask=zeros(a,b,c); +mask(loc)=1; + + +M_target1=mask.*B0; +B0_data=nonzeros(M_target1); +save B0_data B0_data; + +M_target2=mask.*FA; +FA_data=nonzeros(M_target2); +save FA_data FA_data; + +M_target3=mask.*TRACE; +TRACE_data=nonzeros(M_target3); +save TRACE_data TRACE_data; + +M_target4=mask.*MD; +MD_data=nonzeros(M_target4); +save MD_data MD_data; + +figure(1); +f_B0=plotGMM(B0_data); +title('B0'); +print(1, '-dpng', 'B0'); +save f_B0 f_B0; + + +figure(2); +f_FA=plotGMM(FA_data); +title('FA'); +print(2, '-dpng', 'FA'); +save f_FA f_FA; + +figure(3); +f_TRACE=plotGMM(TRACE_data); +title('TRACE'); +print(3 ,'-dpng', 'TRACE'); +save f_TRACE f_TRACE; + +figure(4); +f_MD=plotGMM(MD_data); +title('MD'); +print(4 ,'-dpng', 'MD'); +save f_MD f_MD; + +movefile(source,destination); + +% MEAN=mean(DATA); +% VAR=var(DATA); + +% result=plotGMM(DATA); + +% DATA_DWI=zeros(volume,slice); +% for i=2:slice +% DATA_DWI(:,i)=nonzeros(mask.*DWI_4D(:,:,:,i)); +% +% M_DWI(i-1)=mean(mean(DATA_DWI(:,i))); +% +% end +% M_DWI=(M_DWI-min(M_DWI))/(max(M_DWI)-min(M_DWI)); +% figure;plot(M_DWI); +% FP=zeros(slice,6); +% for i=2:slice +% DATA_DWI(:,i)=nonzeros(mask.*DWI_4D(:,:,:,i)); +% result=plotGMM(DATA_DWI(:,i)); +% FP(i,:)=[result.mu,result.sigma,result.phi]; +% end +% FP1=FP(2:slice,:); +% FP2=FP1(:); \ No newline at end of file diff --git a/GLCM_analysis/codes/codes/Excel2Excel.m b/GLCM_analysis/codes/codes/Excel2Excel.m new file mode 100644 index 0000000..9fc31c0 --- /dev/null +++ b/GLCM_analysis/codes/codes/Excel2Excel.m @@ -0,0 +1,45 @@ +for i = 1:28; + for j = 1:4; + clc; + clearvars -except i j; + filespath_excel='I:\Data\AD'; + filenames_excel=dir(filespath_excel); + filenames_excel=struct2cell(filenames_excel); + filenames_excel=filenames_excel(1,3:20)'; + %roi_name = raw1; + peoplenum = filenames_excel(1:18,1); + load('I:\Data\codes\roi_name'); + stat_header = load('I:\Data\codes\stat_header'); + method = load('D:\Documents\MatlabCode\dtireference\method'); + write_co = load('I:\Data\codes\write_co'); + + roi_load=char(roi_name(i)); %当前ROI的名称 + destination=cell(28,1); + source = cell(4,1); + + temp = method.method; + source{j,1} = strcat('I:\Data\graymatrixdata\NC\',temp{j,1},'\',roi_load,'.xlsx'); %读取目标excel文件 + destination{i,1}=strcat('I:\Data\graymatrixdata\NC2\',temp{j,1},'\',roi_load,'.xlsx'); + header = stat_header.txt1; + coordinate = write_co.write_co; + xlRange = 'B2:IA19'; + + %ans_Range = 'B2'; + for sheet = 1:22; + aveSheet = sheet+1; + [num,txt,raw] = xlsread(source{j,1},aveSheet,xlRange); + %ans_Range = coordinate{sheet-1,1}; + sheetname = header{sheet}; + xlswrite(destination{i,1},num,sheetname,'B2'); + xlswrite(destination{i,1},peoplenum,aveSheet,'A2'); + for number = 1:18; + peopletemp = nanmean(num(number,:)); + numbertemp = int2str(20+number); + location = strcat('A',numbertemp); + xlswrite(destination{i,1},peopletemp,aveSheet,location); + end + end + + end + system('tskill excel'); +end \ No newline at end of file diff --git a/GLCM_analysis/codes/codes/ROI.xlsx b/GLCM_analysis/codes/codes/ROI.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..159b56a57b7b8827978773ef2f18efa7cce0fb1a GIT binary patch literal 12223 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 Ux+kE00+?X5prFQ(+s{w`2jB*l^Z)<= literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/all_ave.m b/GLCM_analysis/codes/codes/all_ave.m new file mode 100644 index 0000000..60b3996 --- /dev/null +++ b/GLCM_analysis/codes/codes/all_ave.m @@ -0,0 +1,25 @@ +%write the ave & std to the excel +% ans_ave_AD = zeros(28,22); +% ans_ave_NC = zeros(28,22); + +for j = 1:4; + for i = 1:28; + load('G:\Data\codes\roi_name.mat'); + roi_load=char(roi_name(i)); + ans_ave_AD = 0; + ans_ave_NC = 0; + source=strcat('G:\Data\graymatrixdata\Bi_ave\Bi_',roi_load,'.xlsx'); + destination =strcat('G:\Data\graymatrixdata\all_average.xlsx'); + readxlRange = 'B2:W37'; + [num1,txt1,raw1] = xlsread(source,j+1,readxlRange); + for k = 1:22; + ans_ave_AD = mean(num1(1:18,k)); + ans_ave_NC = mean(num1(19:36,k)); + AD_range = strcat(char(k+65),int2str(2*i)); + NC_range = strcat(char(k+65),int2str(2*i+1)); + xlswrite(destination,ans_ave_AD,j,AD_range); + xlswrite(destination,ans_ave_NC,j,NC_range); + end + end + system('tskill excel'); +end \ No newline at end of file diff --git a/GLCM_analysis/codes/codes/ans_set.mat b/GLCM_analysis/codes/codes/ans_set.mat new file mode 100644 index 0000000000000000000000000000000000000000..589ab2acdb0f231fa2b4f4cd4fb60031f81cf573 GIT binary patch literal 306 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSyj5-`93qo*%Fki80sE9NY{a+d3m0T25J zo;g)g^J@5Qf0_kd+x6`N|0Jt#5q67ahOzYj<5tXlc-kFpjUS)&l5-`93qo*%FkR1%f6>}aZCnQ)f9LaGw z!+1o8N8kY0Q*NhBH;uW|W=@_pea37phLm!KjjUD%3bGPRjT0wMG~}4U(73X3V`ppQ c#+?gS&fK}QapA<7E9I>U+}Ig%HIxfTGBU6-wNx-NFf>yj5-`93qo*%FkX;GH6>}aZCnVfBc;vtV zwk4JgGbS=JMNIq=6EKUvqdT}bXtMXC%R$24Ufn^8Nn$)4e{~|hY*w17&G0n+$@6E= zjV7$$Z?RFwwwdYg$)B#SQ*O+k6&^IjzwzIcGmjqmc>UooVMzVQUe&<#cW0+4>y#J% Q3oraN_|MExT&XAt0LQmgiU0rr literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/method.mat b/GLCM_analysis/codes/codes/method.mat new file mode 100644 index 0000000000000000000000000000000000000000..85c3266ea1b9a101ba30f252ca420427e8e0d7c4 GIT binary patch literal 217 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSKO$^wb_%x}7#H@l`pSFQ3QwwJa+o)nvGUg)nUj~F Xzjm5qmnKqshNn;O91nxICEH5?pUFD# literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/num.mat b/GLCM_analysis/codes/codes/num.mat new file mode 100644 index 0000000000000000000000000000000000000000..b704cb70b0a6edf27ab8795202006a17351442f2 GIT binary patch literal 410 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSCRxq%zGBLI?wNx-NFf>yj5-`93qo*%FkS)Z>z)&%#x9_x9lcPl2 z{QWw&u0$PDnKU6o^ybc7)sUtuxlh)GIypV{y&*f}=}KSqw>1W9buRO{bd(5gEv%a= zKl9(wJqE`2ZSLF1UuG@Y;o)Y;F@}KfGhc z;oj-0(>R3{J*QZ(%LpaS_BXqc6j*Zj%mxRB{WETz=U8l#zI~gz#iJSS^L`{vR**9+ zZjan$x;OjyNr}fZp0sZHCF$OLIPXO)R?X|4%AZzS+kx_to4& zzfN;4wwuPa>d%|J@BMsmTp>{PeOGqpktutm^HhbxKfOEQp|bGF-N{ouf=-_Ps4%fs XRsZ~Emnsw0kMVB~t!A=IvC9AeY*L@a literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/plotGMM.m b/GLCM_analysis/codes/codes/plotGMM.m new file mode 100644 index 0000000..9395450 --- /dev/null +++ b/GLCM_analysis/codes/codes/plotGMM.m @@ -0,0 +1,137 @@ +function result = plotGMM(X) +% if mean(X)<1 +% X=X*1000; +% end +% X=round(X); + +%%==================================================== +%% STEP 2: Choose initial values for the parameters. + +% Set 'm' to the number of data points. +m = size(X, 1); + +% Set 'k' to the number of clusters to find. +k = 2; + +% Randomly select k data points to serve as the means. +indeces = randperm(m); +mu = zeros(1, k); +for (i = 1 : k) + mu(i) = X(indeces(i)); +end + +% Use the overal variance of the dataset as the initial variance for each cluster. +sigma = ones(1, k) * sqrt(var(X)); + +% Assign equal prior probabilities to each cluster. +phi = ones(1, k) * (1 / k); + +%%=================================================== +%% STEP 3: Run Expectation Maximization + +% Matrix to hold the probability that each data point belongs to each cluster. +% One row per data point, one column per cluster. +W = zeros(m, k); + +% Loop until convergence. +for (iter = 1:1000) + + fprintf(' EM Iteration %d\n', iter); + + %%=============================================== + %% STEP 3a: Expectation + % + % Calculate the probability for each data point for each distribution. + + % Matrix to hold the pdf value for each every data point for every cluster. + % One row per data point, one column per cluster. + pdf = zeros(m, k); + + % For each cluster... + for (j = 1 : k) + + % Evaluate the Gaussian for all data points for cluster 'j'. + pdf(:, j) = (1 / (sigma(j) * sqrt(2 * pi))) * exp(-(X - mu(j)).^2 ./ (2 * sigma(j)^2)); + + end + + % Multiply each pdf value by the prior probability for each cluster. + % pdf [m x k] + % phi [1 x k] + % pdf_w [m x k] + pdf_w = bsxfun(@times, pdf, phi); + + % Divide the weighted probabilities by the sum of weighted probabilities for each cluster. + % sum(pdf_w, 2) -- sum over the clusters. + W = bsxfun(@rdivide, pdf_w, sum(pdf_w, 2)); + + %%=============================================== + %% STEP 3b: Maximization + %% + %% Calculate the probability for each data point for each distribution. + + % Store the previous means so we can check for convergence. + prevMu = mu; + + % For each of the clusters... + for (j = 1 : k) + + % Calculate the prior probability for cluster 'j'. + phi(j) = mean(W(:, j)); + + % Calculate the new mean for cluster 'j' by taking the weighted + % average of *all* data points. + mu(j) = weightedAverage(W(:, j), X); + + % Calculate the variance for cluster 'j' by taking the weighted + % average of the squared differences from the mean for all data + % points. + variance = weightedAverage(W(:, j), (X - mu(j)).^2); + + % Calculate sigma by taking the square root of the variance. + sigma(j) = sqrt(variance); + end + + % Check for convergence. + % Comparing floating point values for equality is generally a bad idea, but + % it seems to be working fine. + if (mu == prevMu) + break + end + +% End of Expectation Maximization loop. +end + +%%===================================================== +%% STEP 4: Plot the data points and their estimated pdfs. + + %x1 = [min(X):(max(X)-min(X))/100:max(X)-(max(X)-min(X))/100]; + x1=X; + x2= [0:1/100:1-1/100]; + y1 = gaussian1D(x1, mu(1), sigma(1)); + y2 = gaussian1D(x1, mu(2), sigma(2)); + %y3 = gaussian1D(x1, mu(3), sigma(3)); + %y4 = gaussian1D(x1, mu(4), sigma(4)); +% y= y1*phi(1)+y2*phi(2)+y3*phi(3)+y4*phi(4); +y= y1*phi(1)+y2*phi(2); + + + + % plot(X,zeros(size(X)), 'bx', 'markersize', 10); +hold on + temp=hist(X,100); + bar(x2,temp); + ratio=sum(temp)/sum(y); +% filled=area(x2,ratio*y); +% set(filled,'FaceColor',[1 0 0]) + + plot(x2, ratio*y1*phi(1), 'r-','LineWidth',4); + plot(x2, ratio*y2*phi(2), 'r-','LineWidth',4); + %plot(x2, ratio*y3*phi(3), 'r-','LineWidth',4); + %plot(x2, ratio*y4*phi(4), 'r-','LineWidth',4); + +result={'mu','sigma','phi'}; +result.mu=mu; +result.sigma=sigma; +result.phi=phi; +end diff --git a/GLCM_analysis/codes/codes/png_contrast.m b/GLCM_analysis/codes/codes/png_contrast.m new file mode 100644 index 0000000..f86e145 --- /dev/null +++ b/GLCM_analysis/codes/codes/png_contrast.m @@ -0,0 +1,7 @@ + clc; + clear; + + + filespath='D:\JHU_AD\analysis\'; + filenames=dir(filespath); + filenames=struct2cell(filenames); \ No newline at end of file diff --git a/GLCM_analysis/codes/codes/roi_name.mat b/GLCM_analysis/codes/codes/roi_name.mat new file mode 100644 index 0000000000000000000000000000000000000000..5da87d8b9984b5b53bfad01477196aef2f3d0c76 GIT binary patch literal 506 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSCQZO{IGBva^v`{cIFf>yj5-`93qo*%FkX^*cz)&$~>lNSZLk1G; zA3E}O@TN?+{8scqx#CXYVgpetp41$7&e$Ukvs$+N{C9fs##MZ=AQ|Fe_X$5Ex+*n!-K^N`?EFQmB-Jj)OnU~MwmW&Qr>ri6+|6j!VH=28w zEHwYJC-La*vQ1}M{9maq|FBKA$b7%^?}O1c-M6khoK`AmXrKFPLAuFH^YD9Bj%ClM X6`0?9^7C%jWmk)?3;N$@ZCL;S$^Yci literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/selectROI.mat b/GLCM_analysis/codes/codes/selectROI.mat new file mode 100644 index 0000000000000000000000000000000000000000..f85fbeef5f1dacde380734e52d425354213865db GIT binary patch literal 470 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSSQtR4_EOGBN=o1tSAPGX)|60}L>F`tk$WevAwZ6?3*ux#)G+K&0(_ z#?*xddx}<=SF`Bv4dKdb?ONCo*B4+c<}rJM$@?eCvo>GN>uoJtJ5B6Y`yct|e=Ohf zFzh?Wc!xLmyH7&>+|a7HwY~}rx|V0|{8pCv)_$+ePZYP z2Q9pQ9D-ZtJJ;k#YhCz$;o)qj&3RV}6W1(wowCGUcGm6eX@y63rQ4{>o=n_1X;)wRg&14aLX#uzRll0r^cjR)cUyV3zrXfcyfh|f##E-EsS1!*jX0RQZ^CR>wXMJRh)aq(NzK0gb&b`I z;{NWclU%oty$OEad))c&n$(BO{)gvWz46D=+_v%dH0_DYa_nC`nZKj`zti=~*y@-o hM;xz;b+%-ki&2r+?~pnF`{yCq^IQM%ww>t@1^^~{#<>6h literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/select_feature.mat b/GLCM_analysis/codes/codes/select_feature.mat new file mode 100644 index 0000000000000000000000000000000000000000..bfa59a08fc7f48624a89faaa00d5320088040a7b GIT binary patch literal 257 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSfTGBUI>FjFuxFf>yj5-`93qo*%FkX;GH6>}aZCnVfBc;vtV zwk4JgGbS=JMNIq=6EKUvqdT}bXtMXC%R$24Ufn^8Nn$)4e{~|hY*w17&G0n+$@6E= zjV7$$Z?RFwwwdYg$)B#SQ*O+k6&^IjzwzIcGmjqmc>UooVMzVQUe&<#cW0+4>y#J% Q3oraN_|MExT&XAt0K%A6g8%>k literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/stat_header.mat b/GLCM_analysis/codes/codes/stat_header.mat new file mode 100644 index 0000000000000000000000000000000000000000..e11521d7b29d52647258b20b44b2a55bbeca8bf3 GIT binary patch literal 301 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSCR4_2MGBC0-HBc}zFf>yj5-`93qo*%Fki8U$E9NY{a**q=0uS2* zo>w3sj1`LB2H>)x2}Et-aI&F?w350+cJ zQ literal 0 HcmV?d00001 diff --git a/GLCM_analysis/codes/codes/tempread.m b/GLCM_analysis/codes/codes/tempread.m new file mode 100644 index 0000000..d0970a4 --- /dev/null +++ b/GLCM_analysis/codes/codes/tempread.m @@ -0,0 +1,30 @@ +%从excel读入所有ROI对应区域的位置 +clc;clear; +source1=strcat('I:\Data\test.xlsx'); +readxlRange = 'A1:M28'; +[num1,txt1,raw1] = xlsread(source1,readxlRange); +num = num1; +save num num1 + +% 从excel读入所有ROI的名称 +% clc;clear; +% source1=strcat('I:\Data\test.xlsx'); +% readxlRange = 'N1:N28'; +% [num1,txt1,raw1] = xlsread(source1,readxlRange); +% roi_name = raw1; +% save roi_name roi_name + +%从excel中读取要写入Ans_开头的excel的位置 +% clc;clear; +% source1=strcat('I:\Data\test.xlsx'); +% readxlRange = 'B32:W32'; +% [num1,txt1,raw1] = xlsread(source1,readxlRange); +% write_co = txt1; +% save write_co write_co; + +%从excel中读取要写入Bi_开头的excel的位置18个AD18个NC +% clc;clear; +% source1=strcat('I:\Data\test.xlsx'); +% readxlRange = 'X1:X36'; +% [num,txt,raw] = xlsread(source1,readxlRange); +% save txt txt; \ No newline at end of file diff --git a/GLCM_analysis/codes/codes/txt.mat b/GLCM_analysis/codes/codes/txt.mat new file mode 100644 index 0000000000000000000000000000000000000000..213bedb81ef4e95d9a670115979cc23006f897a9 GIT binary patch literal 214 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSCQZO{MGBmIyj5-`93qo*%FknIP=6>}aZCnP+0kdTnT ze9_^|2?oYB0sFW@dL}l`T)1RWOC$dYvjm3~>5jqtL8n_%`WPlWe{slQRes3*75fAi Uoj+d*Vg%MY2g)CQZO{IGO@HWFjO!yFf>yj5-`93qo*%FkZljd6>}aZCnRt%B$+8Z zV@MKX<49=zB-t1t;I)~#u&^#OuxOQHGegLo%UZ`&H>wyeQ`x%1Wxdk!9Zaj_8Gg%g zz6BX$2{+~gnlUqEy^5I&1GAF6T>S!);;OVF<}!rbJ9*=T)}0$2j0{WfvaJRgpaM6* z0Bk_RC4~cAPY*LFGjlt~Wv){cp2E+dRK@rLq_z&McJ3K#zNQ3$){ELdRYO`%m2!A9 zJXyGi$2a31Rd=oGec8Lc zXXl>?n&ojM^}^E&u?w^pXfIs7VD-Y?PUX$-_+pvwGVf9^(SH&3!sC3OP$OOVVE$y(oIY^}_3g z-i6qOyB)(F%iGtrt!sS87|R{Yeph&xcuD>XyJv3vKg8=n&S-)y>9bk*sd{LXQjVfo$I;&+$R|M12B z-}cq+^s^rOcRPMR&-kpTbmS+{Ztex#3%eI|FZ5pEz3}vc(;&Avl()ZQ1iL}CM6|@T OgtuhvF8N$xiCh5L4-@_X literal 0 HcmV?d00001 diff --git a/GLCM_analysis/dtireference/GLCMS description.txt b/GLCM_analysis/dtireference/GLCMS description.txt new file mode 100644 index 0000000..991f12e --- /dev/null +++ b/GLCM_analysis/dtireference/GLCMS description.txt @@ -0,0 +1,59 @@ +Description +The GLCMs are stored in a i x j x n matrix, where n is the number of GLCMs calculated usually due to the different orientation and displacements used in the algorithm. Usually the values i and j are equal to 'NumLevels' parameter of the GLCM computing function graycomatrix(). Note that matlab quantization values belong to the set {1,..., NumLevels} and not from {0,...,(NumLevels-1)} as provided in some references +http://www.mathworks.com/help/images/ref/graycomatrix.html + +Although there is a function graycoprops() in Matlab Image Processing Toolbox that computes four parameters Contrast, Correlation, Energy, and Homogeneity. The paper by Haralick suggests a few more parameters that are also computed here. The code is not vectorized and hence is not an efficient implementation but it is easy to add new features based on the GLCM using this code. The code takes care of 3 dimensional glcms (multiple glcms in a single 3D array) + +If you find that the values obtained are different from what you expect or if you think there is a different formula that needs to be used from the ones used in this code please let me know. A few questions which I have are listed in the link http://www.mathworks.com/matlabcentral/newsreader/view_thread/239608 + +I plan to submit a vectorized version of the code later and provide updates based on replies to the above link and this initial code. + +% Features computed +% Autocorrelation: [2] (out.autoc) +% Contrast: matlab/[1,2] (out.contr) +% Correlation: matlab (out.corrm) +% Correlation: [1,2] (out.corrp) +% Cluster Prominence: [2] (out.cprom) +% Cluster Shade: [2] (out.cshad) +% Dissimilarity: [2] (out.dissi) +% Energy: matlab / [1,2] (out.energ) +% Entropy: [2] (out.entro) +% Homogeneity: matlab (out.homom) +% Homogeneity: [2] (out.homop) +% Maximum probability: [2] (out.maxpr) +% Sum of sqaures: Variance [1] (out.sosvh) +% Sum average [1] (out.savgh) +% Sum variance [1] (out.svarh) +% Sum entropy [1] (out.senth) +% Difference variance [1] (out.dvarh) +% Difference entropy [1] (out.denth) +% Information measure of correlation1 [1] (out.inf1h) +% Informaiton measure of correlation2 [1] (out.inf2h) +% Inverse difference (INV) is homom [3] (out.homom) +% Inverse difference normalized (INN) [3] (out.indnc) +% Inverse difference moment normalized [3](out.idmnc) + +Haralick uses 'Symmetric' = true in computing the glcm. There is no Symmetric flag in the Matlab version I use hence I add the diagonally opposite pairs to obtain the Haralick glcm. Here it is assumed that the diagonally opposite orientations are paired one after the other in the matrix. If the above assumption is true with respect to the input glcm then setting the flag 'pairs' to 1 will compute the final glcms that would result by setting 'Symmetric' to true. If your glcm is computed using the +Matlab version with 'Symmetric' flag you can set the flag 'pairs' to 0 + +% References: +1. R. M. Haralick, K. Shanmugam, and I. Dinstein, Textural Features of Image Classification, IEEE Transactions on Systems, Man and Cybernetics, vol. SMC-3, no. 6, Nov. 1973 +2. L. Soh and C. Tsatsoulis, Texture Analysis of SAR Sea Ice Imagery Using Gray Level Co-Occurrence Matrices, IEEE Transactions on Geoscience and Remote Sensing, vol. 37, no. 2, March 1999. +3. D A. Clausi, An analysis of co-occurrence texture statistics as a +function of grey level quantization, Can. J. Remote Sensing, vol. 28, no.1, pp. 45-62, 2002 +4. http://murphylab.web.cmu.edu/publications/boland/boland_node26.html + +% Example: +% Usage is similar to graycoprops() but needs extra parameter 'pairs' apart from the GLCM as input + +>I = imread('circuit.tif'); +>GLCM2 = graycomatrix(I,'Offset',[2 0;0 2]); +>stats = GLCM_features1(GLCM2,0) + +The output is a structure containing all the features calculated from the different GLCMs + +Acknowledgements +This file inspired Glcm Features(Glcm). + +Required Products Image Processing Toolbox +MATLAB release MATLAB 7.0.1 (R14SP1) \ No newline at end of file diff --git a/GLCM_analysis/dtireference/GLCM_Features1.m b/GLCM_analysis/dtireference/GLCM_Features1.m new file mode 100644 index 0000000..ae5a411 --- /dev/null +++ b/GLCM_analysis/dtireference/GLCM_Features1.m @@ -0,0 +1,417 @@ +function [out] = GLCM_Features1(glcmin,pairs) +% +% GLCM_Features1 helps to calculate the features from the different GLCMs +% that are input to the function. The GLCMs are stored in a i x j x n +% matrix, where n is the number of GLCMs calculated usually due to the +% different orientation and displacements used in the algorithm. Usually +% the values i and j are equal to 'NumLevels' parameter of the GLCM +% computing function graycomatrix(). Note that matlab quantization values +% belong to the set {1,..., NumLevels} and not from {0,...,(NumLevels-1)} +% as provided in some references +% http://www.mathworks.com/access/helpdesk/help/toolbox/images/graycomatrix +% .html +% +% Although there is a function graycoprops() in Matlab Image Processing +% Toolbox that computes four parameters Contrast, Correlation, Energy, +% and Homogeneity. The paper by Haralick suggests a few more parameters +% that are also computed here. The code is not fully vectorized and hence +% is not an efficient implementation but it is easy to add new features +% based on the GLCM using this code. Takes care of 3 dimensional glcms +% (multiple glcms in a single 3D array) +% +% If you find that the values obtained are different from what you expect +% or if you think there is a different formula that needs to be used +% from the ones used in this code please let me know. +% A few questions which I have are listed in the link +% http://www.mathworks.com/matlabcentral/newsreader/view_thread/239608 +% +% I plan to submit a vectorized version of the code later and provide +% updates based on replies to the above link and this initial code. +% +% Features computed +% Autocorrelation: [2] (out.autoc) +% Contrast: matlab/[1,2] (out.contr) +% Correlation: matlab (out.corrm) +% Correlation: [1,2] (out.corrp) +% Cluster Prominence: [2] (out.cprom) +% Cluster Shade: [2] (out.cshad) +% Dissimilarity: [2] (out.dissi) +% Energy: matlab / [1,2] (out.energ) +% Entropy: [2] (out.entro) +% Homogeneity: matlab (out.homom) +% Homogeneity: [2] (out.homop) +% Maximum probability: [2] (out.maxpr) +% Sum of sqaures: Variance [1] (out.sosvh) +% Sum average [1] (out.savgh) +% Sum variance [1] (out.svarh) +% Sum entropy [1] (out.senth) +% Difference variance [1] (out.dvarh) +% Difference entropy [1] (out.denth) +% Information measure of correlation1 [1] (out.inf1h) +% Informaiton measure of correlation2 [1] (out.inf2h) +% Inverse difference (INV) is homom [3] (out.homom) +% Inverse difference normalized (INN) [3] (out.indnc) +% Inverse difference moment normalized [3] (out.idmnc) +% +% The maximal correlation coefficient was not calculated due to +% computational instability +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% Formulae from MATLAB site (some look different from +% the paper by Haralick but are equivalent and give same results) +% Example formulae: +% Contrast = sum_i(sum_j( (i-j)^2 * p(i,j) ) ) (same in matlab/paper) +% Correlation = sum_i( sum_j( (i - u_i)(j - u_j)p(i,j)/(s_i.s_j) ) ) (m) +% Correlation = sum_i( sum_j( ((ij)p(i,j) - u_x.u_y) / (s_x.s_y) ) ) (p[2]) +% Energy = sum_i( sum_j( p(i,j)^2 ) ) (same in matlab/paper) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + |i-j|) ) ) (as in matlab) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + (i-j)^2) ) ) (as in paper) +% +% Where: +% u_i = u_x = sum_i( sum_j( i.p(i,j) ) ) (in paper [2]) +% u_j = u_y = sum_i( sum_j( j.p(i,j) ) ) (in paper [2]) +% s_i = s_x = sum_i( sum_j( (i - u_x)^2.p(i,j) ) ) (in paper [2]) +% s_j = s_y = sum_i( sum_j( (j - u_y)^2.p(i,j) ) ) (in paper [2]) +% +% +% Normalize the glcm: +% Compute the sum of all the values in each glcm in the array and divide +% each element by it sum +% +% Haralick uses 'Symmetric' = true in computing the glcm +% There is no Symmetric flag in the Matlab version I use hence +% I add the diagonally opposite pairs to obtain the Haralick glcm +% Here it is assumed that the diagonally opposite orientations are paired +% one after the other in the matrix +% If the above assumption is true with respect to the input glcm then +% setting the flag 'pairs' to 1 will compute the final glcms that would result +% by setting 'Symmetric' to true. If your glcm is computed using the +% Matlab version with 'Symmetric' flag you can set the flag 'pairs' to 0 +% +% References: +% 1. R. M. Haralick, K. Shanmugam, and I. Dinstein, Textural Features of +% Image Classification, IEEE Transactions on Systems, Man and Cybernetics, +% vol. SMC-3, no. 6, Nov. 1973 +% 2. L. Soh and C. Tsatsoulis, Texture Analysis of SAR Sea Ice Imagery +% Using Gray Level Co-Occurrence Matrices, IEEE Transactions on Geoscience +% and Remote Sensing, vol. 37, no. 2, March 1999. +% 3. D A. Clausi, An analysis of co-occurrence texture statistics as a +% function of grey level quantization, Can. J. Remote Sensing, vol. 28, no. +% 1, pp. 45-62, 2002 +% 4. http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% +% Example: +% +% Usage is similar to graycoprops() but needs extra parameter 'pairs' apart +% from the GLCM as input +% I = imread('circuit.tif'); +% GLCM2 = graycomatrix(I,'Offset',[2 0;0 2]); +% stats = GLCM_features1(GLCM2,0) +% The output is a structure containing all the parameters for the different +% GLCMs +% +% [Avinash Uppuluri: avinash_uv@yahoo.com: Last modified: 11/20/08] + +% If 'pairs' not entered: set pairs to 0 +if ((nargin > 2) || (nargin == 0)) + error('Too many or too few input arguments. Enter GLCM and pairs.'); +elseif ( (nargin == 2) ) + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +elseif (nargin == 1) % only GLCM is entered + pairs = 0; % default is numbers and input 1 for percentage + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +end + + +format long e +if (pairs == 1) + newn = 1; + for nglcm = 1:2:size(glcmin,3) + glcm(:,:,newn) = glcmin(:,:,nglcm) + glcmin(:,:,nglcm+1); + newn = newn + 1; + end +elseif (pairs == 0) + glcm = glcmin; +end + +size_glcm_1 = size(glcm,1); +size_glcm_2 = size(glcm,2); +size_glcm_3 = size(glcm,3); + +% checked +out.autoc = zeros(1,size_glcm_3); % Autocorrelation: [2] +out.contr = zeros(1,size_glcm_3); % Contrast: matlab/[1,2] +out.corrm = zeros(1,size_glcm_3); % Correlation: matlab +out.corrp = zeros(1,size_glcm_3); % Correlation: [1,2] +out.cprom = zeros(1,size_glcm_3); % Cluster Prominence: [2] +out.cshad = zeros(1,size_glcm_3); % Cluster Shade: [2] +out.dissi = zeros(1,size_glcm_3); % Dissimilarity: [2] +out.energ = zeros(1,size_glcm_3); % Energy: matlab / [1,2] +out.entro = zeros(1,size_glcm_3); % Entropy: [2] +out.homom = zeros(1,size_glcm_3); % Homogeneity: matlab +out.homop = zeros(1,size_glcm_3); % Homogeneity: [2] +out.maxpr = zeros(1,size_glcm_3); % Maximum probability: [2] + +out.sosvh = zeros(1,size_glcm_3); % Sum of sqaures: Variance [1] +out.savgh = zeros(1,size_glcm_3); % Sum average [1] +out.svarh = zeros(1,size_glcm_3); % Sum variance [1] +out.senth = zeros(1,size_glcm_3); % Sum entropy [1] +out.dvarh = zeros(1,size_glcm_3); % Difference variance [4] +%out.dvarh2 = zeros(1,size_glcm_3); % Difference variance [1] +out.denth = zeros(1,size_glcm_3); % Difference entropy [1] +out.inf1h = zeros(1,size_glcm_3); % Information measure of correlation1 [1] +out.inf2h = zeros(1,size_glcm_3); % Informaiton measure of correlation2 [1] +%out.mxcch = zeros(1,size_glcm_3);% maximal correlation coefficient [1] +%out.invdc = zeros(1,size_glcm_3);% Inverse difference (INV) is homom [3] +out.indnc = zeros(1,size_glcm_3); % Inverse difference normalized (INN) [3] +out.idmnc = zeros(1,size_glcm_3); % Inverse difference moment normalized [3] + +% correlation with alternate definition of u and s +%out.corrm2 = zeros(1,size_glcm_3); % Correlation: matlab +%out.corrp2 = zeros(1,size_glcm_3); % Correlation: [1,2] + +glcm_sum = zeros(size_glcm_3,1); +glcm_mean = zeros(size_glcm_3,1); +glcm_var = zeros(size_glcm_3,1); + +% http://www.fp.ucalgary.ca/mhallbey/glcm_mean.htm confuses the range of +% i and j used in calculating the means and standard deviations. +% As of now I am not sure if the range of i and j should be [1:Ng] or +% [0:Ng-1]. I am working on obtaining the values of mean and std that get +% the values of correlation that are provided by matlab. +u_x = zeros(size_glcm_3,1); +u_y = zeros(size_glcm_3,1); +s_x = zeros(size_glcm_3,1); +s_y = zeros(size_glcm_3,1); + +% % alternate values of u and s +% u_x2 = zeros(size_glcm_3,1); +% u_y2 = zeros(size_glcm_3,1); +% s_x2 = zeros(size_glcm_3,1); +% s_y2 = zeros(size_glcm_3,1); + +% checked p_x p_y p_xplusy p_xminusy +p_x = zeros(size_glcm_1,size_glcm_3); % Ng x #glcms[1] +p_y = zeros(size_glcm_2,size_glcm_3); % Ng x #glcms[1] +p_xplusy = zeros((size_glcm_1*2 - 1),size_glcm_3); %[1] +p_xminusy = zeros((size_glcm_1),size_glcm_3); %[1] +% checked hxy hxy1 hxy2 hx hy +hxy = zeros(size_glcm_3,1); +hxy1 = zeros(size_glcm_3,1); +hx = zeros(size_glcm_3,1); +hy = zeros(size_glcm_3,1); +hxy2 = zeros(size_glcm_3,1); + +%Q = zeros(size(glcm)); + +for k = 1:size_glcm_3 % number glcms + + glcm_sum(k) = sum(sum(glcm(:,:,k))); + glcm(:,:,k) = glcm(:,:,k)./glcm_sum(k); % Normalize each glcm + glcm_mean(k) = mean2(glcm(:,:,k)); % compute mean after norm + glcm_var(k) = (std2(glcm(:,:,k)))^2; + + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + + out.contr(k) = out.contr(k) + (abs(i - j))^2.*glcm(i,j,k); + out.dissi(k) = out.dissi(k) + (abs(i - j)*glcm(i,j,k)); + out.energ(k) = out.energ(k) + (glcm(i,j,k).^2); + out.entro(k) = out.entro(k) - (glcm(i,j,k)*log(glcm(i,j,k) + eps)); + out.homom(k) = out.homom(k) + (glcm(i,j,k)/( 1 + abs(i-j) )); + out.homop(k) = out.homop(k) + (glcm(i,j,k)/( 1 + (i - j)^2)); + % [1] explains sum of squares variance with a mean value; + % the exact definition for mean has not been provided in + % the reference: I use the mean of the entire normalized glcm + out.sosvh(k) = out.sosvh(k) + glcm(i,j,k)*((i - glcm_mean(k))^2); + + %out.invdc(k) = out.homom(k); + out.indnc(k) = out.indnc(k) + (glcm(i,j,k)/( 1 + (abs(i-j)/size_glcm_1) )); + out.idmnc(k) = out.idmnc(k) + (glcm(i,j,k)/( 1 + ((i - j)/size_glcm_1)^2)); + u_x(k) = u_x(k) + (i)*glcm(i,j,k); % changed 10/26/08 + u_y(k) = u_y(k) + (j)*glcm(i,j,k); % changed 10/26/08 + % code requires that Nx = Ny + % the values of the grey levels range from 1 to (Ng) + end + + end + out.maxpr(k) = max(max(glcm(:,:,k))); +end +% glcms have been normalized: +% The contrast has been computed for each glcm in the 3D matrix +% (tested) gives similar results to the matlab function + +for k = 1:size_glcm_3 + + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + p_x(i,k) = p_x(i,k) + glcm(i,j,k); + p_y(i,k) = p_y(i,k) + glcm(j,i,k); % taking i for j and j for i + if (ismember((i + j),[2:2*size_glcm_1])) + p_xplusy((i+j)-1,k) = p_xplusy((i+j)-1,k) + glcm(i,j,k); + end + if (ismember(abs(i-j),[0:(size_glcm_1-1)])) + p_xminusy((abs(i-j))+1,k) = p_xminusy((abs(i-j))+1,k) +... + glcm(i,j,k); + end + end + end + +% % consider u_x and u_y and s_x and s_y as means and standard deviations +% % of p_x and p_y +% u_x2(k) = mean(p_x(:,k)); +% u_y2(k) = mean(p_y(:,k)); +% s_x2(k) = std(p_x(:,k)); +% s_y2(k) = std(p_y(:,k)); + +end + +% marginal probabilities are now available [1] +% p_xminusy has +1 in index for matlab (no 0 index) +% computing sum average, sum variance and sum entropy: +for k = 1:(size_glcm_3) + + for i = 1:(2*(size_glcm_1)-1) + out.savgh(k) = out.savgh(k) + (i+1)*p_xplusy(i,k); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + out.senth(k) = out.senth(k) - (p_xplusy(i,k)*log(p_xplusy(i,k) + eps)); + end + +end +% compute sum variance with the help of sum entropy +for k = 1:(size_glcm_3) + + for i = 1:(2*(size_glcm_1)-1) + out.svarh(k) = out.svarh(k) + (((i+1) - out.senth(k))^2)*p_xplusy(i,k); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + end + +end +% compute difference variance, difference entropy, +for k = 1:size_glcm_3 +% out.dvarh2(k) = var(p_xminusy(:,k)); +% but using the formula in +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% we have for dvarh + for i = 0:(size_glcm_1-1) + out.denth(k) = out.denth(k) - (p_xminusy(i+1,k)*log(p_xminusy(i+1,k) + eps)); + out.dvarh(k) = out.dvarh(k) + (i^2)*p_xminusy(i+1,k); + end +end + +% compute information measure of correlation(1,2) [1] +for k = 1:size_glcm_3 + hxy(k) = out.entro(k); + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + hxy1(k) = hxy1(k) - (glcm(i,j,k)*log(p_x(i,k)*p_y(j,k) + eps)); + hxy2(k) = hxy2(k) - (p_x(i,k)*p_y(j,k)*log(p_x(i,k)*p_y(j,k) + eps)); +% for Qind = 1:(size_glcm_1) +% Q(i,j,k) = Q(i,j,k) +... +% ( glcm(i,Qind,k)*glcm(j,Qind,k) / (p_x(i,k)*p_y(Qind,k)) ); +% end + end + hx(k) = hx(k) - (p_x(i,k)*log(p_x(i,k) + eps)); + hy(k) = hy(k) - (p_y(i,k)*log(p_y(i,k) + eps)); + end + out.inf1h(k) = ( hxy(k) - hxy1(k) ) / ( max([hx(k),hy(k)]) ); + out.inf2h(k) = ( 1 - exp( -2*( hxy2(k) - hxy(k) ) ) )^0.5; +% eig_Q(k,:) = eig(Q(:,:,k)); +% sort_eig(k,:)= sort(eig_Q(k,:),'descend'); +% out.mxcch(k) = sort_eig(k,2)^0.5; +% The maximal correlation coefficient was not calculated due to +% computational instability +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +end + +corm = zeros(size_glcm_3,1); +corp = zeros(size_glcm_3,1); +% using http://www.fp.ucalgary.ca/mhallbey/glcm_variance.htm for s_x s_y +for k = 1:size_glcm_3 + for i = 1:size_glcm_1 + for j = 1:size_glcm_2 + s_x(k) = s_x(k) + (((i) - u_x(k))^2)*glcm(i,j,k); + s_y(k) = s_y(k) + (((j) - u_y(k))^2)*glcm(i,j,k); + corp(k) = corp(k) + ((i)*(j)*glcm(i,j,k)); + corm(k) = corm(k) + (((i) - u_x(k))*((j) - u_y(k))*glcm(i,j,k)); + out.cprom(k) = out.cprom(k) + (((i + j - u_x(k) - u_y(k))^4)*... + glcm(i,j,k)); + out.cshad(k) = out.cshad(k) + (((i + j - u_x(k) - u_y(k))^3)*... + glcm(i,j,k)); + end + end + % using http://www.fp.ucalgary.ca/mhallbey/glcm_variance.htm for s_x + % s_y : This solves the difference in value of correlation and might be + % the right value of standard deviations required + % According to this website there is a typo in [2] which provides + % values of variance instead of the standard deviation hence a square + % root is required as done below: + s_x(k) = s_x(k) ^ 0.5; + s_y(k) = s_y(k) ^ 0.5; + out.autoc(k) = corp(k); + out.corrp(k) = (corp(k) - u_x(k)*u_y(k))/(s_x(k)*s_y(k)); + out.corrm(k) = corm(k) / (s_x(k)*s_y(k)); +% % alternate values of u and s +% out.corrp2(k) = (corp(k) - u_x2(k)*u_y2(k))/(s_x2(k)*s_y2(k)); +% out.corrm2(k) = corm(k) / (s_x2(k)*s_y2(k)); +end +% Here the formula in the paper out.corrp and the formula in matlab +% out.corrm are equivalent as confirmed by the similar results obtained + +% % The papers have a slightly different formular for Contrast +% % I have tested here to find this formula in the papers provides the +% % same results as the formula provided by the matlab function for +% % Contrast (Hence this part has been commented) +% out.contrp = zeros(size_glcm_3,1); +% contp = 0; +% Ng = size_glcm_1; +% for k = 1:size_glcm_3 +% for n = 0:(Ng-1) +% for i = 1:Ng +% for j = 1:Ng +% if (abs(i-j) == n) +% contp = contp + glcm(i,j,k); +% end +% end +% end +% out.contrp(k) = out.contrp(k) + n^2*contp; +% contp = 0; +% end +% +% end + +% GLCM Features (Soh, 1999; Haralick, 1973; Clausi 2002) +% f1. Uniformity / Energy / Angular Second Moment (done) +% f2. Entropy (done) +% f3. Dissimilarity (done) +% f4. Contrast / Inertia (done) +% f5. Inverse difference +% f6. correlation +% f7. Homogeneity / Inverse difference moment +% f8. Autocorrelation +% f9. Cluster Shade +% f10. Cluster Prominence +% f11. Maximum probability +% f12. Sum of Squares +% f13. Sum Average +% f14. Sum Variance +% f15. Sum Entropy +% f16. Difference variance +% f17. Difference entropy +% f18. Information measures of correlation (1) +% f19. Information measures of correlation (2) +% f20. Maximal correlation coefficient +% f21. Inverse difference normalized (INN) +% f22. Inverse difference moment normalized (IDN) diff --git a/GLCM_analysis/dtireference/GLCM_Features2.m b/GLCM_analysis/dtireference/GLCM_Features2.m new file mode 100644 index 0000000..2fa5b54 --- /dev/null +++ b/GLCM_analysis/dtireference/GLCM_Features2.m @@ -0,0 +1,368 @@ +function [out] = GLCM_Features2(glcmin,pairs) +% +% GLCM_Features2 helps to calculate the features from the different GLCMs +% that are input to the function. The GLCMs are stored in a i x j x n +% matrix, where n is the number of GLCMs calculated usually due to the +% different orientation and displacements used in the algorithm. Usually +% the values i and j are equal to 'NumLevels' parameter of the GLCM +% computing function graycomatrix(). Note that matlab quantization values +% belong to the set {1,..., NumLevels} and not from {0,...,(NumLevels-1)} +% as provided in some references +% http://www.mathworks.com/access/helpdesk/help/toolbox/images/graycomatrix +% .html +% +% This vectorized version of GLCM_FEatures1.m reduces the 19 'for' loops +% used in the earlier code to 5 'for' loops +% http://blogs.mathworks.com/loren/2006/07/12/what-are-you-really-measuring +% / +% Using tic toc and cputime as in above discussion I find no significant +% improvement even after reducing all the loops. If anyone can figure out +% why, please let me know. Thanks! +% +% Although there is a function graycoprops() in Matlab Image Processing +% Toolbox that computes four parameters Contrast, Correlation, Energy, +% and Homogeneity. The paper by Haralick suggests a few more parameters +% that are also computed here. The code is not fully vectorized and hence +% is not an efficient implementation but it is easy to add new features +% based on the GLCM using this code. Takes care of 3 dimensional glcms +% (multiple glcms in a single 3D array) +% +% If you find that the values obtained are different from what you expect +% or if you think there is a different formula that needs to be used +% from the ones used in this code please let me know. +% A few questions which I have are listed in the link +% http://www.mathworks.com/matlabcentral/newsreader/view_thread/239608 +% +% +% +% Features computed +% Autocorrelation: [2] (out.autoc) +% Contrast: matlab/[1,2] (out.contr) +% Correlation: matlab (out.corrm) +% Correlation: [1,2] (out.corrp) +% Cluster Prominence: [2] (out.cprom) +% Cluster Shade: [2] (out.cshad) +% Dissimilarity: [2] (out.dissi) +% Energy: matlab / [1,2] (out.energ) +% Entropy: [2] (out.entro) +% Homogeneity: matlab (out.homom) +% Homogeneity: [2] (out.homop) +% Maximum probability: [2] (out.maxpr) +% Sum of squares: Variance [1] (out.sosvh) +% Sum average [1] (out.savgh) +% Sum variance [1] (out.svarh) +% Sum entropy [1] (out.senth) +% Difference variance [1] (out.dvarh) +% Difference entropy [1] (out.denth) +% Information measure of correlation1 [1] (out.inf1h) +% Informaiton measure of correlation2 [1] (out.inf2h) +% Inverse difference (INV) is homom [3] (out.homom) +% Inverse difference normalized (INN) [3] (out.indnc) +% Inverse difference moment normalized [3] (out.idmnc) +% +% The maximal correlation coefficient was not calculated due to +% computational instability +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% Formulae from MATLAB site (some look different from +% the paper by Haralick but are equivalent and give same results) +% Example formulae: +% Contrast = sum_i(sum_j( (i-j)^2 * p(i,j) ) ) (same in matlab/paper) +% Correlation = sum_i( sum_j( (i - u_i)(j - u_j)p(i,j)/(s_i.s_j) ) ) (m) +% Correlation = sum_i( sum_j( ((ij)p(i,j) - u_x.u_y) / (s_x.s_y) ) ) (p[2]) +% Energy = sum_i( sum_j( p(i,j)^2 ) ) (same in matlab/paper) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + |i-j|) ) ) (as in matlab) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + (i-j)^2) ) ) (as in paper) +% +% Where: +% u_i = u_x = sum_i( sum_j( i.p(i,j) ) ) (in paper [2]) +% u_j = u_y = sum_i( sum_j( j.p(i,j) ) ) (in paper [2]) +% s_i = s_x = sum_i( sum_j( (i - u_x)^2.p(i,j) ) ) (in paper [2]) +% s_j = s_y = sum_i( sum_j( (j - u_y)^2.p(i,j) ) ) (in paper [2]) +% +% +% Normalize the glcm: +% Compute the sum of all the values in each glcm in the array and divide +% each element by it sum +% +% Haralick uses 'Symmetric' = true in computing the glcm +% There is no Symmetric flag in the Matlab version I use hence +% I add the diagonally opposite pairs to obtain the Haralick glcm +% Here it is assumed that the diagonally opposite orientations are paired +% one after the other in the matrix +% If the above assumption is true with respect to the input glcm then +% setting the flag 'pairs' to 1 will compute the final glcms that would result +% by setting 'Symmetric' to true. If your glcm is computed using the +% Matlab version with 'Symmetric' flag you can set the flag 'pairs' to 0 +% +% References: +% 1. R. M. Haralick, K. Shanmugam, and I. Dinstein, Textural Features of +% Image Classification, IEEE Transactions on Systems, Man and Cybernetics, +% vol. SMC-3, no. 6, Nov. 1973 +% 2. L. Soh and C. Tsatsoulis, Texture Analysis of SAR Sea Ice Imagery +% Using Gray Level Co-Occurrence Matrices, IEEE Transactions on Geoscience +% and Remote Sensing, vol. 37, no. 2, March 1999. +% 3. D A. Clausi, An analysis of co-occurrence texture statistics as a +% function of grey level quantization, Can. J. Remote Sensing, vol. 28, no. +% 1, pp. 45-62, 2002 +% 4. http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% +% Example: +% +% Usage is similar to graycoprops() but needs extra parameter 'pairs' apart +% from the GLCM as input +% I = imread('circuit.tif'); +% GLCM2 = graycomatrix(I,'Offset',[2 0;0 2]); +% stats = GLCM_features2(GLCM2,0) +% The output is a structure containing all the parameters for the different +% GLCMs +% +% [Avinash Uppuluri: avinash_uv@yahoo.com: Last modified: 12/07/08] + +% If 'pairs' not entered: set pairs to 0 +if ((nargin > 2) || (nargin == 0)) + error('Too many or too few input arguments. Enter GLCM and pairs.'); +elseif ( (nargin == 2) ) + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +elseif (nargin == 1) % only GLCM is entered + pairs = 0; % default is numbers and input 1 for percentage + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +end + + +format long e +if (pairs == 1) + newn = 1; + for nglcm = 1:2:size(glcmin,3) + glcm(:,:,newn) = glcmin(:,:,nglcm) + glcmin(:,:,nglcm+1); + newn = newn + 1; + end +elseif (pairs == 0) + glcm = glcmin; +end + +size_glcm_1 = size(glcm,1); +size_glcm_2 = size(glcm,2); +size_glcm_3 = size(glcm,3); + +% checked +out.autoc = zeros(1,size_glcm_3); % Autocorrelation: [2] +out.contr = zeros(1,size_glcm_3); % Contrast: matlab/[1,2] +out.corrm = zeros(1,size_glcm_3); % Correlation: matlab +out.corrp = zeros(1,size_glcm_3); % Correlation: [1,2] +out.cprom = zeros(1,size_glcm_3); % Cluster Prominence: [2] +out.cshad = zeros(1,size_glcm_3); % Cluster Shade: [2] +out.dissi = zeros(1,size_glcm_3); % Dissimilarity: [2] +out.energ = zeros(1,size_glcm_3); % Energy: matlab / [1,2] +out.entro = zeros(1,size_glcm_3); % Entropy: [2] +out.homom = zeros(1,size_glcm_3); % Homogeneity: matlab +out.homop = zeros(1,size_glcm_3); % Homogeneity: [2] +out.maxpr = zeros(1,size_glcm_3); % Maximum probability: [2] + +out.sosvh = zeros(1,size_glcm_3); % Sum of sqaures: Variance [1] +out.savgh = zeros(1,size_glcm_3); % Sum average [1] +out.svarh = zeros(1,size_glcm_3); % Sum variance [1] +out.senth = zeros(1,size_glcm_3); % Sum entropy [1] +out.dvarh = zeros(1,size_glcm_3); % Difference variance [4] +%out.dvarh2 = zeros(1,size_glcm_3); % Difference variance [1] +out.denth = zeros(1,size_glcm_3); % Difference entropy [1] +out.inf1h = zeros(1,size_glcm_3); % Information measure of correlation1 [1] +out.inf2h = zeros(1,size_glcm_3); % Informaiton measure of correlation2 [1] +%out.mxcch = zeros(1,size_glcm_3);% maximal correlation coefficient [1] +%out.invdc = zeros(1,size_glcm_3);% Inverse difference (INV) is homom [3] +out.indnc = zeros(1,size_glcm_3); % Inverse difference normalized (INN) [3] +out.idmnc = zeros(1,size_glcm_3); % Inverse difference moment normalized [3] + +glcm_sum = zeros(size_glcm_3,1); +glcm_mean = zeros(size_glcm_3,1); +glcm_var = zeros(size_glcm_3,1); + +% http://www.fp.ucalgary.ca/mhallbey/glcm_mean.htm confuses the range of +% i and j used in calculating the means and standard deviations. +% As of now I am not sure if the range of i and j should be [1:Ng] or +% [0:Ng-1]. I am working on obtaining the values of mean and std that get +% the values of correlation that are provided by matlab. +u_x = zeros(size_glcm_3,1); +u_y = zeros(size_glcm_3,1); +s_x = zeros(size_glcm_3,1); +s_y = zeros(size_glcm_3,1); + +% checked p_x p_y p_xplusy p_xminusy +p_x = zeros(size_glcm_1,size_glcm_3); % Ng x #glcms[1] +p_y = zeros(size_glcm_2,size_glcm_3); % Ng x #glcms[1] +p_xplusy = zeros((size_glcm_1*2 - 1),size_glcm_3); %[1] +p_xminusy = zeros((size_glcm_1),size_glcm_3); %[1] +% checked hxy hxy1 hxy2 hx hy +hxy = zeros(size_glcm_3,1); +hxy1 = zeros(size_glcm_3,1); +hx = zeros(size_glcm_3,1); +hy = zeros(size_glcm_3,1); +hxy2 = zeros(size_glcm_3,1); + +corm = zeros(size_glcm_3,1); +corp = zeros(size_glcm_3,1); + +for k = 1:size_glcm_3 + + glcm_sum(k) = sum(sum(glcm(:,:,k))); + glcm(:,:,k) = glcm(:,:,k)./glcm_sum(k); % Normalize each glcm + glcm_mean(k) = mean2(glcm(:,:,k)); % compute mean after norm + glcm_var(k) = (std2(glcm(:,:,k)))^2; + + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + p_x(i,k) = p_x(i,k) + glcm(i,j,k); + p_y(i,k) = p_y(i,k) + glcm(j,i,k); % taking i for j and j for i + if (ismember((i + j),[2:2*size_glcm_1])) + p_xplusy((i+j)-1,k) = p_xplusy((i+j)-1,k) + glcm(i,j,k); + end + if (ismember(abs(i-j),[0:(size_glcm_1-1)])) + p_xminusy((abs(i-j))+1,k) = p_xminusy((abs(i-j))+1,k) +... + glcm(i,j,k); + end + end + end + +end + +% marginal probabilities are now available [1] +% p_xminusy has +1 in index for matlab (no 0 index) +% computing sum average, sum variance and sum entropy: + + +%Q = zeros(size(glcm)); + +i_matrix = repmat([1:size_glcm_1]',1,size_glcm_2); +j_matrix = repmat([1:size_glcm_2],size_glcm_1,1); +% i_index = [ 1 1 1 1 1 .... 2 2 2 2 2 ... ] +i_index = j_matrix(:); +% j_index = [ 1 2 3 4 5 .... 1 2 3 4 5 ... ] +j_index = i_matrix(:); +xplusy_index = [1:(2*(size_glcm_1)-1)]'; +xminusy_index = [0:(size_glcm_1-1)]'; +mul_contr = abs(i_matrix - j_matrix).^2; +mul_dissi = abs(i_matrix - j_matrix); +%div_homop = ( 1 + mul_contr); % used from the above two formulae +%div_homom = ( 1 + mul_dissi); + +for k = 1:size_glcm_3 % number glcms + + out.contr(k) = sum(sum(mul_contr.*glcm(:,:,k))); + out.dissi(k) = sum(sum(mul_dissi.*glcm(:,:,k))); + out.energ(k) = sum(sum(glcm(:,:,k).^2)); + out.entro(k) = - sum(sum((glcm(:,:,k).*log(glcm(:,:,k) + eps)))); + out.homom(k) = sum(sum((glcm(:,:,k)./( 1 + mul_dissi)))); + out.homop(k) = sum(sum((glcm(:,:,k)./( 1 + mul_contr)))); + % [1] explains sum of squares variance with a mean value; + % the exact definition for mean has not been provided in + % the reference: I use the mean of the entire normalized glcm + out.sosvh(k) = sum(sum(glcm(:,:,k).*((i_matrix - glcm_mean(k)).^2))); + out.indnc(k) = sum(sum(glcm(:,:,k)./( 1 + (mul_dissi./size_glcm_1) ))); + out.idmnc(k) = sum(sum(glcm(:,:,k)./( 1 + (mul_contr./(size_glcm_1^2))))); + out.maxpr(k) = max(max(glcm(:,:,k))); + + u_x(k) = sum(sum(i_matrix.*glcm(:,:,k))); + u_y(k) = sum(sum(j_matrix.*glcm(:,:,k))); + % using http://www.fp.ucalgary.ca/mhallbey/glcm_variance.htm for s_x + % s_y : This solves the difference in value of correlation and might be + % the right value of standard deviations required + % According to this website there is a typo in [2] which provides + % values of variance instead of the standard deviation hence a square + % root is required as done below: + s_x(k) = (sum(sum( ((i_matrix - u_x(k)).^2).*glcm(:,:,k) )))^0.5; + s_y(k) = (sum(sum( ((j_matrix - u_y(k)).^2).*glcm(:,:,k) )))^0.5; + + corp(k) = sum(sum((i_matrix.*j_matrix.*glcm(:,:,k)))); + corm(k) = sum(sum(((i_matrix - u_x(k)).*(j_matrix - u_y(k)).*glcm(:,:,k)))); + + out.autoc(k) = corp(k); + out.corrp(k) = (corp(k) - u_x(k)*u_y(k))/(s_x(k)*s_y(k)); + out.corrm(k) = corm(k) / (s_x(k)*s_y(k)); + + out.cprom(k) = sum(sum(((i_matrix + j_matrix - u_x(k) - u_y(k)).^4).*... + glcm(:,:,k))); + out.cshad(k) = sum(sum(((i_matrix + j_matrix - u_x(k) - u_y(k)).^3).*... + glcm(:,:,k))); + + + + + + out.savgh(k) = sum((xplusy_index + 1).*p_xplusy(:,k)); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + out.senth(k) = - sum(p_xplusy(:,k).*... + log(p_xplusy(:,k) + eps)); + + % compute sum variance with the help of sum entropy + out.svarh(k) = sum((((xplusy_index + 1) - out.senth(k)).^2).*... + p_xplusy(:,k)); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + + % compute difference variance, difference entropy, + % out.dvarh2(k) = var(p_xminusy(:,k)); + % but using the formula in + % http://murphylab.web.cmu.edu/publications/boland/boland_node26.html + % we have for dvarh + out.denth(k) = - sum((p_xminusy(:,k)).*... + log(p_xminusy(:,k) + eps)); + out.dvarh(k) = sum((xminusy_index.^2).*p_xminusy(:,k)); + + % compute information measure of correlation(1,2) [1] + hxy(k) = out.entro(k); + glcmk = glcm(:,:,k)'; + glcmkv = glcmk(:); + + hxy1(k) = - sum(glcmkv.*log(p_x(i_index,k).*p_y(j_index,k) + eps)); + hxy2(k) = - sum(p_x(i_index,k).*p_y(j_index,k).*... + log(p_x(i_index,k).*p_y(j_index,k) + eps)); + hx(k) = - sum(p_x(:,k).*log(p_x(:,k) + eps)); + hy(k) = - sum(p_y(:,k).*log(p_y(:,k) + eps)); + + out.inf1h(k) = ( hxy(k) - hxy1(k) ) / ( max([hx(k),hy(k)]) ); + out.inf2h(k) = ( 1 - exp( -2*( hxy2(k) - hxy(k) ) ) )^0.5; + + % eig_Q(k,:) = eig(Q(:,:,k)); + % sort_eig(k,:)= sort(eig_Q(k,:),'descend'); + % out.mxcch(k) = sort_eig(k,2)^0.5; + % The maximal correlation coefficient was not calculated due to + % computational instability + % http://murphylab.web.cmu.edu/publications/boland/boland_node26.html + + +end + + + +% GLCM Features (Soh, 1999; Haralick, 1973; Clausi 2002) +% f1. Uniformity / Energy / Angular Second Moment (done) +% f2. Entropy (done) +% f3. Dissimilarity (done) +% f4. Contrast / Inertia (done) +% f5. Inverse difference +% f6. correlation +% f7. Homogeneity / Inverse difference moment +% f8. Autocorrelation +% f9. Cluster Shade +% f10. Cluster Prominence +% f11. Maximum probability +% f12. Sum of Squares +% f13. Sum Average +% f14. Sum Variance +% f15. Sum Entropy +% f16. Difference variance +% f17. Difference entropy +% f18. Information measures of correlation (1) +% f19. Information measures of correlation (2) +% f20. Maximal correlation coefficient +% f21. Inverse difference normalized (INN) +% f22. Inverse difference moment normalized (IDN) diff --git a/GLCM_analysis/dtireference/GLCM_Features3.m b/GLCM_analysis/dtireference/GLCM_Features3.m new file mode 100644 index 0000000..820c6d6 --- /dev/null +++ b/GLCM_analysis/dtireference/GLCM_Features3.m @@ -0,0 +1,419 @@ +function [out] = GLCM_Features3(glcmin,pairs) +% +% This is an update of GLCM_Features1 (non vectorized) without ismember() +% +% GLCM_Features3 helps to calculate the features from the different GLCMs +% that are input to the function. The GLCMs are stored in a i x j x n +% matrix, where n is the number of GLCMs calculated usually due to the +% different orientation and displacements used in the algorithm. Usually +% the values i and j are equal to 'NumLevels' parameter of the GLCM +% computing function graycomatrix(). Note that matlab quantization values +% belong to the set {1,..., NumLevels} and not from {0,...,(NumLevels-1)} +% as provided in some references +% http://www.mathworks.com/access/helpdesk/help/toolbox/images/graycomatrix +% .html +% +% Although there is a function graycoprops() in Matlab Image Processing +% Toolbox that computes four parameters Contrast, Correlation, Energy, +% and Homogeneity. The paper by Haralick suggests a few more parameters +% that are also computed here. The code is not fully vectorized and hence +% is not an efficient implementation but it is easy to add new features +% based on the GLCM using this code. Takes care of 3 dimensional glcms +% (multiple glcms in a single 3D array) +% +% If you find that the values obtained are different from what you expect +% or if you think there is a different formula that needs to be used +% from the ones used in this code please let me know. +% A few questions which I have are listed in the link +% http://www.mathworks.com/matlabcentral/newsreader/view_thread/239608 +% +% I plan to submit a vectorized version of the code later and provide +% updates based on replies to the above link and this initial code. +% +% Features computed +% Autocorrelation: [2] (out.autoc) +% Contrast: matlab/[1,2] (out.contr) +% Correlation: matlab (out.corrm) +% Correlation: [1,2] (out.corrp) +% Cluster Prominence: [2] (out.cprom) +% Cluster Shade: [2] (out.cshad) +% Dissimilarity: [2] (out.dissi) +% Energy: matlab / [1,2] (out.energ) +% Entropy: [2] (out.entro) +% Homogeneity: matlab (out.homom) +% Homogeneity: [2] (out.homop) +% Maximum probability: [2] (out.maxpr) +% Sum of sqaures: Variance [1] (out.sosvh) +% Sum average [1] (out.savgh) +% Sum variance [1] (out.svarh) +% Sum entropy [1] (out.senth) +% Difference variance [1] (out.dvarh) +% Difference entropy [1] (out.denth) +% Information measure of correlation1 [1] (out.inf1h) +% Informaiton measure of correlation2 [1] (out.inf2h) +% Inverse difference (INV) is homom [3] (out.homom) +% Inverse difference normalized (INN) [3] (out.indnc) +% Inverse difference moment normalized [3] (out.idmnc) +% +% The maximal correlation coefficient was not calculated due to +% computational instability +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% Formulae from MATLAB site (some look different from +% the paper by Haralick but are equivalent and give same results) +% Example formulae: +% Contrast = sum_i(sum_j( (i-j)^2 * p(i,j) ) ) (same in matlab/paper) +% Correlation = sum_i( sum_j( (i - u_i)(j - u_j)p(i,j)/(s_i.s_j) ) ) (m) +% Correlation = sum_i( sum_j( ((ij)p(i,j) - u_x.u_y) / (s_x.s_y) ) ) (p[2]) +% Energy = sum_i( sum_j( p(i,j)^2 ) ) (same in matlab/paper) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + |i-j|) ) ) (as in matlab) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + (i-j)^2) ) ) (as in paper) +% +% Where: +% u_i = u_x = sum_i( sum_j( i.p(i,j) ) ) (in paper [2]) +% u_j = u_y = sum_i( sum_j( j.p(i,j) ) ) (in paper [2]) +% s_i = s_x = sum_i( sum_j( (i - u_x)^2.p(i,j) ) ) (in paper [2]) +% s_j = s_y = sum_i( sum_j( (j - u_y)^2.p(i,j) ) ) (in paper [2]) +% +% +% Normalize the glcm: +% Compute the sum of all the values in each glcm in the array and divide +% each element by it sum +% +% Haralick uses 'Symmetric' = true in computing the glcm +% There is no Symmetric flag in the Matlab version I use hence +% I add the diagonally opposite pairs to obtain the Haralick glcm +% Here it is assumed that the diagonally opposite orientations are paired +% one after the other in the matrix +% If the above assumption is true with respect to the input glcm then +% setting the flag 'pairs' to 1 will compute the final glcms that would result +% by setting 'Symmetric' to true. If your glcm is computed using the +% Matlab version with 'Symmetric' flag you can set the flag 'pairs' to 0 +% +% References: +% 1. R. M. Haralick, K. Shanmugam, and I. Dinstein, Textural Features of +% Image Classification, IEEE Transactions on Systems, Man and Cybernetics, +% vol. SMC-3, no. 6, Nov. 1973 +% 2. L. Soh and C. Tsatsoulis, Texture Analysis of SAR Sea Ice Imagery +% Using Gray Level Co-Occurrence Matrices, IEEE Transactions on Geoscience +% and Remote Sensing, vol. 37, no. 2, March 1999. +% 3. D A. Clausi, An analysis of co-occurrence texture statistics as a +% function of grey level quantization, Can. J. Remote Sensing, vol. 28, no. +% 1, pp. 45-62, 2002 +% 4. http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% +% Example: +% +% Usage is similar to graycoprops() but needs extra parameter 'pairs' apart +% from the GLCM as input +% I = imread('circuit.tif'); +% GLCM2 = graycomatrix(I,'Offset',[2 0;0 2]); +% stats = GLCM_features3(GLCM2,0) +% The output is a structure containing all the parameters for the different +% GLCMs +% +% [Avinash Uppuluri: avinash_uv@yahoo.com: Last modified: 04/05/2010] + +% If 'pairs' not entered: set pairs to 0 +if ((nargin > 2) || (nargin == 0)) + error('Too many or too few input arguments. Enter GLCM and pairs.'); +elseif ( (nargin == 2) ) + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +elseif (nargin == 1) % only GLCM is entered + pairs = 0; % default is numbers and input 1 for percentage + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +end + + +format long e +if (pairs == 1) + newn = 1; + for nglcm = 1:2:size(glcmin,3) + glcm(:,:,newn) = glcmin(:,:,nglcm) + glcmin(:,:,nglcm+1); + newn = newn + 1; + end +elseif (pairs == 0) + glcm = glcmin; +end + +size_glcm_1 = size(glcm,1); +size_glcm_2 = size(glcm,2); +size_glcm_3 = size(glcm,3); + +% checked +out.autoc = zeros(1,size_glcm_3); % Autocorrelation: [2] +out.contr = zeros(1,size_glcm_3); % Contrast: matlab/[1,2] +out.corrm = zeros(1,size_glcm_3); % Correlation: matlab +out.corrp = zeros(1,size_glcm_3); % Correlation: [1,2] +out.cprom = zeros(1,size_glcm_3); % Cluster Prominence: [2] +out.cshad = zeros(1,size_glcm_3); % Cluster Shade: [2] +out.dissi = zeros(1,size_glcm_3); % Dissimilarity: [2] +out.energ = zeros(1,size_glcm_3); % Energy: matlab / [1,2] +out.entro = zeros(1,size_glcm_3); % Entropy: [2] +out.homom = zeros(1,size_glcm_3); % Homogeneity: matlab +out.homop = zeros(1,size_glcm_3); % Homogeneity: [2] +out.maxpr = zeros(1,size_glcm_3); % Maximum probability: [2] + +out.sosvh = zeros(1,size_glcm_3); % Sum of sqaures: Variance [1] +out.savgh = zeros(1,size_glcm_3); % Sum average [1] +out.svarh = zeros(1,size_glcm_3); % Sum variance [1] +out.senth = zeros(1,size_glcm_3); % Sum entropy [1] +out.dvarh = zeros(1,size_glcm_3); % Difference variance [4] +%out.dvarh2 = zeros(1,size_glcm_3); % Difference variance [1] +out.denth = zeros(1,size_glcm_3); % Difference entropy [1] +out.inf1h = zeros(1,size_glcm_3); % Information measure of correlation1 [1] +out.inf2h = zeros(1,size_glcm_3); % Informaiton measure of correlation2 [1] +%out.mxcch = zeros(1,size_glcm_3);% maximal correlation coefficient [1] +%out.invdc = zeros(1,size_glcm_3);% Inverse difference (INV) is homom [3] +out.indnc = zeros(1,size_glcm_3); % Inverse difference normalized (INN) [3] +out.idmnc = zeros(1,size_glcm_3); % Inverse difference moment normalized [3] + +% correlation with alternate definition of u and s +%out.corrm2 = zeros(1,size_glcm_3); % Correlation: matlab +%out.corrp2 = zeros(1,size_glcm_3); % Correlation: [1,2] + +glcm_sum = zeros(size_glcm_3,1); +glcm_mean = zeros(size_glcm_3,1); +glcm_var = zeros(size_glcm_3,1); + +% http://www.fp.ucalgary.ca/mhallbey/glcm_mean.htm confuses the range of +% i and j used in calculating the means and standard deviations. +% As of now I am not sure if the range of i and j should be [1:Ng] or +% [0:Ng-1]. I am working on obtaining the values of mean and std that get +% the values of correlation that are provided by matlab. +u_x = zeros(size_glcm_3,1); +u_y = zeros(size_glcm_3,1); +s_x = zeros(size_glcm_3,1); +s_y = zeros(size_glcm_3,1); + +% % alternate values of u and s +% u_x2 = zeros(size_glcm_3,1); +% u_y2 = zeros(size_glcm_3,1); +% s_x2 = zeros(size_glcm_3,1); +% s_y2 = zeros(size_glcm_3,1); + +% checked p_x p_y p_xplusy p_xminusy +p_x = zeros(size_glcm_1,size_glcm_3); % Ng x #glcms[1] +p_y = zeros(size_glcm_2,size_glcm_3); % Ng x #glcms[1] +p_xplusy = zeros((size_glcm_1*2 - 1),size_glcm_3); %[1] +p_xminusy = zeros((size_glcm_1),size_glcm_3); %[1] +% checked hxy hxy1 hxy2 hx hy +hxy = zeros(size_glcm_3,1); +hxy1 = zeros(size_glcm_3,1); +hx = zeros(size_glcm_3,1); +hy = zeros(size_glcm_3,1); +hxy2 = zeros(size_glcm_3,1); + +%Q = zeros(size(glcm)); + +for k = 1:size_glcm_3 % number glcms + + glcm_sum(k) = sum(sum(glcm(:,:,k))); + glcm(:,:,k) = glcm(:,:,k)./glcm_sum(k); % Normalize each glcm + glcm_mean(k) = mean2(glcm(:,:,k)); % compute mean after norm + glcm_var(k) = (std2(glcm(:,:,k)))^2; + + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + + out.contr(k) = out.contr(k) + (abs(i - j))^2.*glcm(i,j,k); + out.dissi(k) = out.dissi(k) + (abs(i - j)*glcm(i,j,k)); + out.energ(k) = out.energ(k) + (glcm(i,j,k).^2); + out.entro(k) = out.entro(k) - (glcm(i,j,k)*log(glcm(i,j,k) + eps)); + out.homom(k) = out.homom(k) + (glcm(i,j,k)/( 1 + abs(i-j) )); + out.homop(k) = out.homop(k) + (glcm(i,j,k)/( 1 + (i - j)^2)); + % [1] explains sum of squares variance with a mean value; + % the exact definition for mean has not been provided in + % the reference: I use the mean of the entire normalized glcm + out.sosvh(k) = out.sosvh(k) + glcm(i,j,k)*((i - glcm_mean(k))^2); + + %out.invdc(k) = out.homom(k); + out.indnc(k) = out.indnc(k) + (glcm(i,j,k)/( 1 + (abs(i-j)/size_glcm_1) )); + out.idmnc(k) = out.idmnc(k) + (glcm(i,j,k)/( 1 + ((i - j)/size_glcm_1)^2)); + u_x(k) = u_x(k) + (i)*glcm(i,j,k); % changed 10/26/08 + u_y(k) = u_y(k) + (j)*glcm(i,j,k); % changed 10/26/08 + % code requires that Nx = Ny + % the values of the grey levels range from 1 to (Ng) + end + + end + out.maxpr(k) = max(max(glcm(:,:,k))); +end +% glcms have been normalized: +% The contrast has been computed for each glcm in the 3D matrix +% (tested) gives similar results to the matlab function + +for k = 1:size_glcm_3 + + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + p_x(i,k) = p_x(i,k) + glcm(i,j,k); + p_y(i,k) = p_y(i,k) + glcm(j,i,k); % taking i for j and j for i + %if (ismember((i + j),[2:2*size_glcm_1])) + p_xplusy((i+j)-1,k) = p_xplusy((i+j)-1,k) + glcm(i,j,k); + %end + %if (ismember(abs(i-j),[0:(size_glcm_1-1)])) + p_xminusy((abs(i-j))+1,k) = p_xminusy((abs(i-j))+1,k) +... + glcm(i,j,k); + %end + end + end + +% % consider u_x and u_y and s_x and s_y as means and standard deviations +% % of p_x and p_y +% u_x2(k) = mean(p_x(:,k)); +% u_y2(k) = mean(p_y(:,k)); +% s_x2(k) = std(p_x(:,k)); +% s_y2(k) = std(p_y(:,k)); + +end + +% marginal probabilities are now available [1] +% p_xminusy has +1 in index for matlab (no 0 index) +% computing sum average, sum variance and sum entropy: +for k = 1:(size_glcm_3) + + for i = 1:(2*(size_glcm_1)-1) + out.savgh(k) = out.savgh(k) + (i+1)*p_xplusy(i,k); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + out.senth(k) = out.senth(k) - (p_xplusy(i,k)*log(p_xplusy(i,k) + eps)); + end + +end +% compute sum variance with the help of sum entropy +for k = 1:(size_glcm_3) + + for i = 1:(2*(size_glcm_1)-1) + out.svarh(k) = out.svarh(k) + (((i+1) - out.senth(k))^2)*p_xplusy(i,k); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + end + +end +% compute difference variance, difference entropy, +for k = 1:size_glcm_3 +% out.dvarh2(k) = var(p_xminusy(:,k)); +% but using the formula in +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% we have for dvarh + for i = 0:(size_glcm_1-1) + out.denth(k) = out.denth(k) - (p_xminusy(i+1,k)*log(p_xminusy(i+1,k) + eps)); + out.dvarh(k) = out.dvarh(k) + (i^2)*p_xminusy(i+1,k); + end +end + +% compute information measure of correlation(1,2) [1] +for k = 1:size_glcm_3 + hxy(k) = out.entro(k); + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + hxy1(k) = hxy1(k) - (glcm(i,j,k)*log(p_x(i,k)*p_y(j,k) + eps)); + hxy2(k) = hxy2(k) - (p_x(i,k)*p_y(j,k)*log(p_x(i,k)*p_y(j,k) + eps)); +% for Qind = 1:(size_glcm_1) +% Q(i,j,k) = Q(i,j,k) +... +% ( glcm(i,Qind,k)*glcm(j,Qind,k) / (p_x(i,k)*p_y(Qind,k)) ); +% end + end + hx(k) = hx(k) - (p_x(i,k)*log(p_x(i,k) + eps)); + hy(k) = hy(k) - (p_y(i,k)*log(p_y(i,k) + eps)); + end + out.inf1h(k) = ( hxy(k) - hxy1(k) ) / ( max([hx(k),hy(k)]) ); + out.inf2h(k) = ( 1 - exp( -2*( hxy2(k) - hxy(k) ) ) )^0.5; +% eig_Q(k,:) = eig(Q(:,:,k)); +% sort_eig(k,:)= sort(eig_Q(k,:),'descend'); +% out.mxcch(k) = sort_eig(k,2)^0.5; +% The maximal correlation coefficient was not calculated due to +% computational instability +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +end + +corm = zeros(size_glcm_3,1); +corp = zeros(size_glcm_3,1); +% using http://www.fp.ucalgary.ca/mhallbey/glcm_variance.htm for s_x s_y +for k = 1:size_glcm_3 + for i = 1:size_glcm_1 + for j = 1:size_glcm_2 + s_x(k) = s_x(k) + (((i) - u_x(k))^2)*glcm(i,j,k); + s_y(k) = s_y(k) + (((j) - u_y(k))^2)*glcm(i,j,k); + corp(k) = corp(k) + ((i)*(j)*glcm(i,j,k)); + corm(k) = corm(k) + (((i) - u_x(k))*((j) - u_y(k))*glcm(i,j,k)); + out.cprom(k) = out.cprom(k) + (((i + j - u_x(k) - u_y(k))^4)*... + glcm(i,j,k)); + out.cshad(k) = out.cshad(k) + (((i + j - u_x(k) - u_y(k))^3)*... + glcm(i,j,k)); + end + end + % using http://www.fp.ucalgary.ca/mhallbey/glcm_variance.htm for s_x + % s_y : This solves the difference in value of correlation and might be + % the right value of standard deviations required + % According to this website there is a typo in [2] which provides + % values of variance instead of the standard deviation hence a square + % root is required as done below: + s_x(k) = s_x(k) ^ 0.5; + s_y(k) = s_y(k) ^ 0.5; + out.autoc(k) = corp(k); + out.corrp(k) = (corp(k) - u_x(k)*u_y(k))/(s_x(k)*s_y(k)); + out.corrm(k) = corm(k) / (s_x(k)*s_y(k)); +% % alternate values of u and s +% out.corrp2(k) = (corp(k) - u_x2(k)*u_y2(k))/(s_x2(k)*s_y2(k)); +% out.corrm2(k) = corm(k) / (s_x2(k)*s_y2(k)); +end +% Here the formula in the paper out.corrp and the formula in matlab +% out.corrm are equivalent as confirmed by the similar results obtained + +% % The papers have a slightly different formular for Contrast +% % I have tested here to find this formula in the papers provides the +% % same results as the formula provided by the matlab function for +% % Contrast (Hence this part has been commented) +% out.contrp = zeros(size_glcm_3,1); +% contp = 0; +% Ng = size_glcm_1; +% for k = 1:size_glcm_3 +% for n = 0:(Ng-1) +% for i = 1:Ng +% for j = 1:Ng +% if (abs(i-j) == n) +% contp = contp + glcm(i,j,k); +% end +% end +% end +% out.contrp(k) = out.contrp(k) + n^2*contp; +% contp = 0; +% end +% +% end + +% GLCM Features (Soh, 1999; Haralick, 1973; Clausi 2002) +% f1. Uniformity / Energy / Angular Second Moment (done) +% f2. Entropy (done) +% f3. Dissimilarity (done) +% f4. Contrast / Inertia (done) +% f5. Inverse difference +% f6. correlation +% f7. Homogeneity / Inverse difference moment +% f8. Autocorrelation +% f9. Cluster Shade +% f10. Cluster Prominence +% f11. Maximum probability +% f12. Sum of Squares +% f13. Sum Average +% f14. Sum Variance +% f15. Sum Entropy +% f16. Difference variance +% f17. Difference entropy +% f18. Information measures of correlation (1) +% f19. Information measures of correlation (2) +% f20. Maximal correlation coefficient +% f21. Inverse difference normalized (INN) +% f22. Inverse difference moment normalized (IDN) diff --git a/GLCM_analysis/dtireference/GLCM_Features4.m b/GLCM_analysis/dtireference/GLCM_Features4.m new file mode 100644 index 0000000..8cbd2fe --- /dev/null +++ b/GLCM_analysis/dtireference/GLCM_Features4.m @@ -0,0 +1,369 @@ +function [out] = GLCM_Features4(glcmin,pairs) +% +% +% This is an update of GLCM_Features2 (vectorized) without ismember() +% +% GLCM_Features2 helps to calculate the features from the different GLCMs +% that are input to the function. The GLCMs are stored in a i x j x n +% matrix, where n is the number of GLCMs calculated usually due to the +% different orientation and displacements used in the algorithm. Usually +% the values i and j are equal to 'NumLevels' parameter of the GLCM +% computing function graycomatrix(). Note that matlab quantization values +% belong to the set {1,..., NumLevels} and not from {0,...,(NumLevels-1)} +% as provided in some references +% http://www.mathworks.com/access/helpdesk/help/toolbox/images/graycomatrix +% .html +% +% This vectorized version of GLCM_FEatures1.m reduces the 19 'for' loops +% used in the earlier code to 5 'for' loops +% http://blogs.mathworks.com/loren/2006/07/12/what-are-you-really-measuring +% / +% Using tic toc and cputime as in above discussion +% +% Although there is a function graycoprops() in Matlab Image Processing +% Toolbox that computes four parameters Contrast, Correlation, Energy, +% and Homogeneity. The paper by Haralick suggests a few more parameters +% that are also computed here. The code is not fully vectorized and hence +% is not an efficient implementation but it is easy to add new features +% based on the GLCM using this code. Takes care of 3 dimensional glcms +% (multiple glcms in a single 3D array) +% +% If you find that the values obtained are different from what you expect +% or if you think there is a different formula that needs to be used +% from the ones used in this code please let me know. +% A few questions which I have are listed in the link +% http://www.mathworks.com/matlabcentral/newsreader/view_thread/239608 +% +% +% +% Features computed +% Autocorrelation: [2] (out.autoc) +% Contrast: matlab/[1,2] (out.contr) +% Correlation: matlab (out.corrm) +% Correlation: [1,2] (out.corrp) +% Cluster Prominence: [2] (out.cprom) +% Cluster Shade: [2] (out.cshad) +% Dissimilarity: [2] (out.dissi) +% Energy: matlab / [1,2] (out.energ) +% Entropy: [2] (out.entro) +% Homogeneity: matlab (out.homom) +% Homogeneity: [2] (out.homop) +% Maximum probability: [2] (out.maxpr) +% Sum of squares: Variance [1] (out.sosvh) +% Sum average [1] (out.savgh) +% Sum variance [1] (out.svarh) +% Sum entropy [1] (out.senth) +% Difference variance [1] (out.dvarh) +% Difference entropy [1] (out.denth) +% Information measure of correlation1 [1] (out.inf1h) +% Informaiton measure of correlation2 [1] (out.inf2h) +% Inverse difference (INV) is homom [3] (out.homom) +% Inverse difference normalized (INN) [3] (out.indnc) +% Inverse difference moment normalized [3] (out.idmnc) +% +% The maximal correlation coefficient was not calculated due to +% computational instability +% http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% Formulae from MATLAB site (some look different from +% the paper by Haralick but are equivalent and give same results) +% Example formulae: +% Contrast = sum_i(sum_j( (i-j)^2 * p(i,j) ) ) (same in matlab/paper) +% Correlation = sum_i( sum_j( (i - u_i)(j - u_j)p(i,j)/(s_i.s_j) ) ) (m) +% Correlation = sum_i( sum_j( ((ij)p(i,j) - u_x.u_y) / (s_x.s_y) ) ) (p[2]) +% Energy = sum_i( sum_j( p(i,j)^2 ) ) (same in matlab/paper) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + |i-j|) ) ) (as in matlab) +% Homogeneity = sum_i( sum_j( p(i,j) / (1 + (i-j)^2) ) ) (as in paper) +% +% Where: +% u_i = u_x = sum_i( sum_j( i.p(i,j) ) ) (in paper [2]) +% u_j = u_y = sum_i( sum_j( j.p(i,j) ) ) (in paper [2]) +% s_i = s_x = sum_i( sum_j( (i - u_x)^2.p(i,j) ) ) (in paper [2]) +% s_j = s_y = sum_i( sum_j( (j - u_y)^2.p(i,j) ) ) (in paper [2]) +% +% +% Normalize the glcm: +% Compute the sum of all the values in each glcm in the array and divide +% each element by it sum +% +% Haralick uses 'Symmetric' = true in computing the glcm +% There is no Symmetric flag in the Matlab version I use hence +% I add the diagonally opposite pairs to obtain the Haralick glcm +% Here it is assumed that the diagonally opposite orientations are paired +% one after the other in the matrix +% If the above assumption is true with respect to the input glcm then +% setting the flag 'pairs' to 1 will compute the final glcms that would result +% by setting 'Symmetric' to true. If your glcm is computed using the +% Matlab version with 'Symmetric' flag you can set the flag 'pairs' to 0 +% +% References: +% 1. R. M. Haralick, K. Shanmugam, and I. Dinstein, Textural Features of +% Image Classification, IEEE Transactions on Systems, Man and Cybernetics, +% vol. SMC-3, no. 6, Nov. 1973 +% 2. L. Soh and C. Tsatsoulis, Texture Analysis of SAR Sea Ice Imagery +% Using Gray Level Co-Occurrence Matrices, IEEE Transactions on Geoscience +% and Remote Sensing, vol. 37, no. 2, March 1999. +% 3. D A. Clausi, An analysis of co-occurrence texture statistics as a +% function of grey level quantization, Can. J. Remote Sensing, vol. 28, no. +% 1, pp. 45-62, 2002 +% 4. http://murphylab.web.cmu.edu/publications/boland/boland_node26.html +% +% +% Example: +% +% Usage is similar to graycoprops() but needs extra parameter 'pairs' apart +% from the GLCM as input +% I = imread('circuit.tif'); +% GLCM2 = graycomatrix(I,'Offset',[2 0;0 2]); +% stats = GLCM_features4(GLCM2,0) +% The output is a structure containing all the parameters for the different +% GLCMs +% +% [Avinash Uppuluri: avinash_uv@yahoo.com: Last modified: 04/05/2010] + +% If 'pairs' not entered: set pairs to 0 +if ((nargin > 2) || (nargin == 0)) + error('Too many or too few input arguments. Enter GLCM and pairs.'); +elseif ( (nargin == 2) ) + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +elseif (nargin == 1) % only GLCM is entered + pairs = 0; % default is numbers and input 1 for percentage + if ((size(glcmin,1) <= 1) || (size(glcmin,2) <= 1)) + error('The GLCM should be a 2-D or 3-D matrix.'); + elseif ( size(glcmin,1) ~= size(glcmin,2) ) + error('Each GLCM should be square with NumLevels rows and NumLevels cols'); + end +end + + +format long e +if (pairs == 1) + newn = 1; + for nglcm = 1:2:size(glcmin,3) + glcm(:,:,newn) = glcmin(:,:,nglcm) + glcmin(:,:,nglcm+1); + newn = newn + 1; + end +elseif (pairs == 0) + glcm = glcmin; +end + +size_glcm_1 = size(glcm,1); +size_glcm_2 = size(glcm,2); +size_glcm_3 = size(glcm,3); + +% checked +out.autoc = zeros(1,size_glcm_3); % Autocorrelation: [2] +out.contr = zeros(1,size_glcm_3); % Contrast: matlab/[1,2] +out.corrm = zeros(1,size_glcm_3); % Correlation: matlab +out.corrp = zeros(1,size_glcm_3); % Correlation: [1,2] +out.cprom = zeros(1,size_glcm_3); % Cluster Prominence: [2] +out.cshad = zeros(1,size_glcm_3); % Cluster Shade: [2] +out.dissi = zeros(1,size_glcm_3); % Dissimilarity: [2] +out.energ = zeros(1,size_glcm_3); % Energy: matlab / [1,2] +out.entro = zeros(1,size_glcm_3); % Entropy: [2] +out.homom = zeros(1,size_glcm_3); % Homogeneity: matlab +out.homop = zeros(1,size_glcm_3); % Homogeneity: [2] +out.maxpr = zeros(1,size_glcm_3); % Maximum probability: [2] + +out.sosvh = zeros(1,size_glcm_3); % Sum of sqaures: Variance [1] +out.savgh = zeros(1,size_glcm_3); % Sum average [1] +out.svarh = zeros(1,size_glcm_3); % Sum variance [1] +out.senth = zeros(1,size_glcm_3); % Sum entropy [1] +out.dvarh = zeros(1,size_glcm_3); % Difference variance [4] +%out.dvarh2 = zeros(1,size_glcm_3); % Difference variance [1] +out.denth = zeros(1,size_glcm_3); % Difference entropy [1] +out.inf1h = zeros(1,size_glcm_3); % Information measure of correlation1 [1] +out.inf2h = zeros(1,size_glcm_3); % Informaiton measure of correlation2 [1] +%out.mxcch = zeros(1,size_glcm_3);% maximal correlation coefficient [1] +%out.invdc = zeros(1,size_glcm_3);% Inverse difference (INV) is homom [3] +out.indnc = zeros(1,size_glcm_3); % Inverse difference normalized (INN) [3] +out.idmnc = zeros(1,size_glcm_3); % Inverse difference moment normalized [3] + +glcm_sum = zeros(size_glcm_3,1); +glcm_mean = zeros(size_glcm_3,1); +glcm_var = zeros(size_glcm_3,1); + +% http://www.fp.ucalgary.ca/mhallbey/glcm_mean.htm confuses the range of +% i and j used in calculating the means and standard deviations. +% As of now I am not sure if the range of i and j should be [1:Ng] or +% [0:Ng-1]. I am working on obtaining the values of mean and std that get +% the values of correlation that are provided by matlab. +u_x = zeros(size_glcm_3,1); +u_y = zeros(size_glcm_3,1); +s_x = zeros(size_glcm_3,1); +s_y = zeros(size_glcm_3,1); + +% checked p_x p_y p_xplusy p_xminusy +p_x = zeros(size_glcm_1,size_glcm_3); % Ng x #glcms[1] +p_y = zeros(size_glcm_2,size_glcm_3); % Ng x #glcms[1] +p_xplusy = zeros((size_glcm_1*2 - 1),size_glcm_3); %[1] +p_xminusy = zeros((size_glcm_1),size_glcm_3); %[1] +% checked hxy hxy1 hxy2 hx hy +hxy = zeros(size_glcm_3,1); +hxy1 = zeros(size_glcm_3,1); +hx = zeros(size_glcm_3,1); +hy = zeros(size_glcm_3,1); +hxy2 = zeros(size_glcm_3,1); + +corm = zeros(size_glcm_3,1); +corp = zeros(size_glcm_3,1); + +for k = 1:size_glcm_3 + + glcm_sum(k) = sum(sum(glcm(:,:,k))); + glcm(:,:,k) = glcm(:,:,k)./glcm_sum(k); % Normalize each glcm + glcm_mean(k) = mean2(glcm(:,:,k)); % compute mean after norm + glcm_var(k) = (std2(glcm(:,:,k)))^2; + + for i = 1:size_glcm_1 + + for j = 1:size_glcm_2 + p_x(i,k) = p_x(i,k) + glcm(i,j,k); + p_y(i,k) = p_y(i,k) + glcm(j,i,k); % taking i for j and j for i + %if (ismember((i + j),[2:2*size_glcm_1])) + p_xplusy((i+j)-1,k) = p_xplusy((i+j)-1,k) + glcm(i,j,k); + %end + %if (ismember(abs(i-j),[0:(size_glcm_1-1)])) + p_xminusy((abs(i-j))+1,k) = p_xminusy((abs(i-j))+1,k) +... + glcm(i,j,k); + %end + end + end + +end + +% marginal probabilities are now available [1] +% p_xminusy has +1 in index for matlab (no 0 index) +% computing sum average, sum variance and sum entropy: + + +%Q = zeros(size(glcm)); + +i_matrix = repmat([1:size_glcm_1]',1,size_glcm_2); +j_matrix = repmat([1:size_glcm_2],size_glcm_1,1); +% i_index = [ 1 1 1 1 1 .... 2 2 2 2 2 ... ] +i_index = j_matrix(:); +% j_index = [ 1 2 3 4 5 .... 1 2 3 4 5 ... ] +j_index = i_matrix(:); +xplusy_index = [1:(2*(size_glcm_1)-1)]'; +xminusy_index = [0:(size_glcm_1-1)]'; +mul_contr = abs(i_matrix - j_matrix).^2; +mul_dissi = abs(i_matrix - j_matrix); +%div_homop = ( 1 + mul_contr); % used from the above two formulae +%div_homom = ( 1 + mul_dissi); + +for k = 1:size_glcm_3 % number glcms + + out.contr(k) = sum(sum(mul_contr.*glcm(:,:,k))); + out.dissi(k) = sum(sum(mul_dissi.*glcm(:,:,k))); + out.energ(k) = sum(sum(glcm(:,:,k).^2)); + out.entro(k) = - sum(sum((glcm(:,:,k).*log(glcm(:,:,k) + eps)))); + out.homom(k) = sum(sum((glcm(:,:,k)./( 1 + mul_dissi)))); + out.homop(k) = sum(sum((glcm(:,:,k)./( 1 + mul_contr)))); + % [1] explains sum of squares variance with a mean value; + % the exact definition for mean has not been provided in + % the reference: I use the mean of the entire normalized glcm + out.sosvh(k) = sum(sum(glcm(:,:,k).*((i_matrix - glcm_mean(k)).^2))); + out.indnc(k) = sum(sum(glcm(:,:,k)./( 1 + (mul_dissi./size_glcm_1) ))); + out.idmnc(k) = sum(sum(glcm(:,:,k)./( 1 + (mul_contr./(size_glcm_1^2))))); + out.maxpr(k) = max(max(glcm(:,:,k))); + + u_x(k) = sum(sum(i_matrix.*glcm(:,:,k))); + u_y(k) = sum(sum(j_matrix.*glcm(:,:,k))); + % using http://www.fp.ucalgary.ca/mhallbey/glcm_variance.htm for s_x + % s_y : This solves the difference in value of correlation and might be + % the right value of standard deviations required + % According to this website there is a typo in [2] which provides + % values of variance instead of the standard deviation hence a square + % root is required as done below: + s_x(k) = (sum(sum( ((i_matrix - u_x(k)).^2).*glcm(:,:,k) )))^0.5; + s_y(k) = (sum(sum( ((j_matrix - u_y(k)).^2).*glcm(:,:,k) )))^0.5; + + corp(k) = sum(sum((i_matrix.*j_matrix.*glcm(:,:,k)))); + corm(k) = sum(sum(((i_matrix - u_x(k)).*(j_matrix - u_y(k)).*glcm(:,:,k)))); + + out.autoc(k) = corp(k); + out.corrp(k) = (corp(k) - u_x(k)*u_y(k))/(s_x(k)*s_y(k)); + out.corrm(k) = corm(k) / (s_x(k)*s_y(k)); + + out.cprom(k) = sum(sum(((i_matrix + j_matrix - u_x(k) - u_y(k)).^4).*... + glcm(:,:,k))); + out.cshad(k) = sum(sum(((i_matrix + j_matrix - u_x(k) - u_y(k)).^3).*... + glcm(:,:,k))); + + + + + + out.savgh(k) = sum((xplusy_index + 1).*p_xplusy(:,k)); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + out.senth(k) = - sum(p_xplusy(:,k).*... + log(p_xplusy(:,k) + eps)); + + % compute sum variance with the help of sum entropy + out.svarh(k) = sum((((xplusy_index + 1) - out.senth(k)).^2).*... + p_xplusy(:,k)); + % the summation for savgh is for i from 2 to 2*Ng hence (i+1) + + % compute difference variance, difference entropy, + % out.dvarh2(k) = var(p_xminusy(:,k)); + % but using the formula in + % http://murphylab.web.cmu.edu/publications/boland/boland_node26.html + % we have for dvarh + out.denth(k) = - sum((p_xminusy(:,k)).*... + log(p_xminusy(:,k) + eps)); + out.dvarh(k) = sum((xminusy_index.^2).*p_xminusy(:,k)); + + % compute information measure of correlation(1,2) [1] + hxy(k) = out.entro(k); + glcmk = glcm(:,:,k)'; + glcmkv = glcmk(:); + + hxy1(k) = - sum(glcmkv.*log(p_x(i_index,k).*p_y(j_index,k) + eps)); + hxy2(k) = - sum(p_x(i_index,k).*p_y(j_index,k).*... + log(p_x(i_index,k).*p_y(j_index,k) + eps)); + hx(k) = - sum(p_x(:,k).*log(p_x(:,k) + eps)); + hy(k) = - sum(p_y(:,k).*log(p_y(:,k) + eps)); + + out.inf1h(k) = ( hxy(k) - hxy1(k) ) / ( max([hx(k),hy(k)]) ); + out.inf2h(k) = ( 1 - exp( -2*( hxy2(k) - hxy(k) ) ) )^0.5; + + % eig_Q(k,:) = eig(Q(:,:,k)); + % sort_eig(k,:)= sort(eig_Q(k,:),'descend'); + % out.mxcch(k) = sort_eig(k,2)^0.5; + % The maximal correlation coefficient was not calculated due to + % computational instability + % http://murphylab.web.cmu.edu/publications/boland/boland_node26.html + + +end + + + +% GLCM Features (Soh, 1999; Haralick, 1973; Clausi 2002) +% f1. Uniformity / Energy / Angular Second Moment (done) +% f2. Entropy (done) +% f3. Dissimilarity (done) +% f4. Contrast / Inertia (done) +% f5. Inverse difference +% f6. correlation +% f7. Homogeneity / Inverse difference moment +% f8. Autocorrelation +% f9. Cluster Shade +% f10. Cluster Prominence +% f11. Maximum probability +% f12. Sum of Squares +% f13. Sum Average +% f14. Sum Variance +% f15. Sum Entropy +% f16. Difference variance +% f17. Difference entropy +% f18. Information measures of correlation (1) +% f19. Information measures of correlation (2) +% f20. Maximal correlation coefficient +% f21. Inverse difference normalized (INN) +% f22. Inverse difference moment normalized (IDN) diff --git a/GLCM_analysis/dtireference/SVM.m b/GLCM_analysis/dtireference/SVM.m new file mode 100644 index 0000000..83f53dc --- /dev/null +++ b/GLCM_analysis/dtireference/SVM.m @@ -0,0 +1,23 @@ +clc; +clear; +[label, data] = libsvmread('D:\Program Files\libsvm-3.21\tools\FA'); +acc = 0; +% for i = 1:36; +% train_label = label; +% train_data = data; +% % train_label(i,:) = []; +% % train_data(i,:) = []; +% test_label = label(i,:); +% test_data = data(i,:); +% +% model = svmtrain(train_label, train_data, '-s 0'); +% %model = svmtrain(label, instance, '-s 0 -c 32 -g 0.0078125 -v 10'); +% [predict_label, accuracy, dec_val] = svmpredict(test_label, test_data, model); +% acc = acc+accuracy(1,1); +% end +% end_acc = acc/36; + + +model = svmtrain(label, data, '-s 0 -c 32 -g 0.0078125 -v 10'); +%model = svmtrain(label, instance, '-s 0 -c 32 -g 0.0078125 -v 10'); +[predict_label, accuracy, dec_val] = svmpredict(label, data, model); \ No newline at end of file diff --git a/GLCM_analysis/dtireference/Test_GLCM_Features.html b/GLCM_analysis/dtireference/Test_GLCM_Features.html new file mode 100644 index 0000000..a93bc25 --- /dev/null +++ b/GLCM_analysis/dtireference/Test_GLCM_Features.html @@ -0,0 +1,257 @@ + + + + + + Test_GLCM_Features + + + +
% Timing improvement of
+% GLCM_Features3.m [non vectorized without ismember] and
+% GLCM_Features4.m [vectorized without ismember] over
+% GLCM_Features1.m [non vectorized with ismember] and
+% GLCM_Features2.m [ vectorized with ismember]
+
+clear all
+
+offsetmat = [];
+noffs = 10;
+for i = 1:noffs
+    offsetmat = [offsetmat; i*[1 0]];
+    I = imread('circuit.tif'); GLCM2 = graycomatrix(I,...
+        'NumLevels',64,'Offset',offsetmat);
+
+    tic; stats1 = GLCM_Features1(GLCM2,0); t1(i) = toc;
+    clear stats1
+
+    t = cputime; stats1 = GLCM_Features1(GLCM2,0); ct1(i) = cputime-t;
+    %clear stats1
+
+
+    tic; stats2 = GLCM_Features2(GLCM2,0); t2(i) = toc;
+    clear stats2
+
+    t = cputime; stats2 = GLCM_Features2(GLCM2,0); ct2(i) = cputime-t;
+    %clear stats2
+
+    tic; stats3 = GLCM_Features3(GLCM2,0); t3(i) = toc;
+    clear stats3
+
+    t = cputime; stats3 = GLCM_Features3(GLCM2,0); ct3(i) = cputime-t;
+    %clear stats3
+
+    tic; stats4 = GLCM_Features4(GLCM2,0); t4(i) = toc;
+    clear stats4
+
+    t = cputime; stats4 = GLCM_Features4(GLCM2,0); ct4(i) = cputime-t;
+    %clear stats4
+
+end
+
+% Error analysis
+diff_err12 = diffStructFields(stats1, stats2, noffs);
+diff_err13 = diffStructFields(stats1, stats3, noffs);
+diff_err14 = diffStructFields(stats1, stats4, noffs);
+
+% Timing Plots
+figure; subplot(2,1,1);
+            hold on
+            plot(t1,'-*');
+            plot(t2,':sr');
+            %plot(t3,'-x');
+            %plot(t4,':dr');
+            xlabel('No. of GLCMs input');
+            ylabel('Execution time (secs)');
+            legend('GLCM\_Features1','GLCM\_Features2');
+            hold off
+       subplot(2,1,2);
+            hold on
+            plot(ct1,'-*');
+            plot(ct2,':sr');
+            %plot(ct3,'-x');
+            %plot(ct4,':dr');
+            xlabel('No. of GLCMs input');
+            ylabel('CPU time (secs)');
+            legend('GLCM\_Features1','GLCM\_Features2');
+            hold off
+
+figure; subplot(2,1,1);
+            hold on
+            %plot(t1,'-*');
+            %plot(t2,':sr');
+            plot(t3,'-x');
+            plot(t4,':dr');
+            xlabel('No. of GLCMs input');
+            ylabel('Execution time (secs)');
+            legend('GLCM\_Features3','GLCM\_Features4');
+            hold off
+       subplot(2,1,2);
+            hold on
+            %plot(ct1,'-*');
+            %plot(ct2,':sr');
+            plot(ct3,'-x');
+            plot(ct4,':dr');
+            xlabel('No. of GLCMs input');
+            ylabel('CPU time (secs)');
+            legend('GLCM\_Features3','GLCM\_Features4');
+            hold off
+
+ + + \ No newline at end of file diff --git a/GLCM_analysis/dtireference/Test_GLCM_Features.m b/GLCM_analysis/dtireference/Test_GLCM_Features.m new file mode 100644 index 0000000..ac989ab --- /dev/null +++ b/GLCM_analysis/dtireference/Test_GLCM_Features.m @@ -0,0 +1,90 @@ +% Timing improvement of +% GLCM_Features3.m [non vectorized without ismember] and +% GLCM_Features4.m [vectorized without ismember] over +% GLCM_Features1.m [non vectorized with ismember] and +% GLCM_Features2.m [ vectorized with ismember] + +clear all + +offsetmat = []; +noffs = 10; +for i = 1:noffs + offsetmat = [offsetmat; i*[1 0]]; + I = imread('circuit.tif'); GLCM2 = graycomatrix(I,... + 'NumLevels',64,'Offset',offsetmat); + + tic; stats1 = GLCM_Features1(GLCM2,0); t1(i) = toc; + clear stats1 + + t = cputime; stats1 = GLCM_Features1(GLCM2,0); ct1(i) = cputime-t; + %clear stats1 + + + tic; stats2 = GLCM_Features2(GLCM2,0); t2(i) = toc; + clear stats2 + + t = cputime; stats2 = GLCM_Features2(GLCM2,0); ct2(i) = cputime-t; + %clear stats2 + + tic; stats3 = GLCM_Features3(GLCM2,0); t3(i) = toc; + clear stats3 + + t = cputime; stats3 = GLCM_Features3(GLCM2,0); ct3(i) = cputime-t; + %clear stats3 + + tic; stats4 = GLCM_Features4(GLCM2,0); t4(i) = toc; + clear stats4 + + t = cputime; stats4 = GLCM_Features4(GLCM2,0); ct4(i) = cputime-t; + %clear stats4 + +end + +% Error analysis +diff_err12 = diffStructFields(stats1, stats2, noffs); +diff_err13 = diffStructFields(stats1, stats3, noffs); +diff_err14 = diffStructFields(stats1, stats4, noffs); + +% Timing Plots +figure; subplot(2,1,1); + hold on + plot(t1,'-*'); + plot(t2,':sr'); + %plot(t3,'-x'); + %plot(t4,':dr'); + xlabel('No. of GLCMs input'); + ylabel('Execution time (secs)'); + legend('GLCM\_Features1','GLCM\_Features2'); + hold off + subplot(2,1,2); + hold on + plot(ct1,'-*'); + plot(ct2,':sr'); + %plot(ct3,'-x'); + %plot(ct4,':dr'); + xlabel('No. of GLCMs input'); + ylabel('CPU time (secs)'); + legend('GLCM\_Features1','GLCM\_Features2'); + hold off + +figure; subplot(2,1,1); + hold on + %plot(t1,'-*'); + %plot(t2,':sr'); + plot(t3,'-x'); + plot(t4,':dr'); + xlabel('No. of GLCMs input'); + ylabel('Execution time (secs)'); + legend('GLCM\_Features3','GLCM\_Features4'); + hold off + subplot(2,1,2); + hold on + %plot(ct1,'-*'); + %plot(ct2,':sr'); + plot(ct3,'-x'); + plot(ct4,':dr'); + xlabel('No. of GLCMs input'); + ylabel('CPU time (secs)'); + legend('GLCM\_Features3','GLCM\_Features4'); + hold off + diff --git a/GLCM_analysis/dtireference/Test_GLCM_Features.png b/GLCM_analysis/dtireference/Test_GLCM_Features.png new file mode 100644 index 0000000000000000000000000000000000000000..e67c4bd5a44deb347f23ecff63bacc130f0d96d0 GIT binary patch literal 3670 zcmV-c4yo~pP)E2DH2;$^5YoGKbaXU1IT;KFyWMU$9Hx}owr$&XB9UN>0U)m*Jvus4RrT=jaB^~T zR7XDc6GAGLN+OW}APDcxK@dVVHUwRV>tbyUtE&JoJL}Zz^%pN*%*@P8PfvgQ?YFC| ztDR0K8jb$&!w=17GoR15S}je}6h)bvn~TL_<9qS9Ur`iM6yJtbm%`nmF9*_4| z(ffp9fDkmBsMRnx2SOaz)pdP)dpncKBoc|QzyA8e4?om(JsOQZe*CyrtKGVFtJ!R7 znx?91wOal1%P+_G;A6jG7@<(8*=&YFp`)Xta5(&Sj5`OmZCirC7>J@E7Gr`)2p|YI zZrr$e^ClsL5c2uwpBIb8NFrEYqw%*;$U9M0u(nx?&D<2e*XDHQPg--EB>hY!(cAe+7BUVQu?_n(3w z2!ap{2Cuop3xiS^2Kp{66hgBJ#;&;+ANy_F4uwKzC(@h1Fi@*q<;7wVi;Dx2+qY3D zT!&6);A4Lv5LjATx-Pf3zmIAaYiqEqOT6V7{MU-XwsB44(u03^x3;!sT}s~(D3_7R z;O<>~@BwNy{PGLB-3z_Aw})G|eB_IZ*xY<`y-wk8za&YfX)?yfc+PXt=|B(=i2wj0 z$Y!y+icSZ=`~qDcw~{G^X?h30r>=ld2)2D?rG^?D7CDZ?{U3lvqfx0;?8|rPI5;>! zDm5S^1geVFRcIRi@)sC}|GUMa|KM}v^Vrz9tU4p%zy2eU2oIs>=H^nV)MfWS#_;Nu z*L(Fr2-0c%`Oj!Jv9aM@&y=Fu^&kBH>#7RVyp%>G;lKX{0s$WXUM&mS+{EqM7#~0r zf=mWWOW4`L{{HE571grH`C3*fuDI>%wu+>7dg=wTh=tMN0j(@&C@HQfYQ} z_8cunpi)6Ldu9Ml6S|H>!uMf8z~Uk-3+wC1W)YA3xP4zFllbdj5s!mXFxLBgfdDo) zvAWuGIz0D{#jvzQD;0l# zHxv=MIi}hB{F;VN2aAiZJvbqdWjuHQ*M%g(wqe_lBuEkj0o^VJLyTw?fBIux3@X5& zvYifOd0rQA$nI^hT4E>N`6VL%ZC`;bAnL_AC?Ya5UloWsMz)L;vSVKf!x z#-NZfRw|WlsH$hvDd>7U8uip*OQjN})YELc-7c5Q9-*%5$H&Lp+uJvJB0Y$6>fez_ z#CHqqbUMSO(Lf+D94S?+)!`tLF{bPKaI=PCxUTEzkq|Omz%@;CxGzbPhSRoSFld_Q zs6xoN`9B7XvEc%ludoltaR?!O+icsWluD8$2!d_fk|Z(41VP}xub|S^a79+b*Us@J z!ykYAkr0whCU4!k_0vy3O-)TvN;OT(X0yRy@cHxSf*{ZEyI?Kz;-ENnUZ7P*YCX)sRcF~n3%w2lPSk>ve|4VlL2}WbN~DA z?(W87v2ZxtZnq+yJ86vh4h{a`Q{32%ID#5?|xNJN(9Ynl9pfw{Tfbux+d z_1+x51bBq6X=t@Lf8e^VWm(UkKhI{f@p$~3Z@zi>@L{*xjm2VLef3qPQdwGBYBU;} zrX`cfN~LmX{@1o`0J|oPzbJzi*F;kuD5y47YgCty?)Vq zVPS!1a)gjaj~?-nR}|%wPd@2q5IhqRMe$q~!)w1F2t54e9dx^0!!Y=|x~Sp+(5uOv zokllqV0RaOIjEmnlGH!^1K{ju^AzUh=jZvws3P_3>};#m8rjjH(yY_zh@!}ebV5ij zm#f$7S2+AtuVZ0hKq87g+T((2E8rT{lMeOj$m&O!>)I6@rqpN z+k@Bt7mLO9_4PMw)Uy1E`cMcXj^VvGca(dQd@ z?ROj}9*+Ykm&>ZE9v>fHR+Z!9K_@>Lz7v8(0=Df#U0fWDq1#2P1>45)F)RzA5E2Q* zVz_e$(I^NR@Ur>5v$Jyn{)bm!EX$&l9v>eQLXM7(L{Yrd`KLnRY`6++Y(Ue_o?y&o zv9)y?+n#G`rvul8X`>!2IOk+j(@dUU0GQX1R;~jgu~&<$;ocF zdvW7!dvN8uE@o#jJ$-h>1)(=5&aM$IIXr|ULD!+{J%%?Dfo&t1grY!IM=q-?!#ny@tSkmb|3jga0@3Iart6P}84{o@J88Rn10-CaT{ z^XqKjQ9kXj5bD}CIvqTHiVr>j02l@)CVU+Xtu5TY-?P?rdo<>gCs6BEN(t`9FH2yVA4a3S{*Cpv0OAel{F#xWs z-M&2~io)wmnWGko#04Qdm~u15Ow;t_;f~{2wmqDj>$+|jhG$f3wHl>#VsKXT{{rxo zx2)GVE9B&2wOUOklfyQS^S`nzXS3N_t3`&u3v3=?Fc>^JIq?V&4-ZSFl1FHoW~0&Y z2mu@%9Po2z9(gz%_6TdWTBTAM)~Z-64r^N~m8#XMuZ`#PU;RV%XTkqRz$4^edN^g~ zEu8fNjIn-9NeJP$7-Re&SUfHGDnKb^jCmFXKe;`;e{oXWm%=!ItMerxe3{8nVIptg z`|rPxMx!$`GpST+Yioe)D00D_`?@=h*%PXvVoS%t(Tg@h$VM0ryL@Rb41f3bxT4}>foj2gx z>DMHgLeBmPrFRJwW|0_LoGuhvYi1T?#JFG9lCWp&A6dN}5O>@!MF22AB`*{S8Z$SV2LmSxX-t4zaEV+# zB^Y2jxB~$KD7UGR=eaU(&&{2zrZkPas;gkCo-d+Gg0e*` zdtuw5^^vwZ2Q;WKk18l@$_PtFz_+K$0D`Qs_)49n?)+~?lNyqy`_76pSO$(bCZUXVe>yIKFarNit-2GzE z?2pIjYO{MD{ZzC4F1fZ=MmPwC>1ECbzY}d?Ago{tK}oHW zRN^cvXSbj&#e)kkDS>RK=Dz4x$J=fz(Abdln}?!4m#8fM*CA<65pp1>`B~kxtAGMz zq|>Uqz-zvN!{1fIo5oq8D6eu6*!&gBr5*v-5Bevv<9FG*lec z3n~Nj`J|@YE0(snD&n6_yfs*wwckG*YJU`}xXr`(kch!2f(L!WAfA6Yqz!p13tmo)nUvKcZ z)$T^nCrSnj43-dRy$y8-Ol<2PRV^Jw$bv{aRTE`wc}x6Cj*$X40J*43Bn-c34PuCZ zkAmr0{~lM2_(wCoOLc^?cQ|zzB*K)a z@3vW<{bQJjDFk`+T@93`hd1fL?TBwoOEwGZhy^0-Z>oc#Nhy}c0)g%g{H7+3X!Fg# zu7-xkjW1MXi~W*CI^j%J(d4IhY9>6YIgOb@*0c8Z|DfDj>ZHcuEpR`=Vn0F>Hs0px zN=I9In)NK_u5r)n{bBpO$!^ucU&t1$_!k?tZ#(rr_*+gYPl*}SIxi7quE&-}s?2_l zzbu1Q(_u0Ql#mP*`JYU^vwQ4$D!;}XD(TvT);ia3}`i(y# zUv)eeX;z{KeAaKne)2pBNsGGbjjUagI64j|pmV$CJ74~R!yO-cpt>0+tHWGtA0WLu z(nN@WEn7N>p(b<%eE|cS;#AWsY$U@!W&0q{cmV70Ep0R5vb@V^5YQ{MeIH=WJGgB| zz`M@t8~A7tR?~k40g-y98EaCx8E$4RIavWz~^ zchEl{K3ikvCamxy)cnX7zD!Nso_=c+(;=TnT9K+Iw#ruPeG^T9V=@%DMQy6~u%0n$ z4MFJCX&c=&`sI|(a;Shf&T=+wWYyT6VxTw-nW_H*PU_?^%sDN5?71jW4FBZ7b`MO0 z;ULarciDYBg&;)U^@dG{_c$`l%|Z|w&o(guq4qP@%B%$Y`kP7v@^C5PvJR0>W;pp@ zp>Xht4vVlK#Y58VU@dLtetMcfCRjPmVe2|tc>8|mQ0oZjQD7B4n5Lo(WJN!@w`#k3 z@cEDA52sl5G^lkwzT?!<0^2tnh^8M3SPGZ@>a80CqK#j--3|nm)ZKSQRT?8^PSTIE zhCx}i6d)U{g@-lmNnUL}oAxygz*;p< zR<&LjPA^?Dq9`f(A&93hKfoiPHXuK*b1NL~=KUCcLnm{>$$Le7NplUm{z0oMT1!zn z`4j4hS&T4Q3%%ACer^4AcLbRQ2yvcH`Vc@7hM*L2ep_<>>xf zOc1M5PrcUEk~2ccEwl}fTwF_qwCy(1vxhyIxW2Xf)d#<+YSNU^J&&r5jgtc7SIqsT zuM{&G7CP5M9F6vtSp2+57p#sRAh?57vt|8C4$%*He=9Ok! zp^SddyRpmA>xaVIMi6K2IhW7ja&S`5pB=CP|MEw(94aR@9UZ5%6`nIhIx&n0V*Zo$ z)!oJKqrTNkJ8igioMS*hK>vCB)bx!8{10$u_4XEvub1S``~Yi0D%8Cq%QG+q$vs;` zTPBg??DG&?f_Qq`FP;1o1LVA=cx^Ba+&a0k_c8sV99YbN9 zZXX^GpI?R_zw%EPg%^eB9E`b(Iwy%%rT%*U@E3AUl4pHr6X|lhx?#Pkh4ZP?!gMmj zY-Yss`PN`1&AC~w#>y@IiVmB7=cvKY8!h8!*_&QY~|pWv>4dMNIW0QjNXGx0XfG zdm=&a!R>(btgkl>`h(3|k~IWVOM`!<4bkgN+a0f!Q|kWyYS8uIfL`MW*Sy`t5H1*& z*HBWuQ#3~UTSjZ{HXWg-#E>Ol3lih#MPS(a{Y_fUl}~5KDS1m(#nPSk>kTW3yL3%w zYWcNmad1QTwb1o@HT5bU4i*Fzus!ZW0d@M!Wlst&J0l^3ZsKU}x=Z@_6OmRcnT`?B zy8C*+@4fgrh(MjKZPao4aI%F$_3!E~ol?On0zMPXKY-KH$nUeePxcK6Hr4l+sq@PC z#Ju9UQg~QKdrykd1KUO1A|iS4W8{;*lluw5)k}(+!D7D=5Zz|aTth18$uZiOI3=q- z9o5OZJDjfmpEG+W)`rsg9d}luPf2)1p|+qMgilyyEq#%-*l)?vJtZhD1M(}Th~HVd zjUxd~h;?iZ-mEqMf=YVjKMip?whH{Ths2!{Kb$+Ygc85*xOz~sD)n=#emCf0vScR` z_QrDhh1Jl^{wexU;OTSxjwaAvYedq0NJMm%5s3bLi>>y&M zjrj4d#CyFO!7rRogU#%}(&Lg*2fqzd%^>U4+tEP>YU8;}kE4FbcyhmxD`I53NPTe0 z!fY7FW`W5Iyx*P*a^Z+Kn87&hc_wv57NQ&>5 zodR-!>acsrntp=4VM_{|V`gj9-tQW-el8?)X4B$&ymb*GQOFzHVK)%y6!-D=@vn1O zX;`rzsTlFgn*S^Htjg@tYnacibzotcDa-qa=Ez30UV0+T!?$%G|TCn`3G; zuaB3P59r*T&C%kZb-!X83%TFFWSbS?k5U6Y*b|tG+h~?|B!-|*U)4z%FLMz5jgs@8 zhuu9dIf6;pvHF!+7_XH)MQG=X?d6JwQ3NIy2kE6-d!*Hv*Xe%eHj7NQsWxazF%-jW zv+W#f`d#Bz78Z>90?~J#0Pgq$qpt34N5ETa#tt`X>@}c0`K2|k;mosvlsd5-{B&wd=Jv5X{-#uG+nx=A~czrj<_M~6XJYqE6 z$Sc?+@v-J-e0kBG7e~k?h1j#SXCA7(MZCRKs&Y2-r>1Cj_UBha{_?5ZOPJWoDjPu{ zSAP(4`QVg_EoR9;%$j8%$Gz<$UmCqN0!f<1hy$>xZTc}rRcEoFq6LB?u0ld}An=)_ zJzLm<@>mQlDbR#AW&Ng`h!9GW&xPh|h2L4`(&f=a^U(Y&pni9$elqvmet@n z1@Iu@1Oh|lPdUq=#*g|y!0a9qo?aaPij}by)j`6IR5hxk6Tcg$@+sBma~|yTrfsBg zCwZ9$zxGOvp6<;VLZz;YB``O)ej_zjWz^1&88)Wvl`XY}ebzHgwGb3Y((^*Zr|4l* z&oU=i-9EX!e4@)k9rv5*`Gc~IFUmPVe>P?0w9fvleR|H)|1z`1qhy9(>eILI)|O}3 z8zNFzFI0oCEXzu7m8zkB7cxtvU>$Ou9Fuy6>tqtpTfWIS z>RFZR&_dbsvo(az?0$5I263a8DVUU*rHfrfTS^v7pX6Zr#I~QiXG|W?v-rdE|3tQ} zM%i87xTjUldmksy(>nNC&+_^)IHJ|veBn%b^8RcoN`E`lqp3aK%IId_v%HwEb_<5; z0J}9?S8bmvmjKVs9LQYLblWO7P);F7-)DfE#n<{XrobUuLAFXPoy@0}*QuetN~(?+ z?0uaZBo_>;aESYAnX|25k0RdWJ@9@nkVtRs_SclKs8pb3ue65>4 z&ttminzzuAl_7RmZ2ev42=Bfh7;zMcb(l^9bKu^F;)fUCYDk9bCgui`|0VEaH(R8_ zi;(}${{QucOaK6ye=`j)F96mcIS>HBi=zLx(8)+M5D~jXFTgDkXV#j-LkSAB8wPQy z=Zbtz6(<1N@d_VESma8uCM1ySmnNbCa?Kq35;R2O#|TPpc8jPtrjh`er&m`E{0fn9 zImw8dAV9#^6+7gR<;=K5J@o*;1_ob{N3PFxLc>kJ@Po3K8?C;-V68gymBkNX=3--a zH$UdB#08NKgLLRkz_kajlYv~H|JCR?flmN(LxQ0`k9LZ5zl}W&>JhY8zZIid=H+WD zW$KWhG11!V@(aq509X%j&t{y7`wi}l+dWi%Te+8miV?1BPA>7iyc}x$`P>3eqh2;M zYpL#I2=1I>n@0KMEBE6)|DkiYhspl&%FU^BY4b_qF>C}9unhn9fQ5OxKyM^f##b(oIX^z4mUZp*En@e@n#snfmU$6#8%>te-P^jj zR4kssEZw+!`Np;f8j`Kq@Mu3@gEQ>>G{T+{0GD0<+Sj{L(JR&H;_Q*{?p60IRfZv) zD^xHP|6E-Ne59oTp6b5eyxM9sj$gR+I-K+%Z)g?1h)teE6j7JXZrR$^Xq^5D&03l&;~#}M0rY-SnVoiKh9)^FfX=KC%aJFy zd1E|^<7imp1^zBtvE}C^a$*}sD{WYZw2>JyVQ&e5`CKS#?9%J+@Kb~3egKH`c4a&A zslTsSuEH=z0+^sIbrczu8Ty^wAf$oKravz{dKxgRrgX&?EZ)9e-i=#tb_tcv8o`P1 z740t>6A5nU$-fgtU+=QCdOr$O)~{$rO&)hX802aAdO#DW^Z3`2bRlo;3cSL@=o3|^ zL+atyPID<127CMBRd1xs{-iXS$*>~3O`y1x5uLyR*L-XGtN(Hedd$)UaoPBE9B09n zQv^DQn(-F#8tFzS-JT7XrT_AFc;MDyeD-r*PITb-O)5Bli%8JM_~SVGTkr5j0bU(i zW~jW#F>d<&T0QJ`@eaS~yhV=r?vrp4)zv3@mSfNWG%&3SCuw*PsjuqN=859FQyrm) zx!A`@ldX)m_w>C~@W3{glLf}f(7i)(KX4z1+V}8@)8M{3Q>bOivs!G!B?`fvpNTaT zGMYk9kEXaix@-;}dw#Zf@t(k?*ydnil2UX1UM`BNV)-<0T{qiKuCo1Q>xWJIlD~$J z#NZkqNFs(~-M;tJ>r6#u+<#r+0b1+SFTK-kd1zor{d&l~y7k9?M3vRHZ0^3${jf^k zTt*b$caaetDQ~?EEGGW*b_8puHz)T#5%|eAZvl($=J5=5HVe*Ku!p<=5c~^?`)SvY zuO)}?gJ&MU6-5Cdm}ZxsBGYvMH}Hk)KQ0asc>4@efY*LNeRJ7S?vH-_ak0hpk|Vq< zJGtf%Gja@GnrvVC0|TJz#c_8gaJBVswxx!zA0`8fq1hQPg7EG^API<6?pA?(xuhNQ zKkLM%AA0^CD0QhF-mIBI?gw+&JllqgfV`)Cn5H%S2|B5$9a{KXGCq?JIs$X{Ek&yCs_zV1AonWW6n&{PH;`Py9-}a+$$7*tNx(D&y zFr!>tO>wNVpa&n7_VG{w-aT4hex%^`u*gc_8*$A%=^MmZUcfTuRjv@6c1+vw{gAi; z4*8ggKUWE)=c$MvVN%YdVk;!%d28Wth#(532~PbI5?smd@6cvnkExMaG@eI_DE3|L z-|oD(eCMgF@Ofp&pMshY!fdZSf<5u=bM))c1W%-1ll&2L3M^Ik4|+(k2sG`jdGI)0 z^E{4Qcx7!cY+VLtPVA_bcz^E^82SF`b_@1)5aIk3r}w0|6Kwuym@sv?*o4R6mH*%2eO;4NvJC|()BdZDGj2XPzN^`#vSj46ug_Xprb8eAB`lgG@3Hl%XZwXbo8(vs&IFY|Ie85G5HeO*OTul zAs89LQ!4lUwQe<^IAyNj<+}HH7jgAA|6q#VS->UxIuoOP>+=@5AJwR|JS^CrOW+2) zT%|1Mc?(C;`~~!iP2gGKHi%1^3QIWAVxq{GEvs(lz%}aq1;fycxoi&Smy$E^n^`Me zE~aujE+X=2u$4jBXr^2k$;+f%-@7s1o(6Rv1O3|MnXyS>4F|Q#3Kkzn<+?yUwd2Wk*c)w~i?d z&z&iezx$~9d}(+Htue6#H7R=kU5fXDd)hdfB>-zmA6`zWk|WXT{N?-Ty<`S}&4jx+ zqS)xuTf~K=jg;Ck{YI)9D7xae3X`V!V~G}w$rwaS+BM9A*L<)21u|i`(8GUNW4pfJ zNTsB+g0De>?WPG@0kkCpSB_&KZ;TSgqp?+;i9LoZMiTNGeY8v>qS|=L;d%ud7Jsm7{4?o%;sjSC!LDfw*q;; z37r<^)=4D+tuEOF^nF>Mvh4zShR+{2**-5(zl)RuQ6NiW?r=j@)}Qz#yk~*Lu>Epi z@Dug#!QjXf$JkRF#MKY1@78Sv7MDiuxQ>tct}cAq`h5EBrdLUPZH`5RhSul~gJX*x z&yL$WThCLPS8jC=Pb%%58*~(>I?@`NNuo?>H=DM=j3}Ucv<}Yo<+f^{- zhL+-KJu7I%Y>PpkMjvGnUq3vm+u|NQ3)1!Fa4dBC6h9*BX-&l(Kw;qsB8`%WHyg1e z>do_+P_LVlFe?+XN@j>-Nb2CY@d?+@#>ef)w1Sq|m=X=H)}XvrIXmkG(5qZP*M+DSRG!sTHDj`JMbnlg>ox=;yosF)Zq$U0qds>Mg z3<*nbzHmf@qIcM6p43E0zto#DH&&?heJ&qCHuFI0sfOf3s)&h_V$7vaL@|Ei?)7}F zUJJ)IzANU0bE{G2;PSlmYM`tRqT$~;T{{tDc@4MGJ1$7*2kCI|$3-4NOPhy9Ox~rv zFDXkqOKfK@ZF)zK>>ato5+2>QMUod*RX^2VcMpu82!AoH%;+$Z8lrL_<2zJ3ibOez zCPO$REEaUF-h%%8zOO*O9y(

7_nnO(Z&c(Aj)C!g0wWiudrS3ZmriVbWzHM?N!dUOO`aJb_p*;}JTFr`oY?j_FZE;1Nk-nu_gTuF!-jTvhqJOX;V8nc^51^2BwD z8UjuBgn6qBeePNESM#GKshZ`rHJ6jL>~#VJXp*46f&=4QD5!ZOc#zG7j|QM6DO|mr zstG8c4$l%?SLK^gI2am0#^z75pBCxTEIuG9q}|C<(*JDn!HlCf>ac`h{~y5XT!RFs zj9L927!+nHOi4PSm1uPfoengGdFI}^db%?nH>fQ0)Hygk?<5c}&)kM`M+^+;f6?vT`$zAMuPs#pUe+&}tZg zKToD&@kAfZ`+Bk+2?25yaw`1#g$gCwh6Y8x1@tVyi@$+@r%VkA-7pTW!8X@tbu|9| z4MqPO!BY`(Wk-Fgm;bby3IN{Zg)kjrz<1*V1u3vNyx7cPx7qs|2$X6k#Ov7D`Mv}l z$!PP^`acstZb!CStnZOBL_jw9P;r_!dHy$wPtCc<6ZRnPvF6KFKJxc0di9NJ<$|au z>2xaP(%Al&<@Tz68ny|NKO`S~E=wVPu}77kq^JJ6U_@^JkeT(dpNs3u{CKkm!*ea; z4rxq3-Yd?}<=7KuWNo!t7|Z6wui%XV$^64x5cPH6f|zewkCPPc=>%tO*$9E7%~c)V za8iEf<<(YZtv9=RDo;6d45`!m*?sP&kz)o4h7|A}9QXeR&$?x=viHECGNLlg8l%{2 z6>v~Zs%<~#TSP z#f!ZE6MLHQjl63+&YWuU?A^FTEzp`=qL((0gFkqV-qVN)GaJde(NVvAd()G4N(m}^ zsns`IkE?tL+(ITSzFsQ&ly>*nkpNNhLpW4hYIC+1~s<|>ZGS}8iw-d4cpwh z7Ld00kb0C&1Yt{9oOg7%LPrljlg40+TCGKP@figc#|;-$Y#|6G@vRa&ly5CpY&8tJ zm+*yd)6O5tu=g#JL*3V&Pj%IAZB3KKE6SKHZ^A7IZmyDNZhE!MTcoLvlgtbZl|i&r z{U_`3cL!Ad-390*It!Fd6mp9ACr|$a@Bj6N$Ep9@|Mstm%>_P|{*4S2{dXflMM>j% JwZgmL{|2{E_3i)w literal 0 HcmV?d00001 diff --git a/GLCM_analysis/dtireference/Test_GLCM_Features_02.png b/GLCM_analysis/dtireference/Test_GLCM_Features_02.png new file mode 100644 index 0000000000000000000000000000000000000000..5b613e34f3dd475d6951f8c9eb3dd42a01371aab GIT binary patch literal 8120 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 literal 0 HcmV?d00001 diff --git a/GLCM_analysis/dtireference/Vectorized4VsNonVectorized3.png b/GLCM_analysis/dtireference/Vectorized4VsNonVectorized3.png new file mode 100644 index 0000000000000000000000000000000000000000..fe197a17f4cda0f5fff04090ad65a17b0fd0dd9b GIT binary patch literal 7195 zcmcJUcTiJbxA#Ml-b6&YK?qekN{7&-ccd4Q4$?#D0hDTi7?9pUkR}45H#LA@=m^q5 zdJ9O65dt^A=b1bAdH=XG?;r2`$C)#0?RDntIcM#)zn{I5jSaPEso1Ch006CywuUJH zKr9Xb5S3976Ffz)lYSF!l>XY*K>z?`sOJ7GF@f|DGgW1vYsM|y*qi}87+sUg92 z529%WQ4e%=f_VD*0?j>rTmj+_L{$9)MI^-~#DNkIX;HKaO zs4-{*;(%}fg({GU;W?NXNE%BDrXU0`{J#$^tc+u^CKdB{$KCD^cQV^c-g{;~eDjWJD zz~=jDbSc%1iQPx4G+>TeKQxQY0sET<@(C8r>eVh;}`mgoJV>hAdgqm&Et zJ6W%h(VPHA9SYh;`w!((f_}h!9X3x=|NeA!bnWIP0@_l!!S_I4iTj;=%n3B`gA~Ey zy&?auU2n5dZL@BE1TDL`K6Hj%PT9yy2Ocg?qlq~~jpz*YFMPoWX7`3jSUxJZFq;Lx zwyFH>>f4*l_$UK<706n=oOHb@3bi?Zu0%c7A!SoTp4r%XTE92u($ z1a-LNhHmmD@{n35GQf7sU$=Bc(G#iUSBsq)B8SBE@A+?W)7|nu3rMpdWTA)Nf<&1V z&s{>S@3M6_*Mu37BB&R42Xl#9^quKSoM97s;juneOf}h^s5qYjWG}5rtPttAF;&~V zj@_&s*_&i7(G1+~oS5v^$~+&QXFU0hjI299_O;ye>{-SXNtwqbLsP9jmVIU&9&Na| zH0j`OyYJ4y;hU0{TjOwj6!m<=_V+-pUzFmiMvJv~SdNIfyAk zIk}n4cBZfC|F_IObjX5DR8VFPlgHw)(RtAy#jNZP*X!$vhi{>?60!v46hb5H!UwxK(p0D z%^wG*mii5q@iQUT_C88&zfZQ9HcuSW3NwGobU2l3R*B;(LNaVU(}DdQ^8jm(g$Z>~yF{FXcyz$GzI^+PAVRGIV!0 znKq3ICk8V_GhBSXUP9<0l_SVQvWe{im-~NqMDonCj8v{euj85?sE#}>_k+v8KaP;| zq(zDa_L*ggCFV!Mxy%DQqTMo@`}CKAen8N>c8$W5o~?KB`~`CjpP;Q92EGm9c)hcB zse@rYmFSl0M%oar{1pzNUej~L;^j=~luGdSP81q{%crK`Ws82S_qE-c?Iez_qWEwb zGj_yZ5u%n9wRm7zu9by&F^B@R-&7E)>${1{tLIR{8HUe7YOQvA39!J>!(uRWpw1Som>;(r6yx2-1 ziZNuMQdtdF@D1Ua5E{X31(}UE`@d8-Bh@*=NCf4?99P9HE$aNQ)BtP<8F+af0}Eik z(Ub(h%|un^Iyf>%1sHNI`~lAsUzbW_qG+v{q+VYj-fLS!FiLC zJG9sfq!7i&s7B%NaSrKs>x-i+tj6g0r1u*UZ0e6mur4%R+>zDkQy~5N*wro%aWdnk z+>iat8_cWE@EulBWefKeoVEQLo1h$!5o9){?X#TI1?KPgM?bQ1iT%Ee~ zgpF1gnitT(PFg4KvnTdmyWZkm^!Ap(Y`vijh3Q%XZ1?T{x751f;9~mM`FH+W)J2Bg z5WT6Ukr}ak?NWQc5}~>M781a`z8@>?+P^D4aYehu8pPu11(EsCH;&+7UqJoJPLM8m zq#g^-;d`K1z`W}IZDc9em%$)>_wy*8R9?(2mDfUn zfzH}!>i6b!CzjzhpS}qj%%4|STi)-$c_~#H((fEmE$woicUg^3!|jei?;c6};jE36 z7nE1KK1g9A?B)(C<7V2cl^M6iLz{iiw7c?Ks?T<^RSrVx$x2d#D{@rmDsu;evCrLK zy$=rsPdl88y}GGgYWSF4J)Bo_wQL+GhHm^q(ssFo?q-wgbV#TDTQ#-j5HkI(I>O4d zK}ImNm1m^;`VE&(cB#c$r-q^k1c)zj0oJ-1Rn!T~_06vMicDLFv^5K*YO8Ma!#62! zR{Vet!YcSj`s4U+WG5Ztu*mL;wQ-u|Jo3&L6&IW8pPlJv!3^ zCZtqE-6?c+Pub5%3(67W+{Zmh>vUyMZzFM5D2(&L6p2*lUR7$GuRSLQYo+hETZACp zX1EGi#p<#o%8{yy8*a0l4ilg7*0xP9Ia5$i#<^XM1R!gX81)yz@((D$LKsZv(E>G4 zVnokK$mi-%e+%1g9=|H@_M@?Uf^;~NEnAN%^Aa5%mtVLic4x%)<5Kim>`Oua^*4;H z{$;24J9gkR`>DCXDbrUdr8BD*_k7L~uj+SH6BIKRPVW;ctJASJ)0S-)=p1r_A9fYk zs%zbxR`ENs2j~jQBtSxS=BqNxHu*=aebn8>WXCusy9;l*Pg@LG`v5wQ$tF5QGk%4n-g(T z%@!CzsIs1+ZgW@nJEqC80IoZcFP44i1^?{PflGdIO{{#jib+9oY6BoBq~E_4^BATq z;cLkoH%;$R-T}l5qEr*=vkVdb$^Vl2&@C!qp`@ai;OXZ+*)rphURwKh!k-W-vk6rLx z4|Ji6Ie(AwQC`t^8b=O9=8y3(=WbW^Pil}o(h1b+zKP**(pVXVPZqV6d!Y=^leFEJ z52YpP2YBz};=$pjXNQ#Ty^*O;n_r47)p5M$R(izd!-~DDQaF05j$sZM+R8pAosd$C ziYWCt>XA~9u}6E<(GO=w$EihOZMWV>#*|WwQXgYz|NPbPHid_HG5$VdjsCEdRY3Rp z%~>|dN>lp&|B4SeNX7HLS(JT6Fvvp8@hW(0T+IIZve7?O3}2tYS^GU?eREoA*=jY& zeelP|u$b$R*{ISS(WlOAF2-7+&hN*8sHmBkb-s-Fgec-}1tLkHXh)hEjfW(6E_ z&S@@;8BNBIZ4Pz{j8{EN6(?n+wZ#Ozwml#JRSpf?kQM&C6v~W_o9_vO^HcLUYx~cd z?OCRHO5l5fnot*Q0m4a-faA@m+OTqR&gcQlecchAoE;M&6G%Z|Yge&74WzLB0$dX2 z`fwJlCAXi=X=uyR91+^1!Xxo0D1Coh)pW&%xuf~(nyKr3$}D_oQaO$oE9BRcxsUK< zLqP)-n392!48`h_3Cw~7f$%T9!iNLY#?=46aMrdQT)EH)!}r^vHuA5HC%@lV5Rhn$ zA(nLXA~NBy1#fn1^t9vzi=>+;5 zKg(CY6-&xsnfbm=gqX5mT&rGhN;D}GlFUdf*p4%=$K`z<-D-TG>EAw>y?3}U`styG z$UtXrZRU-f^AV05in1{Ta)v&2Bbd$)=Jxb7HTOcw=juo~NRgE3ylP@0V=NZZdWXYH zCd^?wv~0V6VFcE*jG`O9tV{gqXC6H&!1TBS;jjeK?WHY~iog~_(<z2Yi`*(ly5EJ&5k34X6+unx z?YBfusEwfGBfQhQYkakVdg}dw zhIj%bUy1|2Y|K^MFiz38fl^o5`V1Zp+vfkgvt{q_Uh0d79Q=NwsHXxP>XvSB$53T! zDWlKMO2+Zf>1^ssN!HS~TFShjYLWINcKu7i_h6qw`W^rI(|p0nGIEjsV6Ms#^nO?w zyUf3s>)UW5yvNZKVqMHNvCCZ62N(Ev9{2bBo46pqEdB$ynpCvUpF8?qB^!oo+r8@o zNct3u;ypv3&S9NY!1xM3*QModlFCE(5L-sI6Lg^x%aPCVIsCkZ0aLBXPY>Pce1^aRnvi->Wi>d}ME_DSlYE-?45S$=+ey$%*X@b6ynY zHaBV0q1A~U`9sSP$3RtrS%b$cgxAhd7RQh>F8tVVYxh$VXjO}qR#9^`t|QUCsYWaK zQ#~BLFWWH;;eR&eyVrV``-cFiL(A3bU|w(tJGJZcZ2{af9EfS%3A8bHn!}EH4~n7! zmkpg@pax3USX2=Bt()(L*`6==c2Xf{5n^NZE4ztgox9I7}JP7L-97^*h)8T{F?=OVwIesMI z7#%1g)#y-XM5dR12_u&GHLv<3G$xcC)G-nqMs?!p;e~6x(b?!A({9t02DUSW%wY+1 zQ!$qE6sF&MYt$E~maiC(gW2yL{k&d!c6<`jAwTcGH9qKm)i0{Dsq26FfxxIJcFCRk ziy*2XPzSi5{*Sb^7I~8UZQXdGib8*?lT7r{Rd<_%Og)e|n@L`rdHV&*WU%5Z($D=h z?SSBr94hvMi|d>WYGqOG8{Z7Uc<(|Err03%bZB@L1mOp$nrEGJ?v~Y;+yo|B*8O1M zzUdiH#5*v|LO72~FF5C{av%qD1eZtY@ywMtkl$Drna$6Zd}2ccP(R=@HLcX+5S{hE zs)2aL0BX?=4Y^{+U4JV?wnjUPQZ+4hgN+{%GR2jPBIeNp6^v~?T@n2-IU^v-BjSC6 zRK-dzZ2Ijg8Hu*B{(LM%n}P^g@(ZyzbCEqwC-al8$a5oH+w93}a(?_$h@6}thp$=P z3xrS}?5S*~&PihdedC|EN&tH*r356K;+7a`5jSlrx9UIdwAz_8qT$c@M6wdUn+GEX zFzP}9amIwK(kM*+L<3X}BLE@EXCaWnAMd3%EvMv6%ztHh1@n4H2 z%3ZV|1llSYvw@-!i(WTVTV`z(4o+|vhZpz@`qrBKH$LZFrhz3^S-Ewu#jV=Nxqkkb z;F%@y%=z(zCHZ|A9WLfG%EmUl%y`g{O+x2;zzcyAsVdcw>>pst>6A5*)${?xLsHKv z(O3;pf*t&P-wCAo8(1r^3OwR9Lvp|3)jp5rjCPprb*>l}r%@VxAf8r2!%d3%)ZEsS ze($2^YN_nEr!Gceoe2ydHa%ZCM(AZKF+PDLnY|gh62~CcK+yG(L^i^2HO=_pOp{*qP!9Zz-0#Mx6DU{oQEyVd2V7A9s)4@t zFgS76u8OWE92$t?`n5k!&m!FZfLrPoaPWlZ@7hBMRc2PHLo3ZMkjUq|aso2?!&u58 zwu8-WGXHgS6i(pnY(U-EL3i}Q;0?E?GZ19Z_ra5LYDX3o9_~}ofQPNsrLw3;CZX*k zb}1DM>wUi{i%F7`8Nw?mUchwj@tIK~b|fC#YzvQ5$1-IyRFz*S9k6dnTIHK8;;A*Q z;|-lgbPA)54wdkwd9o*~ExInYmde+AFp!VC?$9Ny?52^hJlZ!D&k^@HTrKv8$XlP< zP3h~s>8GSvNwRx8zdp|l)No>bcXNRD+As(7a>~$X$l8VMSt#u{ zZYAe7zpl$EzW3$d?$ioa)=q!5C*I+=mFs}TN}Zd&zad@=EX$j|0E zy;oy?Btl`q^p)3F#;cb*G*o%$C$j)g(!=w9t_i&h^=i({T9ohopJYtf5-!u>E91rS z9Fqx7+*O2Oz74B$?ZcJSE0Ri>y>Ia8Rb|8yE*NL-oH6iRA4lS~rvUFh`<7UcPhh^^ z<=mKNj!?tp*i%nG^^m5?pm&U{43C#%&F6P(njPJ0l+==GD0G0XaER);<=rYqnhA;| zEnt4oT5DdVY;#b$03fRM@H+2SpPJ#d0zCFx(C1oN+3Sj`t)?+NJTUUjh_{>1Iho{kbuCR zJPRJrc$qX^pabulOUurl%4OQc+Zfu?PL=JxVZGPn9wr&Lvqd5HgE=%2pwybRK<_?I<1Esq8d zg3AvgC+{xk6KBkIIoftF`+dfGGgVP7GQ^r|=jDH|WWAZgR7@K*u8TQ&sNrFh=SFjs z@Mx1LI}XH8S;klu{aBV~C4%Xb&i-#0et^XkI^ltCrN-eR%kO%%B#|f&xq#ruRA)C* zn)|LtXo${5OS_bju2(q9vp&BhOA#J&#)3QR)Et;I%9#R+;Vja~sQ$ZEGUekW&dyPt zfKU;T!vEI8NwyH7KM6k{nD(Sho_*P)O?CGfD%V1@ zpap#mUk1B;?6d5gjPX2Vu^RIh7aVIDQIOV3dk49Zr*$#~eUiV<{kYZ#zdoU%JP7k@ z`Ys_-ejV}=8mc1Wd!v|wHz%a^!RTqx8a?i%{UEEhloC~Mu?xATeZE#mg9|w)gZ63B z5MKmNAW^9i NL) = NL; +SI(SI < 1) = 1; + +numOffsets = size(Offset,1); + +if NL ~= 0 + + % Create vectors of row and column subscripts for every pixel and its + % neighbor. + s = size(I); + [r,c,h] = meshgrid(1:s(1),1:s(2),1:s(3)); + r = r(:); + c = c(:); + h = h(:); + + % Compute GLCMS + GLCMS = zeros(NL,NL,NL,numOffsets); + for k = 1 : numOffsets + GLCMS(:,:,:,k) = computeGLCM(r,c,h,Offset(k,:),SI,NL); + + if makeSymmetric + % Reflect glcm across the diagonal + glcmTranspose = GLCMS(:,:,:,k).'; + GLCMS(:,:,:,k) = GLCMS(:,:,:,k) + glcmTranspose; + end + end + +else + GLCMS = zeros(0,0,0,numOffsets); +end + +%----------------------------------------------------------------------------- +function oneGLCM = computeGLCM(r,c,h,offset,si,nl) +% computes GLCM given one Offset + +r2 = r + offset(1); +c2 = c + offset(2); +h2 = h + offset(3); + +[nRow nCol nHei] = size(si); +% Determine locations where subscripts outside the image boundary +outsideBounds = find(c2 < 1 | c2 > nCol | r2 < 1 | r2 > nRow | h2 < 1 | h2 > nHei); + +% Create vector containing si(r1,c1,h1) +v1 = shiftdim(si,1); +v1 = v1(:); +v1(outsideBounds) = []; + +% Create vector containing si(r2,c2,h2). Not using sub2ind for performance +% reasons +r2(outsideBounds) = []; +c2(outsideBounds) = []; +h2(outsideBounds) = []; +Index = r2 + h2*nRow+(c2 - 1)*nRow; +v2 = si(Index); +Index2= c2 + h2*nCol+(r2 - 1)*nCol; +v3 = si(Index2); +% Ensure that v2 is a column vector. +v2 = v2(:); +v3 = v2(:); +% Remove pixel and its neighbor if their value is NaN. +bad = isnan(v1) | isnan(v2); +if any(bad) + warning(message('images:graycomatrix:scaledImageContainsNan')); +end + +Ind = [v1 v2 v3]; +Ind(bad,:) = []; + +if isempty(Ind) + oneGLCM = zeros(nl); +else + % Tabulate the occurrences of pixel pairs having v1 and v2. + oneGLCM = accumarray(Ind, 1, [nl nl nl]); +end + +%----------------------------------------------------------------------------- +function [I, offset, nl, gl, sym] = ParseInputs(varargin) + +narginchk(1,9); + +% Check I +I = varargin{1}; +validateattributes(I,{'logical','numeric'},{'3d','real','nonsparse'}, ... + mfilename,'I',1); + +% Assign Defaults +offset = [0 0 1]; +if islogical(I) + nl = 2; +else + nl = 8; +end +gl = getrangefromclass(I); +sym = false; + +% Parse Input Arguments +if nargin ~= 1 + + paramStrings = {'Offset','NumLevels','GrayLimits','Symmetric'}; + + for k = 2:2:nargin + + param = lower(varargin{k}); + inputStr = validatestring(param, paramStrings, mfilename, 'PARAM', k); + idx = k + 1; %Advance index to the VALUE portion of the input. + if idx > nargin + error(message('images:graycomatrix:missingParameterValue', inputStr)); + end + + switch (inputStr) + + case 'Offset' + + offset = varargin{idx}; + validateattributes(offset,{'logical','numeric'},... + {'2d','nonempty','integer','real'},... + mfilename, 'OFFSET', idx); + if size(offset,3) ~= 1 + error(message('images:graycomatrix:invalidOffsetSize')); + end + offset = double(offset); + + case 'NumLevels' + + nl = varargin{idx}; + validateattributes(nl,{'logical','numeric'},... + {'real','integer','nonnegative','nonempty','nonsparse'},... + mfilename, 'NL', idx); + if numel(nl) > 1 + error(message('images:graycomatrix:invalidNumLevels')); + elseif islogical(I) && nl ~= 2 + error(message('images:graycomatrix:invalidNumLevelsForBinary')); + end + nl = double(nl); + + case 'GrayLimits' + + gl = varargin{idx}; + % step 1: checking for classes + validateattributes(gl,{'logical','numeric'},{},mfilename, 'GL', idx); + if isempty(gl) + gl = [min(I(:)) max(I(:))]; + end + + % step 2: checking for attributes + validateattributes(gl,{'logical','numeric'},{'vector','real'},mfilename, 'GL', idx); + + if numel(gl) ~= 2 + error(message('images:graycomatrix:invalidGrayLimitsSize')); + end + gl = double(gl); + + case 'Symmetric' + sym = varargin{idx}; + validateattributes(sym,{'logical'}, {'scalar'}, mfilename, 'Symmetric', idx); + + end + end +end diff --git a/GLCM_analysis/dtireference/header.mat b/GLCM_analysis/dtireference/header.mat new file mode 100644 index 0000000000000000000000000000000000000000..3446fb33bcc48024f9150ef84afe8c45f8bac2c1 GIT binary patch literal 348 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSyj5-`93qo*%FkbMP+E9N|%ahB_l0nhQx zKO2`nJlM?t(6RiJR@FDzQ&!vMZuM>Hv)wnh>_?&G8@2xq9zm1ZJkg{TJE4+1$5rM|CvI?d$K|UtM1RYl`3WkGmZ0 zeqTCLciq_cna-MzJO@v%akP+TIoGCp#3oi(g<*NfIZcLhm!`xx7F2Cxn6ve&!1I9f zodxSNE}C+@S4@wMRxaq;*7P8U)w!Upo3$~x=?nfNGBmO>uv9QIFf>yj5-`93qo*%FkR1-h6>}aZCnQWrNJ&Uw zz9i$olhVYfJ>@);D0AY3S$D2X>iHwW#%8B*yMb|GKdZ02hpq6WN+ySSlNl?2-H|zY e`T1+6i|LLI^4eW?9QI2z3@t@Hm>FVfI8*>8Hal$q literal 0 HcmV?d00001 diff --git a/GLCM_analysis/dtireference/stat_ans.m b/GLCM_analysis/dtireference/stat_ans.m new file mode 100644 index 0000000..9b71d3e --- /dev/null +++ b/GLCM_analysis/dtireference/stat_ans.m @@ -0,0 +1,58 @@ +%创建27个ROI的excel +for e_num = 1:28; + clc; + clearvars -except e_num; + + load('I:\Data\codes\roi_name');%加载roi_name raw1 + stat_header = load('I:\Data\codes\stat_header'); + method = load('D:\Documents\MatlabCode\dtireference\method'); + filespath_excel='I:\Data\NC'; + filenames_excel=dir(filespath_excel); + filenames_excel=struct2cell(filenames_excel); + filenames_excel=filenames_excel(1,3:20)'; + %roi_name = raw1; + roi_load=char(roi_name(e_num)); %当前ROI的名称 + destination=cell(28,1); + + destination{e_num,1}=strcat('I:\Data\graymatrixdata\analysis\NC\Ans_',roi_load,'.xlsx'); + temp = method.method; + header = stat_header.txt1; + for sheet_num = 1:4; + sheetname = temp{sheet_num,1}; + xlswrite(destination{e_num,1},filenames_excel,sheetname,'A2'); + xlswrite(destination{e_num,1},header,sheet_num+1,'B1'); + end + system('tskill excel'); +end + + +for i = 1:27; + for j = 1:4; + clc; + clearvars -except i j; + + load('I:\Data\codes\roi_name'); + stat_header = load('I:\Data\codes\stat_header'); + method = load('D:\Documents\MatlabCode\dtireference\method'); + write_co = load('I:\Data\codes\write_co'); + + roi_load=char(roi_name(i)); %当前ROI的名称 + destination=cell(28,1); + source = cell(4,1); + + temp = method.method; + source{j,1} = strcat('K:\Data\JHU_AD\graymatrixdata\analysis\AD\',temp{j,1},'\',roi_load,'.xlsx'); %读取目标excel文件 + destination{i,1}=strcat('K:\Data\JHU_AD\graymatrixdata\analysis2\AD\Ans_',roi_load,'.xlsx'); + + coordinate = write_co.write_co; + xlRange = 'A21:A40'; + aveSheet = j+1; + for sheet = 2:23; + [num,txt,raw] = xlsread(source{j,1},sheet,xlRange); + ans_Range = coordinate{sheet-1,1}; + xlswrite(destination{i,1},num,aveSheet,ans_Range); + end + + end + system('tskill excel'); +end \ No newline at end of file diff --git a/GLCM_analysis/dtireference/stat_header.mat b/GLCM_analysis/dtireference/stat_header.mat new file mode 100644 index 0000000000000000000000000000000000000000..1155ddb95f246f1d1432c37d0b30fdade4871770 GIT binary patch literal 344 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSUKwL5B>5Q{nhYWa*8!vy9 zS@Ge4b47svKEKFk*PL%pEKBXrUoKr2!?ydRy}+a?OCGu}(ADjDQK4{4ZMXNVi{56* zd%UWu);$;b<>2}$|I4}f|4-5v+rQl`pL~@yT+RB*{Pb6!*Z-OmvL@}d+Rr!M+`oSw z=(hAuZ+0l?k`Op2*0@=e-O&HO2HS&_w|m(htjSR|Wl0xcKXB86xsZ={4#)Sdz}oH) za-Yr}XKM^TD%E7H)%d_ioSR9#`OIX;XDi?SWja)O^g&AZ2m2*A|A; 0.05 + tvalue(i,m) = total(2*m-1,5); + else + tvalue(i,m) = total(2*m,5); + end + end + + for n = 1:22; + if tvalue(i,n) >0.05 + mark(i,n) = 100; + elseif tvalue(i,n) <=0.05 && tvalue(i,n) > 0.01 + mark(i,n) = 50; + else + mark(i,n) = 0; + end + end + + end + ans_Range = 'B2:W29'; + xlswrite(destination1,tvalue,j,ans_Range); + xlswrite(destination2,mark,j,ans_Range); + system('tskill excel'); +end + \ No newline at end of file diff --git a/GLCM_analysis/dtireference/txt.mat b/GLCM_analysis/dtireference/txt.mat new file mode 100644 index 0000000000000000000000000000000000000000..df90f4c40ee6428941ebed1f566bea169d29ef10 GIT binary patch literal 212 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSGGO@5SF#s|Q%@l|P3^2gx>B|pf`v7spoX5!t2_F)Y6Bv}( z_!QDo8W_Sf;@Py0oj7nNASm$A0rnJW1BEM_7p!Dond)TZ&Tyi*BvIn3`KtVo`wTBX R7s~;e{dT_?%yVT|0RX2nI;;Qy literal 0 HcmV?d00001 diff --git a/GLCM_analysis/dtireference/write_co.mat b/GLCM_analysis/dtireference/write_co.mat new file mode 100644 index 0000000000000000000000000000000000000000..c9de7c496671b67d7a7d15c57d733b488a885fa8 GIT binary patch literal 277 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NSHc>D#Ff>yj5-`93qo*%FklhQ!6>}aZGcbj*v6(3x zWjxZuBXEH0X}9B1iG_bYEjlyl%8w^Cb_%x}7#H@l`pSFQ3QwwJa+o*SkeS)?SImhk z&)t^U@f&@uoVfCQyH9Oh$}4V#;CO+Vzno575qDd*kHhGztKiChNmqH}W@UrK$xF|- j`qbv7y!xyVJYRg~uNt5M?#uQu7=2|FHe;~dEp;0JGjdtk literal 0 HcmV?d00001