image thumbnail
from Determination of Crack and Buckle Density by Digital Image Analysis by Stephan Frank
Determination of density and distance distribution of line-shaped features such as coating cracks

FractureBucklingAnalysis.m
function varargout = FractureBucklingAnalysis(varargin)

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @FractureBucklingAnalysis_OpeningFcn, ...
                   'gui_OutputFcn',  @FractureBucklingAnalysis_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


function FractureBucklingAnalysis_OpeningFcn(hObject, eventdata, handles, varargin)
    handles.output = hObject;
    guidata(hObject, handles);

    global Status Parameters Files  SavedParameters

    % DEFAULT PARAMETERS
    % Enter default directory in line 34 for faster access on images for analysis.
    % Set Parameters.PointXYSave = 1 if you want to save the intersection positions in
    % a separate file "MarkerPos_....dat". Otherwise, set Parameters.PointXYSave = 0.
    
    Files.DefaultDir = 'C:\';
    Parameters.PointXYSave = 0;
    
    
    Files.OldDir = cd;

    Status.Loop = 2;
    while Status.Loop ~= 0
        if Status.Loop == 2
            Files.AFile = 0;
            Files.APath = 0;
            Files.ZFile = 0;
            Files.ZPath = 0;
            Files.OldFile = '';
            Status.InPar(1:5)=[0 0 0 0 0];
            Status.ScaleLine = 0;
            Status.PointNo = 0;
            Status.Points = [];
            Status.OutputData = [];
            SavedParameters = [];
            Parameters.Mode = 'H';
            set(handles.Button_FileALoad, 'Enable', 'on')
            set(handles.Button_Accept, 'Enable', 'off')
            set(handles.Button_SetScale, 'Enable', 'off')
            set(handles.Button_LineDirection, 'Enable', 'off', 'String', 'h o r i z o n t a l')
            set(handles.Button_SetArea, 'Enable', 'off')
            set(handles.Edit_ScaleLength, 'Enable', 'off')
            set(handles.Edit_LinesNo, 'Enable', 'off')
            set(handles.Slider_Threshold, 'Enable', 'off')
            set(handles.Slider_VarIn, 'Enable', 'off')
            set(handles.Slider_VarOut, 'Enable', 'off')
            set(handles.Button_ClearCracks, 'Enable', 'off')
            set(handles.Button_StartCrackFind, 'Enable', 'off')
            set(handles.Button_Manual, 'Enable', 'off')
            cla(handles.Axes_Image)
            cla(handles.Axes_Graph)
            set(handles.Text_FileA, 'String', '- no data selected -', 'ForegroundColor', [1 0 0])
            set(handles.Text_FileZ, 'String', '- no data selected -', 'ForegroundColor', [1 0 0])
            set(handles.Text_CurrentFile, 'String', '- - -', 'ForegroundColor', [1 1 0])
            set(handles.Text_Status, 'String', '', 'ForegroundColor', [1 1 0])
            set(handles.Panel_ImageScale, 'ForegroundColor', [1 1 1], 'ShadowColor', [1 1 1])
            set(handles.Panel_AoI, 'ForegroundColor', [1 1 1], 'ShadowColor', [1 1 1])
            Files.CurrentDir = Files.DefaultDir;
            cd(Files.CurrentDir); 
        elseif Status.Loop == 3
            set(handles.Button_Accept, 'Enable', 'on')
            set(handles.Slider_Threshold, 'Enable', 'on')
            set(handles.Slider_VarIn, 'Enable', 'on')
            set(handles.Slider_VarOut, 'Enable', 'on')
            set(handles.Button_ClearCracks, 'Enable', 'on')
            set(handles.Button_StartCrackFind, 'Enable', 'on')
            set(handles.Button_Manual, 'Enable', 'on')
        end

        Status.Loop = 0;
        figure(handles.Main)
        uiwait(handles.Main)
    end


    close all
    cd (Files.OldDir);


function varargout = FractureBucklingAnalysis_OutputFcn(hObject, eventdata, handles) 
    %varargout{1} = handles.output;


function Button_FileALoad_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    Status.Loop = 1;
    [FileA, PathA] = uigetfile({'*.bmp;*.tif;*.jpg;*.TIF;*.BMP;*.JPG','image files (*.bmp,*.tif,*.jpg)';'*.*',  'all files (*.*)'}, 'S E L E C T   F I R S T   I M A G E', Files.CurrentDir);
    if PathA ~= 0
        [FileZ, PathZ] = uigetfile({'*.bmp;*.tif;*.jpg;*.TIF;*.BMP;*.JPG','image files (*.bmp,*.tif,*.jpg)';'*.*',  'all files (*.*)'}, 'S E L E C T   L A S T   I M A G E', PathA);
        if PathZ ~= 0
            Files.AFile = FileA;
            Files.APath = PathA;
            set(handles.Text_FileA, 'String', Files.AFile, 'ForegroundColor', [0 1 0])
            Status.InPar(1) = 1;
            Files.ZFile = FileZ;
            Files.ZPath = PathZ;
            set(handles.Text_FileZ, 'String', Files.ZFile, 'ForegroundColor', [0 1 0])
            Status.InPar(2) = 1;
            Files.CurrentDir = Files.ZPath;
            CreateFilelist(handles)
        end
    end
    uiresume


