Code covered by the BSD License  

Highlights from
Multi-Scale Analysis of Area Fractions Characterization GUI

image thumbnail
from Multi-Scale Analysis of Area Fractions Characterization GUI by Mark Tschopp
Characterizes a binary microstructure using the multi-scale analysis of area fractions technique.

gui_vmsaaf(varargin)
function varargout = gui_vmsaaf(varargin)
% GUI_VMSAAF M-file for gui_vmsaaf.fig
%      GUI_VMSAAF, by itself, creates a new GUI_VMSAAF or raises the existing
%      singleton*.
%
%      H = GUI_VMSAAF returns the handle to a new GUI_VMSAAF or the handle to
%      the existing singleton*.
%
%      GUI_VMSAAF('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GUI_VMSAAF.M with the given input arguments.
%
%      GUI_VMSAAF('Property','Value',...) creates a new GUI_VMSAAF or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before gui_vmsaaf_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to gui_vmsaaf_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help gui_vmsaaf

% Last Modified by GUIDE v2.5 25-Jul-2008 15:09:18

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @gui_vmsaaf_OpeningFcn, ...
                   'gui_OutputFcn',  @gui_vmsaaf_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before gui_vmsaaf is made visible.
function gui_vmsaaf_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to gui_vmsaaf (see VARARGIN)

% Choose default command line output for gui_vmsaaf
handles.output = hObject;

% UIWAIT makes gui_vmsaaf wait for user response (see UIRESUME)
% uiwait(handles.figure1);

clc;
I = rand(512); 

handles.I = I;
handles.filename = 'test.jpg';
handles.X = rand(3);
handles.Y = rand(3);
handles.Z = rand(3);
handles.AngDivisions = 4;

axes(handles.axes1)
imshow(handles.I)

axes(handles.axes2)
imshow(ones(100))

% Update handles structure
guidata(hObject, handles);


% --- Outputs from this function are returned to the command line.
function varargout = gui_vmsaaf_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton_load.
function pushbutton_load_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_load (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[filename, pathname] = uigetfile( ...
{'*.jpg;*.tif','Image Files (*.jpg,*.tif)';
   '*.jpg','Jpeg files (*.jpg)';
   '*.tif','Tiff files (*.tif)'; ...
   '*.*',  'All Files (*.*)'}, ...
   'Select the image');

handles.filename = filename;
handles.pathname = pathname;
I = (imread([pathname, filename]));
I = uint8(round(double(I)/double(max(I(:))))*255);

handles.I = I;
axes(handles.axes1)
imshow(handles.I)
set(handles.image1_menu,'Value',1);

% Update handles structure
guidata(hObject, handles);

% --- Executes on button press in pushbutton_dmsaaf.
function pushbutton_dmsaaf_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_dmsaaf (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[ResStats] = compute_homogeneous_length_scale(handles.I);

L = ResStats(1:end,4);
CV_X = ResStats(1:end,7);
CV_Y = ResStats(1:end,9);
Af = ResStats(1:end,3);

[alpha_X, xi_X] = fit_MSAAF_curve(L(2:end-2),CV_X(2:end-2),Af(2:end-2));
[alpha_Y, xi_Y] = fit_MSAAF_curve(L(2:end-2),CV_Y(2:end-2),Af(2:end-2));

f = @(alpha,xi) (Af./(1-Af)+alpha.*(L-1).^(-2*xi)).^(-1/2);
FittedCurve_X = f(alpha_X,xi_X);
FittedCurve_Y = f(alpha_Y,xi_Y);

% Update graph
axes(handles.axes2);
loglog(L, CV_X, '*b'); 
hold on;
loglog(L, CV_Y, '*r');
hold on, axis square, grid off
loglog(L, FittedCurve_X, '-b')
loglog(L, FittedCurve_Y, '-r')
title('Anisotropic MSAAF Plot');
xlabel('L','FontSize',10), ylabel('CV','FontSize',10)
h = gca; set(h,'XLim', [1 10000],'YLim', [.01 10]);
text(2000,3,{['\alpha_X = ' num2str(round(1000*alpha_X)/1000)];['\xi_X = ' num2str(round(1000*xi_X)/1000)];...
    ['\alpha_Y = ' num2str(round(1000*alpha_Y)/1000)];['\xi_Y = ' num2str(round(1000*xi_Y)/1000)]},...
     'HorizontalAlignment','center')
hold off

% Set the text boxes
CV = str2double(get(handles.edit_dmsaaf_cv,'String'));
Af = ResStats(1,3);
LS_X = 1 + ((CV^-2-Af/(1-Af))/alpha_X)^(-1/(2*xi_X));
LS_Y = 1 + ((CV^-2-Af/(1-Af))/alpha_Y)^(-1/(2*xi_Y));

% Unfortunately when I set up the coordinate system, X is in the vertical
% direction and Y is in the horizontal direction.

set(handles.edit_dmsaaf_xLH,'String',round(LS_X))
set(handles.edit_dmsaaf_yLH,'String',round(LS_Y))

set(handles.edit_dmsaaf_xalpha,'String',round(alpha_X*1000)/1000)
set(handles.edit_dmsaaf_xxi,'String',round(xi_X*1000)/1000)
set(handles.edit_dmsaaf_yalpha,'String',round(alpha_Y*1000)/1000)
set(handles.edit_dmsaaf_yxi,'String',round(xi_Y*1000)/1000)
set(handles.image2_menu,'Value',3)

% Update handles structure with new information
handles.ResStats = ResStats;
handles.FittedCurve_X = FittedCurve_X;
handles.FittedCurve_Y = FittedCurve_Y;

guidata(hObject, handles);

% --- Executes on button press in pushbutton_vmsaaf.
function pushbutton_vmsaaf_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_vmsaaf (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

AngDivisions = handles.AngDivisions;

I = handles.I;
MicropicO = double(I)/255;
ImagePower = log2(size(MicropicO,1))-1;
ResStats = zeros(ImagePower,9,AngDivisions);

h=0;

for RotAngle = 0:(90/AngDivisions):90

    tic
 
    h=h+1;
    Micropic  = MicropicO;
    Micropic  = imrotate(MicropicO,(-1)*RotAngle,'bilinear');
    Micropic  = Micropic(floor(size(Micropic,1)/2)-size(MicropicO,1)/4:floor(size(Micropic,1)/2)+size(MicropicO,1)/4-1,floor(size(Micropic,1)/2)-size(MicropicO,1)/4:floor(size(Micropic,1)/2)+size(MicropicO,1)/4-1);
    Micropic1 = Micropic;
    Micropic2 = Micropic';

    for i = 1:ImagePower
    
        ResStats(i,1,h) = floor(size(Micropic,1));
        ResStats(i,2,h) = std(Micropic(:));
        ResStats(i,3,h) = 1-mean(Micropic(:));
        ResStats(i,4,h) = 2^(i-1);
        ResStats(i,5,h) = ResStats(i,2,h)/ResStats(i,3,h);
        ResStats(i,6,h) = std(Micropic1(:));
        ResStats(i,7,h) = ResStats(i,6,h)/ResStats(i,3,h);
        ResStats(i,8,h) = std(Micropic2(:));
        ResStats(i,9,h) = ResStats(i,8,h)/ResStats(i,3,h);
    
        % Reduce the image and save it in the upper quadrant of Micropic
    
        Micropic  = 0.25*(Micropic(1:2:end,1:2:end)+Micropic(2:2:end,2:2:end)+Micropic(2:2:end,1:2:end)+Micropic(2:2:end,2:2:end));
        Micropic1 = 0.50*(Micropic1(:,1:2:end)+Micropic1(:,2:2:end));
        Micropic2 = 0.50*(Micropic2(:,1:2:end)+Micropic2(:,2:2:end));
        
    end

    toc
    waitbar(RotAngle/90)

end

% Output

% ResStats

X = zeros((4*AngDivisions),(ImagePower));
Y = zeros((4*AngDivisions),(ImagePower));
Z = zeros((4*AngDivisions),(ImagePower));
slopedata = zeros(4*AngDivisions-1,2);
alphadata = zeros(4*AngDivisions-1,2);

% Changed from 1:AngDiv+2 to 2:AngDiv+1
for i = 2:(AngDivisions+1)
    RotAngle = (i-2)*90/AngDivisions;
    for j = 1:(ImagePower+1)
        if j == 1

            slopedata(i-1,j)                = RotAngle;
            alphadata(i-1,j)                = RotAngle;
            L = ResStats(1:end,4,i-1);
            CV = ResStats(1:end,9,i-1);
            Af = ResStats(1:end,3,i-1);
            [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));
            slopedata(i-1,j+1) = abs(xi);
            alphadata(i-1,j+1) = alpha;
            
            slopedata(i+AngDivisions-1,j)   = RotAngle+90;
            alphadata(i+AngDivisions-1,j)   = RotAngle+90;
            CV = ResStats(1:end,7,i-1);
            Af = ResStats(1:end,3,i-1);
            [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));
            slopedata(i+AngDivisions-1,j+1) = abs(xi);
            alphadata(i+AngDivisions-1,j+1) = alpha;
            
            slopedata(i+2*AngDivisions-1,j) = RotAngle+180;
            alphadata(i+2*AngDivisions-1,j) = RotAngle+180;
            CV = ResStats(1:end,9,i-1);
            Af = ResStats(1:end,3,i-1);
            [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));
            slopedata(i+2*AngDivisions-1,j+1) = abs(xi);
            alphadata(i+2*AngDivisions-1,j+1) = alpha;
                        
            slopedata(i+3*AngDivisions-1,j) = RotAngle+270;
            alphadata(i+3*AngDivisions-1,j) = RotAngle+270;
            CV = ResStats(1:end,7,i-1);
            Af = ResStats(1:end,3,i-1);
            [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));
            slopedata(i+3*AngDivisions-1,j+1) = abs(xi);
            alphadata(i+3*AngDivisions-1,j+1) = alpha;
            
            if i == 2
                slopedata(i+4*AngDivisions-1,j)           = 360;
                alphadata(i+4*AngDivisions-1,j)           = 360;
                CV = ResStats(1:end,9,i-1);
                Af = ResStats(1:end,3,i-1);
                [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));
                slopedata(i+4*AngDivisions-1,j+1) = abs(xi);
                alphadata(i+4*AngDivisions-1,j+1) = alpha;
            end

        else
            
            X(i-1,j-1)                = log10(2^(j-2))*cos(RotAngle*3.1415927/180);
            X(i-1+AngDivisions,j-1)   = log10(2^(j-2))*cos((RotAngle+90)*3.1415927/180);
            X(i-1+2*AngDivisions,j-1) = log10(2^(j-2))*cos((RotAngle+180)*3.1415927/180);
            X(i-1+3*AngDivisions,j-1) = log10(2^(j-2))*cos((RotAngle+270)*3.1415927/180);
            
            Y(i-1,j-1)                = log10(2^(j-2))*sin(RotAngle*3.1415927/180);
            Y(i-1+AngDivisions,j-1)   = log10(2^(j-2))*sin((RotAngle+90)*3.1415927/180);
            Y(i-1+2*AngDivisions,j-1) = log10(2^(j-2))*sin((RotAngle+180)*3.1415927/180);
            Y(i-1+3*AngDivisions,j-1) = log10(2^(j-2))*sin((RotAngle+270)*3.1415927/180);
            
            Z(i-1,j-1)                = log10(ResStats(j-1,7,i-1));
            Z(i-1+AngDivisions,j-1)   = log10(ResStats(j-1,9,i-1));
            Z(i-1+2*AngDivisions,j-1) = log10(ResStats(j-1,7,i-1));
            Z(i-1+3*AngDivisions,j-1) = log10(ResStats(j-1,9,i-1));
            
            if i == 2
                X(i-1+4*AngDivisions,j-1) = log10(2^(j-2));
                Y(i-1+4*AngDivisions,j-1) = 0;
                Z(i-1+4*AngDivisions,j-1) = log10(ResStats(j-1,7,i-1));
            end
        end
    end
