%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file 'imageFilters.m' contains implementation of Linear and Non-Linear Image Filters.
%
% Programmer : Nilesh Ghubade (nileshg@temple.edu)
% Date : Oct 2002
% Advisor : Dr.Longin Jan Latecki (latecki@temple.edu )
% Project : Homework 2
% Department : Computer and Information Science Department, Temple University, Philadelphia, PA-19122, USA
%
% Input arguments:-
% imgFileName = Name of the input image to be filtered.
% defaultORPgmmedFuncs = The value 'default' for this parameters invokes default Non-Linear filter functions provided in the Image Processing
%                       Toolbox. The value 'allnonlinear' invokes the Non-Linear filters one-by-one implemented in this function
%                       and displays the resulting filtered image in a subplot of 4-by-2. The individual filters can be invoked
%                       by supplying individual filter names like 'median', 'mean', 'dilation' etc...
% order = The order of the window to be used during filtering.example: '3' indicates that neighbourhood of 3-by-3 should be considered
%           while computing the new intensity value for a particular pixel.
%
% Output : -
% The output is the filtered image.
%
% Example: -
% 1) imageFilters('noise_1.gif','allnonlinear',3)
% 2) imageFilters('noise_1.gif','dilation',3)
% 3) imageFilters('noise_1.gif','default',3)
% 4) imageFilters('noise_1.gif','laplacian',3)
% 5) imageFilters('noise_1.gif','smooth',3)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function imageFilters(imgFileName,defaultORPgmmedFuncs,order)
img = imread(imgFileName);
imgDouble = double(img);
colormap(gray(256));
switch defaultORPgmmedFuncs
case 'default'
	subplot(4,2,1); image(imgDouble);title('Input image in Gray scale');
	subplot(4,2,2); mesh(imgDouble);title('Mesh for the Input image');
	subplot(4,2,3); medianFilterOnimg = ordfilt2(imgDouble,5,ones(order,order));image(medianFilterOnimg);title('MEDIAN Filter on the input image in Gray scale');
	subplot(4,2,4); meanFilterOnimg = filter2(fspecial('average',order),imgDouble);image(meanFilterOnimg);title('MEAN Filter on the input image in Gray scale');
	subplot(4,2,5); minFilterOnimg = ordfilt2(imgDouble,1,ones(order,order));image(minFilterOnimg);title('EROSION (MIN) Filter on the input image in Gray scale');
	subplot(4,2,6); maxFilterOnimg = ordfilt2(imgDouble,9,ones(order,order));image(maxFilterOnimg);title('DILATION (MAX) Filter on the input image in Gray scale');
	subplot(4,2,7); openingFilterOnimg = ordfilt2(minFilterOnimg,9,ones(order,order));image(openingFilterOnimg);title('OPENING Filter on the input image in Gray scale');
	subplot(4,2,8); closingFilterOnimg = ordfilt2(maxFilterOnimg,1,ones(order,order));image(closingFilterOnimg);title('CLOSING Filter on the input image in Gray scale');

case 'smooth'
    filterMask = 1/9*[1 1 1; 1 1 1; 1 1 1] %filter mask for smoothing.
    filteredImg = filter2(filterMask,imgDouble); %convolution of the image with the filterMask.
    titleString = 'Smooth (Blurr) Filter on the input image in Gray scale';
    image(filteredImg);title(titleString);

    
case 'laplacian'
    filterMask = [1 1 1; 1 -8 1; 1 1 1] %laplacian filter mask for 8-neighbourhood to produce edges.
    filteredImg = filter2(filterMask,imgDouble); %convolution of the image with the filterMask.
    titleString = 'Laplacian Filter (for 8-neighbourhood) on the input image in Gray scale';
    image(filteredImg);title(titleString);

otherwise
%     imgDouble =[11 12 13 14
%                     21 22 23 24
%                     31 32 33 34
%                    ]
% 
%     order = 5;
                    
    paddedImgDouble = zeros(size(imgDouble,1)+(order-1),size(imgDouble,2)+(order-1));
    beginningRow = ((order-1)/2)+1;
    endingRow = beginningRow + size(imgDouble,1) - 1;
    beginningCol = ((order-1)/2)+1;
    endingCol = beginningCol + size(imgDouble,2) - 1;
    
    paddedImgDouble(beginningRow:endingRow,beginningCol:endingCol) = imgDouble;