function CreateFilelist(handles)
    global Status Parameters Files SavedParameters
    set(handles.Text_Status, 'String', 'CREATING FILELIST - PLEASE WAIT.....', 'ForegroundColor', [1 1 0])
    set(handles.Button_FileALoad, 'Enable', 'off')
    Files.Filelist = [];
    Error = 0;
    FileLength(1) = size(Files.AFile,2);
    FileLength(2) = size(Files.ZFile,2);
    if FileLength(1) == FileLength(2)
        FileType(1,:) = Files.AFile((FileLength(1)-3):FileLength(1));
        FileType(2,:) = Files.ZFile((FileLength(2)-3):FileLength(2));
        FileStart = str2num(Files.AFile((FileLength(1)-6):(FileLength(1)-4)));
        FileEnd = str2num(Files.ZFile((FileLength(2)-6):(FileLength(2)-4)));
        FileLabel(1,:) = Files.AFile(1:(FileLength(1)-7));
        FileLabel(2,:) = Files.ZFile(1:(FileLength(2)-7));
        if FileType(1,:) ~= FileType(2,:)
            Error = 1;
        end
        if FileLabel(1,:) ~= FileLabel(2,:)
            Error = 1;
        end
    else
        Error = 1;
    end
    if size(Files.APath, 2) == size(Files.ZPath, 2)
        if Files.APath ~= Files.ZPath
            Error = 1;
        end
    else
        Error = 1;
    end
    if Error == 1
        set(handles.Text_Status, 'String', 'CRITICAL ERROR WHILE CREATING FILELIST', 'ForegroundColor', [1 0 0])
        Status.Loop = 1;
        uiresume
    end
    j = 0;
    for i = FileStart:FileEnd
        j = j + 1;
        FileNo = num2str(i + 1000);    
        Filename(j,:) = [FileLabel(1,:), FileNo(:,2:4), FileType(1,:)];
    end
    Files.Filelist = Filename;
    Parameters.FileType = FileType(1,:);
    Parameters.FileLabel = FileLabel(1,:);
    Files.Path = Files.APath;
    clear Filename FileLength FileType FileLabel
    Files.ActualFile = Files.Filelist(1,:);
    Files.FileCounter = 1;

    fexist = fopen([Files.Path, 'FA-parameters.dat']);
    if fexist == -1
        set(handles.Text_Status, 'String', sprintf('Parameter file does not exist. \n Set   I M A G E   S C A L E   and \n A R E A   O F   I N T E R E S T \n before continuing.'))
        set(handles.Panel_ImageScale, 'ForegroundColor', [1 1 0], 'ShadowColor', [1 1 0])
        set(handles.Panel_AoI, 'ForegroundColor', [1 1 0], 'ShadowColor', [1 1 0])
        SavedParameters.Settings.IntThrd = 0.1;
        SavedParameters.Settings.VarIn = 0.15;
        SavedParameters.Settings.VarOut = 0.15;
        SavedParameters.Settings.Mode = 'H';
        SavedParameters.Scale.ScaleLength = 80;
        SavedParameters.Area.LineNumber = 10;
        Status.InPar(3:4) = zeros;
    else
        load([Files.Path, 'FA-parameters.dat'], '-mat')
        Parameters.ScaleRatio = SavedParameters.Scale.ScaleRatio;
        Parameters.Scalebar = SavedParameters.Scale.Scalebar;
        Parameters.LinePosX = SavedParameters.Area.LinePosX;
        Parameters.LinePosY = SavedParameters.Area.LinePosY;
        %downward compatibility: add hor./vert. parameter
        if isfield(SavedParameters.Settings, 'Mode') ~= 1
            SavedParameters.Settings.Mode = 'H';
        end
        Status.InPar(3:4) = [1 1];
        Status.Loop = 3;
        set(handles.Text_Status, 'String', '')
        fclose(fexist);
    end
    Parameters.IntThrd = SavedParameters.Settings.IntThrd;
    Parameters.VarIn = SavedParameters.Settings.VarIn;
    Parameters.VarOut = SavedParameters.Settings.VarOut;
    Parameters.Mode = SavedParameters.Settings.Mode;
    Parameters.ScaleLength = SavedParameters.Scale.ScaleLength;
    Parameters.LineNumber = SavedParameters.Area.LineNumber;
    set(handles.Slider_Threshold, 'Value', Parameters.IntThrd + 0.5)
    set(handles.Text_Threshold, 'String', num2str(Parameters.IntThrd))
    set(handles.Slider_VarIn, 'Value', Parameters.VarIn + 0.5)
    set(handles.Text_VarIn, 'String', num2str(Parameters.VarIn))
    set(handles.Slider_VarOut, 'Value', Parameters.VarOut + 0.5)
    set(handles.Text_VarOut, 'String', num2str(Parameters.VarOut))
    set(handles.Edit_ScaleLength, 'String', num2str(Parameters.ScaleLength))
    set(handles.Edit_LinesNo, 'String', num2str(Parameters.LineNumber))
    if Parameters.Mode == 'H'
    	set(handles.Button_LineDirection, 'String', 'h o r i z o n t a l')
    elseif Parameters.Mode == 'V'
        set(handles.Button_LineDirection, 'String', 'v e r t i c a l')
    end
    
    DisplayImage(handles, Files.ActualFile)
    
    set(handles.Button_SetScale, 'Enable', 'on')
    set(handles.Button_SetArea, 'Enable', 'on')
    set(handles.Edit_ScaleLength, 'Enable', 'on')
    set(handles.Edit_LinesNo, 'Enable', 'on')
    set(handles.Button_LineDirection, 'Enable', 'on')
    


    