end

axes(handles.axes2);
contourf(X,Y,Z,-1:((1.5)/8):0.5);colormap (bone); axis square; axis off;
set(handles.image2_menu,'Value',4)

% Update handles
handles.X = X;
handles.Y = Y;
handles.Z = Z;
handles.slopedata = slopedata;
handles.alphadata = alphadata;

guidata(hObject, handles);


% --- Executes on button press in pushbutton_save.
function pushbutton_save_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

for i = 2:7
    figure(1);
    switch i
      case 2

        ResStats = handles.ResStats;

        L = ResStats(1:end,4);
        CV = ResStats(1:end,5);
        Af = ResStats(1:end,3);

        [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));

        f = @(alpha,xi) (Af./(1-Af)+alpha.*(L-1).^(-2*xi)).^(-1/2);
        FittedCurve = f(alpha,xi);

        % Update graph
        loglog(L,CV, '*')
        hold on, axis square, grid off
        loglog(L, FittedCurve, '-r')
        title('Isotropic MSAAF Plot');
        xlabel('L','FontSize',10), ylabel('CV','FontSize',10)
        h = gca; set(h,'XLim', [1 10000],'YLim', [.01 10]);
        text(100,5,{['\alpha = ' num2str(round(1000*alpha)/1000)];['\xi = ' num2str(round(1000*xi)/1000)] },...
            'HorizontalAlignment','center')
        hold off
        if ~isempty(strfind(handles.filename, '.tif'))
            f1 = strrep(handles.filename, '.tif','_iso.tif');
        else
            f1 = strrep(handles.filename, '.jpg','_iso.tif');
        end