%     paddedImgDouble    
    
    allFilters = {'median','mean','erosion','dilation','opening','closing'};
    noOfFilterOperations = 1;
    subplotFlag = 0;
    if (strcmpi(defaultORPgmmedFuncs,'allnonlinear'))
        noOfFilterOperations = size(allFilters,2);
        subplotFlag = 1;
       	subplot(4,2,1); image(imgDouble);title('Input image in Gray scale');
    	subplot(4,2,2); mesh(imgDouble);title('Mesh for the Input image');
        subplotCount = 3;
    end

    for noOfFilterOperationsCount = 1:noOfFilterOperations
        if (strcmpi(defaultORPgmmedFuncs,'allnonlinear'))
            defaultORPgmmedFuncs = allFilters(noOfFilterOperationsCount);
            defaultORPgmmedFuncs = defaultORPgmmedFuncs{1};
        end

        filteredImgRowCount = 1;
        for rowCount=beginningRow:1:endingRow
            filteredImgColCount = 1;
            for colCount=beginningCol:1:endingCol
                switch lower(defaultORPgmmedFuncs)
                case 'median'    
                    mask = paddedImgDouble(rowCount-((order-1)/2):rowCount-((order-1)/2)+order-1,colCount-((order-1)/2):colCount-((order-1)/2)+order-1);                    
                    filteredImg(filteredImgRowCount,filteredImgColCount) =  median(reshape(mask,1,size(mask,1)*size(mask,2)));
                    titleString = 'MEDIAN Filter on the input image in Gray scale';
                case 'mean'
                    mask = paddedImgDouble(rowCount-((order-1)/2):rowCount-((order-1)/2)+order-1,colCount-((order-1)/2):colCount-((order-1)/2)+order-1);
                    filteredImg(filteredImgRowCount,filteredImgColCount) =  mean(mean(mask));
                    titleString = 'MEAN Filter on the input image in Gray scale';
                case {'dilation','closing'}
                    mask = paddedImgDouble(rowCount-((order-1)/2):rowCount-((order-1)/2)+order-1,colCount-((order-1)/2):colCount-((order-1)/2)+order-1);
                    [rows,cols,nonZeroValues] = find(mask);
                    filteredImg(filteredImgRowCount,filteredImgColCount) =  max(nonZeroValues);
                    titleString = 'DILATION (MAX) Filter on the input image in Gray scale';
                case {'erosion','opening'}
                    mask = paddedImgDouble(rowCount-((order-1)/2):rowCount-((order-1)/2)+order-1,colCount-((order-1)/2):colCount-((order-1)/2)+order-1);
                    [rows,cols,nonZeroValues] = find(mask);
                    filteredImg(filteredImgRowCount,filteredImgColCount) =  min(nonZeroValues);
                    titleString = 'EROSION (MIN) Filter on the input image in Gray scale';
                otherwise
                    disp('Please specify filtering operation as median OR mean OR dilation OR erosion OR opening OR closing!');                
                end
                filteredImgColCount = filteredImgColCount + 1;
            end
            filteredImgRowCount = filteredImgRowCount + 1;
        end
            
            switch lower(defaultORPgmmedFuncs)
            case 'opening'
                paddedImgDouble(beginningRow:endingRow,beginningCol:endingCol) = filteredImg;
                additionalfilteredImgRowCount = 1;
                for rowCount=beginningRow:1:endingRow
                    additionalfilteredImgColCount = 1;
                    for colCount=beginningCol:1:endingCol
                        mask = paddedImgDouble(rowCount-((order-1)/2):rowCount-((order-1)/2)+order-1,colCount-((order-1)/2):colCount-((order-1)/2)+order-1);
                        [rows,cols,nonZeroValues] = find(mask);
                        filteredImg(additionalfilteredImgRowCount,additionalfilteredImgColCount) =  max(nonZeroValues);
                    end
                    additionalfilteredImgRowCount = additionalfilteredImgRowCount + 1;
                    titleString = 'OPENING Filter on the input image in Gray scale';
                end
                
            case 'closing'
                paddedImgDouble(beginningRow:endingRow,beginningCol:endingCol) = filteredImg;
                additionalfilteredImgRowCount = 1;
                for rowCount=beginningRow:1:endingRow
                    additionalfilteredImgColCount = 1;
                    for colCount=beginningCol:1:endingCol
                        mask = paddedImgDouble(rowCount-((order-1)/2):rowCount-((order-1)/2)+order-1,colCount-((order-1)/2):colCount-((order-1)/2)+order-1);
                        [rows,cols,nonZeroValues] = find(mask);
                        filteredImg(additionalfilteredImgRowCount,additionalfilteredImgColCount) =  min(nonZeroValues);
                    end
                    additionalfilteredImgRowCount = additionalfilteredImgRowCount + 1;
                    titleString = 'CLOSING Filter on the input image in Gray scale';
                end
                
            end
  
            paddedImgDouble(beginningRow:endingRow,beginningCol:endingCol) = imgDouble;
            
            if (subplotFlag == 1)
                subplot(4,2,subplotCount); image(filteredImg);title(titleString);
                subplotCount = subplotCount + 1;
                defaultORPgmmedFuncs = 'allnonlinear';
            end
    end      
        
        if (subplotFlag == 0)        
            titleString = strcat(defaultORPgmmedFuncs,' Filter on the input image in Gray scale');
            image(filteredImg);title(titleString);
        end        


end

return