function DisplayImage(handles, Filename)
    global Status Parameters Files

    set(handles.Text_CurrentFile, 'String', Filename)
    TempData = imread([Files.Path, Filename]);
    ImageData = mean(double(TempData), 3);
    Parameters.ImageSize = [size(ImageData, 2) size(ImageData, 1)];
    
    axes(handles.Axes_Image)
    cla(handles.Axes_Image)
    axis ij
    imagesc(TempData);

    set(handles.Axes_Image, 'Color', [0 0 0.251], 'Box', 'on', 'XColor', 'w', 'YColor', 'w', 'XTickLabelMode', 'manual', 'XTickLabel', '', 'XTickMode', 'manual', 'XTick', [], 'YTickLabelMode', 'manual', 'YTickLabel', '', 'YTickMode', 'manual', 'YTick', [])
    
    Parameters.ImageData = ImageData;
    
    hold on
    if Status.InPar(3) == 1
        Status.ScaleLine = plot ([Parameters.Scalebar(1), Parameters.Scalebar(2)], [Parameters.Scalebar(3), Parameters.Scalebar(3)], 'c+', [Parameters.Scalebar(1), Parameters.Scalebar(2)], [Parameters.Scalebar(3), Parameters.Scalebar(3)], 'c:');
    end
    if Status.InPar(4) == 1
        if Parameters.Mode == 'H'
            for i = 1:Parameters.LineNumber
                plot(Parameters.LinePosX(:),[Parameters.LinePosY(i), Parameters.LinePosY(i)], 'b-')
                SelectedData(i,:)=ImageData(Parameters.LinePosY(i),Parameters.LinePosX(1):Parameters.LinePosX(2));
            end
        elseif Parameters.Mode == 'V'
            for i = 1:Parameters.LineNumber
                plot([Parameters.LinePosX(i), Parameters.LinePosX(i)],Parameters.LinePosY(:), 'b-')
                SelectedData(i,:)=ImageData(Parameters.LinePosY(1):Parameters.LinePosY(2),Parameters.LinePosX(i));
            end            
        end
        Parameters.SelectedData = SelectedData;
        clear SelectedData
    end
    hold off

    clear TempData ImageData
    
    
    
function Button_Reset_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    Status.Loop = 2;
    uiresume
    

function Button_SetScale_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    if Status.ScaleLine ~= 0
        delete(Status.ScaleLine)
    end
    String = get(handles.Text_Status, 'String');
    set(handles.Text_Status, 'String', sprintf('DETERMINATION OF IMAGE SCALE: \n First, click LEFT END of scale bar. \n Then, click RIGHT END of scale bar.'))
    [XScale, YScale]=ginput(2);
    Parameters.Scalebar = [XScale(1), XScale(2), (YScale(1)+YScale(2))/2];
    Parameters.ScaleLengthPixel = abs(XScale(2) - XScale(1));
    Parameters.ScaleLength = str2double(get(handles.Edit_ScaleLength, 'String'));
    Parameters.ScaleRatio = Parameters.ScaleLength / Parameters.ScaleLengthPixel;
    Status.InPar(3) = 1;
    set(handles.Panel_ImageScale, 'ForegroundColor', [1 1 1], 'ShadowColor', [1 1 1])
    DisplayImage(handles, Files.ActualFile)
    if Status.InPar(1:4)-1 == zeros
        Status.Loop = 3;
        set(handles.Text_Status, 'String', '')
    else
        Status.Loop = 1;
        set(handles.Text_Status, 'String', String)
    end
    uiresume