%        saveas(gcf,f1,'tif');
        print('-f1','-dtiff','-r300',f1);

      case 3

        ResStats = handles.ResStats;
        L = ResStats(1:end,4);
        CV_X = ResStats(1:end,7);
        CV_Y = ResStats(1:end,9);
        Af = ResStats(1:end,3);

        [alpha_X, xi_X] = fit_MSAAF_curve(L(2:end-2),CV_X(2:end-2),Af(2:end-2));
        [alpha_Y, xi_Y] = fit_MSAAF_curve(L(2:end-2),CV_Y(2:end-2),Af(2:end-2));

        f = @(alpha,xi) (Af./(1-Af)+alpha.*(L-1).^(-2*xi)).^(-1/2);
        FittedCurve_X = f(alpha_X,xi_X);
        FittedCurve_Y = f(alpha_Y,xi_Y);

        % Update graph
        loglog(L, CV_X, '*b'); 
        hold on;
        loglog(L, CV_Y, '*r');
        hold on, axis square, grid off
        loglog(L, FittedCurve_X, '-b')
        loglog(L, FittedCurve_Y, '-r')
        title('Anisotropic MSAAF Plot');
        xlabel('L','FontSize',10), ylabel('CV','FontSize',10)
        h = gca; set(h,'XLim', [1 10000],'YLim', [.01 10]);
        text(2000,3,{['\alpha_X = ' num2str(round(1000*alpha_X)/1000)];['\xi_X = ' num2str(round(1000*xi_X)/1000)];...
            ['\alpha_Y = ' num2str(round(1000*alpha_Y)/1000)];['\xi_Y = ' num2str(round(1000*xi_Y)/1000)]},...
            'HorizontalAlignment','center')
        hold off
        if ~isempty(strfind(handles.filename, '.tif'))
            f1 = strrep(handles.filename, '.tif','_ani.tif');
        else
            f1 = strrep(handles.filename, '.jpg','_ani.tif');
        end