function Edit_ScaleLength_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    Parameters.ScaleLength = str2double(get(handles.Edit_ScaleLength, 'String'));
    Parameters.ScaleRatio = Parameters.ScaleLength / Parameters.ScaleLengthPixel;
    Status.Loop = 1;
    uiresume


function Button_SetArea_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    String = get(handles.Text_Status, 'String');
    set(handles.Text_Status, 'String', sprintf('SELECT AREA OF INTEREST: \n First, click TOP LEFT, then BOTTOM RIGHT of area of interest.'))
    [XArea, YArea]=ginput(2);
    XArea = sort(XArea, 'ascend');
    YArea = sort(YArea, 'ascend');
    Parameters.LineNumber = str2double(get(handles.Edit_LinesNo, 'String'));
    if Parameters.Mode == 'H'
        Parameters.LinePosX = [round(XArea(1)), round(XArea(2))];
        DeltaLinePos = round((YArea(2) - YArea(1))/(Parameters.LineNumber - 1));
        Parameters.LinePosY = [round(YArea(1)):DeltaLinePos:round(YArea(1))+(Parameters.LineNumber-1)*DeltaLinePos];
    elseif Parameters.Mode == 'V'
        Parameters.LinePosY = [round(YArea(1)), round(YArea(2))];
        DeltaLinePos = round((XArea(2) - XArea(1))/(Parameters.LineNumber - 1));
        Parameters.LinePosX = [round(XArea(1)):DeltaLinePos:round(XArea(1))+(Parameters.LineNumber-1)*DeltaLinePos];
    end
    Status.InPar(4) = 1;
    set(handles.Panel_AoI, 'ForegroundColor', [1 1 1], 'ShadowColor', [1 1 1])
    Button_ClearCracks_Callback(hObject, eventdata, handles)
    if Status.InPar(1:4)-1 == zeros
        Status.Loop = 3;
        set(handles.Text_Status, 'String', '')
    else
        Status.Loop = 1;
        set(handles.Text_Status, 'String', String)
    end
    uiresume
    

function Edit_LinesNo_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    if Status.InPar(4) == 1
        Parameters.LineNumber = str2double(get(handles.Edit_LinesNo, 'String'));
        if Parameters.Mode == 'H'
            OldYArea = [Parameters.LinePosY(1) Parameters.LinePosY(size(Parameters.LinePosY, 2))];
            DeltaLinePos = round((OldYArea(2) - OldYArea(1))/(Parameters.LineNumber - 1));
            Parameters.LinePosY = [OldYArea(1):DeltaLinePos:OldYArea(1)+(Parameters.LineNumber-1)*DeltaLinePos];
        elseif Parameters.Mode == 'V'
            OldXArea = [Parameters.LinePosX(1) Parameters.LinePosX(size(Parameters.LinePosX, 2))];
            DeltaLinePos = round((OldXArea(2) - OldXArea(1))/(Parameters.LineNumber - 1));
            Parameters.LinePosX = [OldXArea(1):DeltaLinePos:OldXArea(1)+(Parameters.LineNumber-1)*DeltaLinePos];
        end
        Button_ClearCracks_Callback(hObject, eventdata, handles)
    end
    Status.Loop = 1;
    uiresume

    
function Button_LineDirection_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    if Parameters.Mode == 'H'        
        set(handles.Button_LineDirection, 'String', 'v e r t i c a l')
        Parameters.Mode = 'V';
    elseif Parameters.Mode == 'V'
        set(handles.Button_LineDirection, 'String', 'h o r i z o n t a l')
        Parameters.Mode = 'H';
    end
    if Status.InPar(4) == 1
        Parameters.LineNumber = str2double(get(handles.Edit_LinesNo, 'String'));
        OldXArea = [Parameters.LinePosX(1) Parameters.LinePosX(size(Parameters.LinePosX, 2))];
        OldYArea = [Parameters.LinePosY(1) Parameters.LinePosY(size(Parameters.LinePosY, 2))];
        if Parameters.Mode == 'H'
            DeltaLinePos = round((OldYArea(2) - OldYArea(1))/(Parameters.LineNumber - 1));
            Parameters.LinePosY = [OldYArea(1):DeltaLinePos:OldYArea(1)+(Parameters.LineNumber-1)*DeltaLinePos];
            Parameters.LinePosX = [OldXArea(1) OldXArea(2)];
        elseif Parameters.Mode == 'V'
            DeltaLinePos = round((OldXArea(2) - OldXArea(1))/(Parameters.LineNumber - 1));
            Parameters.LinePosX = [OldXArea(1):DeltaLinePos:OldXArea(1)+(Parameters.LineNumber-1)*DeltaLinePos];
            Parameters.LinePosY = [OldYArea(1) OldYArea(2)];
        end
        Button_ClearCracks_Callback(hObject, eventdata, handles)
    end
    Status.Loop = 1;
    uiresume


function Slider_Threshold_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    Parameters.IntThrd = get(handles.Slider_Threshold, 'Value') - 0.5;
    set(handles.Text_Threshold, 'String', num2str(Parameters.IntThrd))
    Status.Loop = 1;
    uiresume


function Slider_VarOut_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    Parameters.VarOut = get(handles.Slider_VarOut, 'Value') - 0.5;
    set(handles.Text_VarOut, 'String', num2str(Parameters.VarOut))
    Status.Loop = 1;
    uiresume


function Slider_VarIn_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    Parameters.VarIn = get(handles.Slider_VarIn, 'Value') - 0.5;
    set(handles.Text_VarIn, 'String', num2str(Parameters.VarIn))
    Status.Loop = 1;
    uiresume

    
function Button_StartCrackFind_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    DisplayImage(handles, Files.ActualFile)
    InCounter = 0;
    OutCounter = 0;
    InPoint = [0 0];
    OutPoint = [0 0];
    Status.PointNo = 0;
    Status.Points = [];
    if Parameters.Mode == 'H'
        xdata = [Parameters.LinePosX(1):Parameters.LinePosX(2)];
    elseif Parameters.Mode == 'V'
        xdata = [Parameters.LinePosY(1):Parameters.LinePosY(2)];
    end        
    for i = 1:Parameters.LineNumber   
        axes(handles.Axes_Graph)
        ydata = Parameters.SelectedData(i,:);
        plot(xdata, ydata, 'Color', [0.05 0.05 0.65], 'LineStyle', ':')
        set(handles.Axes_Graph, 'Color', [0 0 0], 'XColor', [1 1 1], 'YColor', [1 1 1], 'XLim', [xdata(1), xdata(size(xdata, 2))], 'YAxisLocation', 'right')
        xlabel(handles.Axes_Graph, 'position  [pixel]', 'Color', 'w')
        ylabel(handles.Axes_Graph, 'intensity  [-]', 'Color', 'w')
        hold on
        Parabolic = lsqcurvefit(@(Parabolic,xdata) Parabolic(1)*(xdata).^2+Parabolic(2)*xdata+Parabolic(3),[0 0 mean(ydata)],xdata,ydata);
        NormData = ydata./(Parabolic(1).*xdata.^2+Parabolic(2).*xdata+Parabolic(3))*Parabolic(3);
        plot(xdata,NormData, 'b-');
        Threshold = Parabolic(3)*(1-Parameters.IntThrd);
        plot(xdata,[Parabolic(3)],'r:');
        plot(xdata,[Threshold],'r-');
        YRange = get(handles.Axes_Graph, 'YLim');
            
        Counter = 0;
        PeakIndicator = 0;
        CoordinateSum = 0;
        Average = 0;
        for j = 1:size(NormData,2)
            if NormData(j) < Threshold
                if PeakIndicator == 0
                    PeakIndicator = 1;
                end
            else
                if j < size(NormData,2)
                    if NormData(j+1) < Threshold
                        PeakIndicator = 1;
                    else
                        PeakIndicator = 0;
                    end
                end
            end
            if PeakIndicator == 1
                if Parameters.Mode == 'H'
                    CoordinateSum = CoordinateSum + Parameters.LinePosX(1) + j - 1;
                elseif Parameters.Mode == 'V'
                    CoordinateSum = CoordinateSum + Parameters.LinePosY(1) + j - 1;
                end
                Counter = Counter + 1;
                Average = 1;
            else
                if Average == 1
                    %coordinates
                    if Parameters.Mode == 'H'
                        XPoint = round(CoordinateSum/Counter);
                        YPoint = Parameters.LinePosY(i);
                        plot([XPoint XPoint],YRange,'r:');
                    elseif Parameters.Mode == 'V'
                        YPoint = round(CoordinateSum/Counter);
                        XPoint = Parameters.LinePosX(i);
                        plot([YPoint YPoint],YRange,'r:');
                    end
                    
                    %plausibility check
                    Delete = 0;
                    PointInt = Parameters.ImageData(YPoint,XPoint);
                    if Parameters.Mode == 'H'
                        PointInt_Out = (mean(mean(Parameters.ImageData((YPoint-5):(YPoint+5), (XPoint-10):(XPoint-5)))) + mean(mean(Parameters.ImageData((YPoint-5):(YPoint+5), (XPoint+5):(XPoint+10)))))/2;
                        PointInt_In = (mean(mean(Parameters.ImageData((YPoint-9):(YPoint-4), XPoint))) + mean(mean(Parameters.ImageData((YPoint+4):(YPoint+9), XPoint))))/2;
                    elseif Parameters.Mode == 'V'
                        PointInt_Out = (mean(mean(Parameters.ImageData((YPoint-15):(YPoint-10), (XPoint-5):(XPoint+5)))) + mean(mean(Parameters.ImageData((YPoint+10):(YPoint+15), (XPoint-5):(XPoint+5)))))/2;
                        PointInt_In = (mean(mean(Parameters.ImageData(YPoint, (XPoint-4):(XPoint-2)))) + mean(mean(Parameters.ImageData(YPoint, (XPoint+2):(XPoint+4)))))/2;
                    end
                    if PointInt_In > PointInt*(1+Parameters.VarIn)
                        InCounter = InCounter + 1;
                        InPoint(InCounter, :) = [XPoint, YPoint];
                        Delete = 1;
                    end
                    if PointInt_Out < PointInt*(1+Parameters.VarOut)
                        OutCounter = OutCounter + 1;
                        OutPoint(OutCounter, :) = [XPoint, YPoint];
                        Delete = 1;
                    end
                    
                    if Delete == 0
                        Status.PointNo = Status.PointNo + 1;
                        Status.Points(Status.PointNo,:) = [XPoint YPoint];
                    end
                    Average = 0;
                    CoordinateSum = 0;
                    Counter = 0;
                end
            end
        end
        hold off
        clear Parabolic
    end
    clear xdata ydata NormData
    axes(handles.Axes_Image)
    hold on
    if Parameters.Mode == 'H'
        plot(InPoint(:, 1), InPoint(:, 2), 'r^', OutPoint(:,1), OutPoint(:,2), 'r<')
    elseif Parameters.Mode == 'V'
        plot(InPoint(:, 1), InPoint(:, 2), 'r<', OutPoint(:,1), OutPoint(:,2), 'r^')
    end
    plot(Status.Points(:,1), Status.Points(:,2), 'go', Status.Points(:,1), Status.Points(:,2), 'gx')
    hold off
    Status.Loop = 1;
    uiresume