%        saveas(gcf,f1,'tif');
        print('-f1','-dtiff','-r300',f1);

      case 4
        
        contourf(handles.X,handles.Y,handles.Z,-1:((1.5)/8):0.5);
        colormap (bone); axis square; axis off      
        if ~isempty(strfind(handles.filename, '.tif'))
            f1 = strrep(handles.filename, '.tif','_dhl.tif');
        else
            f1 = strrep(handles.filename, '.jpg','_dhl.tif');
        end
%        saveas(gcf,f1,'tif');
        print('-f1','-dtiff','-r300',f1);

      case 5 % Slope plot
    
        polar([0 pi/2], [0 1],':k'); hold on;
        polar(handles.slopedata(:,1)*pi/180,handles.slopedata(:,2),'-*b')
        polar(handles.slopedata(:,1)*pi/180,(handles.slopedata(:,2)>0)*0.5,'-r')
        hold off;
        if ~isempty(strfind(handles.filename, '.tif'))
            f1 = strrep(handles.filename, '.tif','_xi.tif');
        else
            f1 = strrep(handles.filename, '.jpg','_xi.tif');
        end
%        saveas(gcf,f1,'tif');
        print('-f1','-dtiff','-r300',f1);
        
      case 6 % Alpha plot
    
        polar([0 pi/2], [0 0.1],':k'); hold on;
        polar(handles.alphadata(:,1)*pi/180,handles.alphadata(:,2),'-*b')
        hold off;
        if ~isempty(strfind(handles.filename, '.tif'))
            f1 = strrep(handles.filename, '.tif','_alpha.tif');
        else
            f1 = strrep(handles.filename, '.jpg','_alpha.tif');
        end