function Button_ClearCracks_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    cla(handles.Axes_Graph)
    DisplayImage(handles, Files.ActualFile)
    Status.PointNo = 0;
    Status.Points = [];
    Status.Loop = 1;
    uiresume



function Button_Manual_Callback(hObject, eventdata, handles)
    global Status Parameters Files
    set(handles.Text_Status, 'String', sprintf('L E F T - C L I C K  for adding crack markers,\n R I G H T - C L I C K  for removing bad markers.\n Press  R E T U R N  to continue.'))
    axes(handles.Axes_Image)
    hold on
    Loop = 1;
    Delete = 0;
    while Loop == 1
        [XPoint,YPoint,Key]=ginput(1);
        if isempty(Key)
            Loop = 0;
        else
            if Key == 3
                if Status.PointNo > 0
                    %delete bad points
                    for i=1:Status.PointNo
                        if abs(XPoint - Status.Points(i,1)) <= 2
                            if abs(YPoint - Status.Points(i,2)) <= 2
                                XPoint = Status.Points(i,1);
                                YPoint = Status.Points(i,2);
                                plot(XPoint, YPoint, 'rx',XPoint, YPoint, 'ro')
                                Delete(1) = 1;
                                Delete(2) = i;
                            end
                        end
                    end
                    if Delete(1) == 1
                        Status.Points(Delete(2),:)=[];
                        Status.PointNo = Status.PointNo - 1;
                        Delete = 0;
                    end
                end
            elseif Key == 1
                %collect points of intersection
                if Parameters.Mode == 'H'
                    if XPoint >= Parameters.LinePosX(1) && XPoint <= Parameters.LinePosX(2)
                        for i=1:Parameters.LineNumber
                            if abs(YPoint - Parameters.LinePosY(i)) <= 2
                                YPoint = Parameters.LinePosY(i);
                                Status.PointNo = Status.PointNo + 1;
                                Status.Points(Status.PointNo,1:2) = [XPoint, YPoint];
                                plot(XPoint, YPoint, 'gx',XPoint, YPoint, 'go')
                            end
                        end
                    end
                elseif Parameters.Mode == 'V'
                    if YPoint >= Parameters.LinePosY(1) && YPoint <= Parameters.LinePosY(2)
                        for i=1:Parameters.LineNumber
                            if abs(XPoint - Parameters.LinePosX(i)) <= 2
                                XPoint = Parameters.LinePosX(i);
                                Status.PointNo = Status.PointNo + 1;
                                Status.Points(Status.PointNo,1:2) = [XPoint, YPoint];
                                plot(XPoint, YPoint, 'gx',XPoint, YPoint, 'go')
                            end
                        end
                    end
                end
            end        
        end
    end
    hold off
    clear XPoint YPoint Key
    set(handles.Text_Status, 'String', '')
    Status.Loop = 1;
    uiresume

    