%        saveas(gcf,f1,'tif');
        print('-f1','-dtiff','-r300',f1);
        
      case 7 % Image plus Length Scale Contour Plot
        
        I = handles.I;
        figure(1)
        contourf(handles.X,handles.Y,handles.Z,-1:((1.5)/8):0.5);
        colormap (bone); axis square; axis off;
%        dhl_filename = strrep(filename, '.jpg','_dhl.tif');
        if ~isempty(strfind(handles.filename, '.tif'))
            dhl_filename = strrep(handles.filename, '.tif','_dhl_tmp.tif');
        else
            dhl_filename = strrep(handles.filename, '.jpg','_dhl_tmp.tif');
        end
        saveas(gcf,dhl_filename,'tif');
        close(1);
        J = imread(dhl_filename); J1 = J(:,:,1);
        delete(dhl_filename);
        Jsum = sum(255-J1); jmin = find(Jsum~=0); J = J(:,jmin(1):jmin(end),:);
        Jsum = sum(255-J1'); jmin = find(Jsum~=0); J = J(jmin(1):jmin(end),:,:);
        K(:,:,1) = I; K(:,:,2) = I; K(:,:,3) = I;
        K(end-size(J,1)+1:end,end-size(J,2)+1:end,:) = J;
        figure(1); imshow(K);
        if ~isempty(strfind(handles.filename, '.tif'))
            f1 = strrep(handles.filename, '.tif','_image_dhl.tif');
        else
            f1 = strrep(handles.filename, '.jpg','_image_dhl.tif');
        end
%        saveas(gcf,f1,'tif');
        print('-f1','-dtiff','-r300',f1);

    end
    close(1);
end


% --- Executes on selection change in image1_menu.
function image1_menu_Callback(hObject, eventdata, handles)
% hObject    handle to image1_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns image1_menu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from image1_menu

I = handles.I;

switch get(handles.image1_menu,'Value')   
    case 1
        I = I;
    case 2
        I = I(1:end/2,1:end/2);
    case 3
        I = I(1:end/4,1:end/4);
    case 4
        I = I(1:end/8,1:end/8);
    case 5
        I = I(1:end/16,1:end/16);
    case 6
        I = I(1:end/32,1:end/32);
    otherwise
end

axes(handles.axes1)
imshow(I)


% --- Executes during object creation, after setting all properties.
function image1_menu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to image1_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on selection change in image2_menu.
function image2_menu_Callback(hObject, eventdata, handles)
% hObject    handle to image2_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns image2_menu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from image2_menu

switch get(handles.image2_menu,'Value')   
    case 1
        
        axes(handles.axes2)
        imshow(ones(100))
        
    case 2

        ResStats = handles.ResStats;

        L = ResStats(1:end,4);
        CV = ResStats(1:end,5);
        Af = ResStats(1:end,3);

        [alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));

        f = @(alpha,xi) (Af./(1-Af)+alpha.*(L-1).^(-2*xi)).^(-1/2);
        FittedCurve = f(alpha,xi);

        % Update graph
        axes(handles.axes2);
        loglog(L,CV, '*')
        hold on, axis square, grid off
        loglog(L, FittedCurve, '-r')
        title('Isotropic MSAAF Plot');
        xlabel('L','FontSize',10), ylabel('CV','FontSize',10)
        h = gca; set(h,'XLim', [1 10000],'YLim', [.01 10]);
        text(100,5,{['\alpha = ' num2str(round(1000*alpha)/1000)];['\xi = ' num2str(round(1000*xi)/1000)] },...
            'HorizontalAlignment','center')
        hold off

    case 3

        ResStats = handles.ResStats;
        L = ResStats(1:end,4);
        CV_X = ResStats(1:end,7);
        CV_Y = ResStats(1:end,9);
        Af = ResStats(1:end,3);

        [alpha_X, xi_X] = fit_MSAAF_curve(L(2:end-2),CV_X(2:end-2),Af(2:end-2));
        [alpha_Y, xi_Y] = fit_MSAAF_curve(L(2:end-2),CV_Y(2:end-2),Af(2:end-2));

        f = @(alpha,xi) (Af./(1-Af)+alpha.*(L-1).^(-2*xi)).^(-1/2);
        FittedCurve_X = f(alpha_X,xi_X);
        FittedCurve_Y = f(alpha_Y,xi_Y);

        % Update graph
        axes(handles.axes2);
        loglog(L, CV_X, '*b'); 
        hold on;
        loglog(L, CV_Y, '*r');
        hold on, axis square, grid off
        loglog(L, FittedCurve_X, '-b')
        loglog(L, FittedCurve_Y, '-r')
        title('Anisotropic MSAAF Plot');
        xlabel('L','FontSize',10), ylabel('CV','FontSize',10)
        h = gca; set(h,'XLim', [1 10000],'YLim', [.01 10]);
        text(2000,3,{['\alpha_X = ' num2str(round(1000*alpha_X)/1000)];['\xi_X = ' num2str(round(1000*xi_X)/1000)];...
            ['\alpha_Y = ' num2str(round(1000*alpha_Y)/1000)];['\xi_Y = ' num2str(round(1000*xi_Y)/1000)]},...
            'HorizontalAlignment','center')
        hold off

    case 4
        
        axes(handles.axes2)
        contourf(handles.X,handles.Y,handles.Z,-1:((1.5)/8):0.5);
        colormap (bone); axis square; axis off;

    case 5 % Slope plot
    
        axes(handles.axes2)
        polar([0 pi/2], [0 1],':k'); hold on;
        polar(handles.slopedata(:,1)*pi/180,handles.slopedata(:,2),'-*b')
        polar(handles.slopedata(:,1)*pi/180,(handles.slopedata(:,2)>0)*0.5,'-r')
        hold off;

    case 6 % Alpha plot
    
        axes(handles.axes2)
        polar([0 pi/2], [0 0.1],':k'); hold on;
        polar(handles.alphadata(:,1)*pi/180,handles.alphadata(:,2),'-*b')
        hold off;
        
    case 7 % Image plus Length Scale Contour Plot
        
        I = handles.I;
        
        figure(1)
        contourf(handles.X,handles.Y,handles.Z,-1:((1.5)/8):0.5);
        colormap (bone); axis square; axis off;
        if ~isempty(strfind(handles.filename, '.tif'))
            dhl_filename = strrep(handles.filename, '.tif','_dhl_tmp.tif');
        else
            dhl_filename = strrep(handles.filename, '.jpg','_dhl_tmp.tif');
        end
        saveas(gcf,dhl_filename,'tif');
        close(1);
        J = imread(dhl_filename); J1 = J(:,:,1);
        delete(dhl_filename);
        Jsum = sum(255-J1); jmin = find(Jsum~=0); J = J(:,jmin(1):jmin(end),:);
        Jsum = sum(255-J1'); jmin = find(Jsum~=0); J = J(jmin(1):jmin(end),:,:);
        K(:,:,1) = I; K(:,:,2) = I; K(:,:,3) = I;
        K(end-size(J,1)+1:end,end-size(J,2)+1:end,:) = J;
        axes(handles.axes2)
        imshow(K);
        
    otherwise
end


% --- Executes during object creation, after setting all properties.
function image2_menu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to image2_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_angle_rotations_Callback(hObject, eventdata, handles)
% hObject    handle to edit_angle_rotations (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_angle_rotations as text
%        str2double(get(hObject,'String')) returns contents of edit_angle_rotations as a double

handles.AngDivisions = str2double(get(hObject,'String'));

guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function edit_angle_rotations_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_angle_rotations (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbutton_isotropic.
function pushbutton_isotropic_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_isotropic (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

[ResStats] = compute_homogeneous_length_scale(handles.I);

L = ResStats(1:end,4);
CV = ResStats(1:end,5);
Af = ResStats(1:end,3);

[alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));
%[alpha, xi] = fit_MSAAF_curve1(L(2:end-1),CV(2:end-1),Af(2:end-1));

f = @(alpha,xi) (Af./(1-Af)+alpha.*(L-1).^(-2*xi)).^(-1/2);
FittedCurve = f(alpha,xi);

% Update graph
axes(handles.axes2);
loglog(L,CV, '*')
hold on, axis square, grid off
loglog(L, FittedCurve, '-r')
title('Isotropic MSAAF Plot');
xlabel('L','FontSize',10), ylabel('CV','FontSize',10)
h = gca; set(h,'XLim', [1 10000],'YLim', [.01 10]);
text(100,5,{['\alpha = ' num2str(round(10000*alpha)/10000)];['\xi = ' num2str(round(10000*xi)/10000)] },...
     'HorizontalAlignment','center')
hold off

% Set the text boxes
CV = str2double(get(handles.edit_iso_cv,'String'));
Af = ResStats(1,3);
LS = 1 + ((CV^-2-Af/(1-Af))/alpha)^(-1/(2*xi));
set(handles.edit_area_fraction,'String',round(ResStats(1,3)*1000)/1000) % Area fraction
set(handles.edit_iso_LH,'String',round(LS)) % 
set(handles.edit_iso_alpha,'String',round(alpha*10000)/10000)
set(handles.edit_iso_xi,'String',round(xi*10000)/10000)
set(handles.image2_menu,'Value',2)

% Update handles structure with new information
handles.ResStats = ResStats;
handles.FittedCurve = FittedCurve;

guidata(hObject, handles);

function edit_dmsaaf_xLH_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_xLH (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_xLH as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_xLH as a double


% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_xLH_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_xLH (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function edit_dmsaaf_xalpha_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_xalpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_xalpha as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_xalpha as a double


% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_xalpha_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_xalpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_dmsaaf_xxi_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_xxi (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_xxi as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_xxi as a double


% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_xxi_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_xxi (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_dmsaaf_yLH_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_yLH (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_yLH as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_yLH as a double


% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_yLH_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_yLH (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_dmsaaf_yalpha_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_yalpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_yalpha as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_yalpha as a double


% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_yalpha_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_yalpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_dmsaaf_yxi_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_yxi (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_yxi as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_yxi as a double


% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_yxi_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_yxi (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_area_fraction_Callback(hObject, eventdata, handles)
% hObject    handle to edit_area_fraction (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_area_fraction as text
%        str2double(get(hObject,'String')) returns contents of edit_area_fraction as a double


% --- Executes during object creation, after setting all properties.
function edit_area_fraction_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_area_fraction (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_iso_LH_Callback(hObject, eventdata, handles)
% hObject    handle to edit_iso_LH (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_iso_LH as text
%        str2double(get(hObject,'String')) returns contents of edit_iso_LH as a double


% --- Executes during object creation, after setting all properties.
function edit_iso_LH_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_iso_LH (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_iso_alpha_Callback(hObject, eventdata, handles)
% hObject    handle to edit_iso_alpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_iso_alpha as text
%        str2double(get(hObject,'String')) returns contents of edit_iso_alpha as a double


% --- Executes during object creation, after setting all properties.
function edit_iso_alpha_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_iso_alpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_iso_xi_Callback(hObject, eventdata, handles)
% hObject    handle to edit_iso_alpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_iso_alpha as text
%        str2double(get(hObject,'String')) returns contents of edit_iso_alpha as a double


% --- Executes during object creation, after setting all properties.
function edit_iso_xi_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_iso_alpha (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbutton_excel.
function pushbutton_excel_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_excel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    string_path = pwd;
    if ~isempty(strfind(handles.filename, '.tif'))
        Excel_name = strrep(handles.filename, '.tif','.xls');
    else
        Excel_name = strrep(handles.filename, '.jpg','.xls');
    end
    Excel_fileName = sprintf('%s\\%s',string_path,Excel_name);
    sheet = 'Stats';
    warning off MATLAB:xlswrite:AddSheet;
    ColHeaders = {'ImageSize','Std','Mean','Quilt','Std/Mean','StdX','StdX/Mean','StdY','StdY/Mean'};
    xlswrite(Excel_fileName, ColHeaders, sheet, 'A1');
    xlswrite(Excel_fileName, handles.ResStats, sheet, 'A2');

% From program deleteEmptyExcelSheets

fileName = Excel_fileName;
excelObj = actxserver('Excel.Application');
%opens up an excel object 
excelWorkbook = excelObj.workbooks.Open(fileName);
worksheets = excelObj.sheets;
%total number of sheets in workbook
numSheets = worksheets.Count;
 
count=1;
for x=1:numSheets
    %stores the current number of sheets in the workbook
    %this number will change if sheets are deleted
    temp = worksheets.count;
 
    %if there's only one sheet left, we must leave it or else 
    %there will be an error.
    if (temp == 1) 
        break; 
    end
 
    %this command will only delete the sheet if it is empty
    worksheets.Item(count).Delete;
 
    %if a sheet was not deleted, we move on to the next one 
    %by incrementing the count variable
    if (temp == worksheets.count)
        count = count + 1;
    end
end
excelWorkbook.Save;
excelWorkbook.Close(false);
excelObj.Quit;
delete(excelObj);

% End program
    



function edit_dmsaaf_cv_Callback(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_cv (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_dmsaaf_cv as text
%        str2double(get(hObject,'String')) returns contents of edit_dmsaaf_cv as a double

ResStats = handles.ResStats;

L = ResStats(1:end,4);
CV_X = ResStats(1:end,7);
CV_Y = ResStats(1:end,9);
Af = ResStats(1:end,3);

[alpha_X, xi_X] = fit_MSAAF_curve(L(2:end-2),CV_X(2:end-2),Af(2:end-2));
[alpha_Y, xi_Y] = fit_MSAAF_curve(L(2:end-2),CV_Y(2:end-2),Af(2:end-2));

CV = str2double(get(handles.edit_dmsaaf_cv,'String'));
Af = ResStats(1,3);
LS_X = 1 + ((CV^-2-Af/(1-Af))/alpha_X)^(-1/(2*xi_X));
LS_Y = 1 + ((CV^-2-Af/(1-Af))/alpha_Y)^(-1/(2*xi_Y));

% Unfortunately when I set up the coordinate system, X is in the vertical
% direction and Y is in the horizontal direction.

set(handles.edit_dmsaaf_xLH,'String',round(LS_X))
set(handles.edit_dmsaaf_yLH,'String',round(LS_Y))

% --- Executes during object creation, after setting all properties.
function edit_dmsaaf_cv_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_dmsaaf_cv (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function edit_iso_cv_Callback(hObject, eventdata, handles)
% hObject    handle to edit_iso_cv (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit_iso_cv as text
%        str2double(get(hObject,'String')) returns contents of edit_iso_cv as a double

ResStats = handles.ResStats;

L = ResStats(1:end,4);
CV = ResStats(1:end,5);
Af = ResStats(1:end,3);

[alpha, xi] = fit_MSAAF_curve(L(2:end-2),CV(2:end-2),Af(2:end-2));

CV = str2double(get(handles.edit_iso_cv,'String'));
Af = ResStats(1,3);
LS = 1 + ((CV^-2-Af/(1-Af))/alpha)^(-1/(2*xi));

set(handles.edit_iso_LH,'String',round(LS)) % 



% --- Executes during object creation, after setting all properties.
function edit_iso_cv_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit_iso_cv (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


Contact us at files@mathworks.com