function Button_Accept_Callback(hObject, eventdata, handles)
    global Status Parameters Files SavedParameters
    %save parameter file
    SavedParameters.Scale.ScaleRatio = Parameters.ScaleRatio;
    SavedParameters.Scale.Scalebar = Parameters.Scalebar;
    SavedParameters.Scale.ScaleLength = Parameters.ScaleLength;
    SavedParameters.Area.LinePosX = Parameters.LinePosX;
    SavedParameters.Area.LinePosY = Parameters.LinePosY;
    SavedParameters.Area.LineNumber = Parameters.LineNumber;
    SavedParameters.Settings.IntThrd = Parameters.IntThrd;
    SavedParameters.Settings.VarIn = Parameters.VarIn;
    SavedParameters.Settings.VarOut = Parameters.VarOut;
    SavedParameters.Settings.Mode = Parameters.Mode;
    save ([Files.Path, 'FA-parameters.dat'], 'SavedParameters', '-mat')
    %determine crack/buckle density
    if Parameters.Mode == 'H'
        LineLength = abs(Parameters.LinePosX(2)-Parameters.LinePosX(1))*Parameters.LineNumber;
    elseif Parameters.Mode == 'V'
        LineLength = abs(Parameters.LinePosY(2)-Parameters.LinePosY(1))*Parameters.LineNumber;
    end
    CrackDensity = Status.PointNo / (LineLength*Parameters.ScaleRatio);
    MeanCrackDist = 1 / CrackDensity;
    CrackDensityErr = CrackDensity/sqrt(Status.PointNo);
    MeanCrackDistErr = MeanCrackDist/sqrt(Status.PointNo);
    String = sprintf('Mean crack / buckle distance:  %f  m \n Crack / buckle density:  %f 1/m', MeanCrackDist, CrackDensity);
    Status.OutputData(Files.FileCounter, :) = [CrackDensity CrackDensityErr MeanCrackDist MeanCrackDistErr 0 0];

    if Status.PointNo > 2*Parameters.LineNumber
        %determine crack/buckle distance distribution
        TotalDistance = 0;
        CrackSizeDistributionTemp = [0, 0];
        for i = 1 : Parameters.LineNumber
            LinePointNo = 0;
            LinePoints = 0;
            if Parameters.Mode == 'H'
                for j = 1 : Status.PointNo
                    if Status.Points(j,2) == Parameters.LinePosY(i)
                        LinePointNo = LinePointNo + 1;
                        LinePoints(LinePointNo) = Status.Points(j,1);
                    end
                end
            elseif Parameters.Mode == 'V'
                for j = 1 : Status.PointNo
                    if Status.Points(j,1) == Parameters.LinePosX(i)
                        LinePointNo = LinePointNo + 1;
                        LinePoints(LinePointNo) = Status.Points(j,2);
                    end
                end
            end
            LinePoints = sort(LinePoints, 'ascend');
            if LinePointNo > 1
                for j = 1 : (LinePointNo - 1)
                    DistanceTemp = LinePoints(j+1)-LinePoints(j);
                    TotalDistance = [TotalDistance, DistanceTemp];
                end
            end
            clear DistanceTemp
        end
        TotalDistance(1) = [];    
        DistrCount = 0;
        CrackNumber = 0;
        for i = 1 : max(TotalDistance)
            Index = 0;
            for j = 1 : size(TotalDistance, 2)
                if i == TotalDistance(j)
                    CrackNumber = CrackNumber + 1;
                    Index = 1;
                end
            end
            if Index == 1
                DistrCount = DistrCount + 1;
                CrackSizeDistrTemp(DistrCount, 1) = i;
                CrackSizeDistrTemp(DistrCount, 2) = CrackNumber;
            end
        end
    
        CrackSizeDistrTemp(:,1) = (CrackSizeDistrTemp(:,1) * Parameters.ScaleRatio);
        CrackSizeDistrTemp(:,2) = CrackSizeDistrTemp(:,2) / CrackNumber;
        CrackSizeDistr(:,1) = CrackSizeDistrTemp(:,1);
        CrackSizeDistr(:,2) = CrackSizeDistrTemp(:,1)/MeanCrackDist;
        CrackSizeDistr(:,3) = CrackSizeDistrTemp(:,2);    
        axes(handles.Axes_Graph)
        plot (CrackSizeDistr(:,1),CrackSizeDistr(:,3), 'gx')
        set(handles.Axes_Graph, 'Color', [0 0 0], 'XColor', [1 1 1], 'YColor', [1 1 1], 'YAxisLocation', 'right')
        xlabel(handles.Axes_Graph, 'crack / buckle distance  [m]', 'Color', 'w')
        ylabel(handles.Axes_Graph, 'cummulative probability  [-]', 'Color', 'w')
        
        Weibull(1:2)=0; 
        hold on        
        xdata = CrackSizeDistr(:,1);
        ydata = CrackSizeDistr(:,3);
        WeibullGuess(2) = 2.5;
        WeibullGuess(1) = exp(log(log(2))/WeibullGuess(2))/MeanCrackDist;
        exitflag = 0;
        i = 0;
        while exitflag == 0
            i = i + 1;
            [Weibull,resnorm,residual,exitflag]  = lsqcurvefit(@(Weibull, xdata) 1-exp(-(Weibull(1)*xdata).^Weibull(2)), WeibullGuess, xdata, ydata, [0 0], [Inf Inf]);
            WeibullGuess = Weibull;
            if i == 20
                exitflag = 1;
            end
        end
        xtest = [0:1:(max(xdata)*1.1)];
        ytest = 1-exp(-(Weibull(1)*xtest).^Weibull(2));
        plot (xtest,ytest,'r:');
        hold off
        String = [String sprintf('\n Weibull parameters: %f , %f', Weibull(1), Weibull(2))];
        Status.OutputData(Files.FileCounter, 5:6) = [Weibull(1) Weibull(2)];
        save ([Files.Path 'CBDistr_' Parameters.Mode '_' Files.Filelist(Files.FileCounter, 1:size(Files.Filelist(Files.FileCounter,:),2)-4) '.dat'], 'CrackSizeDistr', '-ASCII', '-tabs')
        clear resnorm residual exitflag CrackSizeDistrTemp CrackSizeDistr
    end
    set(handles.Text_Status, 'String', String)
    OutputData = Status.OutputData;
    Files.OutputFile = ['FBAnalysis_', Parameters.Mode, '_', Files.Filelist(1,1:(size(Files.Filelist, 2)-4)), '-', Files.Filelist(Files.FileCounter,1:(size(Files.Filelist, 2)-4)), '.dat'];
    save ([Files.Path, Files.OutputFile], 'OutputData', '-ASCII', '-tabs')
    if Files.FileCounter ~=1
        delete ([Files.Path, Files.OldFile])
    end
    Files.OldFile = Files.OutputFile;
    if Parameters.PointXYSave == 1
        XYPoints = Status.Points;
        if Parameters.Mode == 'H'
            XYPoints = sortrows(XYPoints, [2 1]);
        elseif Parameters.Mode == 'V'
            XYPoints = sortrows(XYPoints, [1 2]);
        end
        XYPoints(:,3) = XYPoints(:,1) * Parameters.ScaleRatio;
        XYPoints(:,4) = XYPoints(:,2) * Parameters.ScaleRatio;
        save ([Files.Path 'MarkerPos_' Parameters.Mode '_' Files.Filelist(Files.FileCounter, 1:size(Files.Filelist(Files.FileCounter,:),2)-4) '.dat'], 'XYPoints', '-ASCII', '-tabs')
    end

    if Files.FileCounter == size(Files.Filelist, 1)
        String = [String sprintf('\n End of filelist reached.')];
        set(handles.Text_Status, 'String', String)
        set(handles.Button_FileALoad, 'Enable', 'off')
        set(handles.Button_Accept, 'Enable', 'off')
        set(handles.Button_SetScale, 'Enable', 'off')
        set(handles.Button_LineDirection, 'Enable', 'off')
        set(handles.Button_SetArea, 'Enable', 'off')
        set(handles.Edit_ScaleLength, 'Enable', 'off')
        set(handles.Edit_LinesNo, 'Enable', 'off')
        set(handles.Slider_Threshold, 'Enable', 'off')
        set(handles.Slider_VarIn, 'Enable', 'off')
        set(handles.Slider_VarOut, 'Enable', 'off')
        set(handles.Button_ClearCracks, 'Enable', 'off')
        set(handles.Button_StartCrackFind, 'Enable', 'off')
        set(handles.Button_Manual, 'Enable', 'off')
        Status.Loop = 1;
    else
        Files.FileCounter = Files.FileCounter + 1;
        Files.ActualFile = Files.Filelist(Files.FileCounter, :);
        DisplayImage(handles, Files.ActualFile)
        Status.PointNo = 0;
        Status.Points = [];
        figure(handles.Main)
        uiwait(handles.Main, 10)
        if ishandle(handles.Main)
            cla(handles.Axes_Graph)
            set(handles.Text_Status, 'String', '')
            Status.Loop = 1;
        else
            Status.Loop = 0;
        end
    end
    uiresume

Contact us