image thumbnail

Black & white image enhancer

by

 

25 Oct 2010 (Updated )

Application can can work wonders on grayscale images with only a few controls.

LoFiImgGUIv2.m
function LoFiImgGUIv2

% The program generates gray-scale lo-fi images from colour pictures. The
% user has the option of selecting the number of gray-scale shades wanted
% in the image. There is option for selecting the gray-scale range 
% within which the user wants to work on. There is also an option for
% thresholding the gray shades, which helps working with lighter or darker 
% shade images.
% 
% 

warning off all

dx=0.5; dy=-0.1;

fmain=figure(394857);
clf
set(fmain,'MenuBar','none',...
    'Name','Lo-Fi Image WS',...
    'NumberTitle','off',...
    'Color',[0.8314    0.8157    0.7843]);

%%%%% defining push buttons %%%%%
% browse button
brws=uicontrol(fmain,'Style','pushbutton',...
    'Units','normalized',...
    'Position',[0.05 0.925 0.9 0.045],...
    'String','Select Image File ...',...
    'ForegroundColor',[1 1 1]*0.3,...
    'FontWeight','demi',...
    'Callback',{@browse_callback});

% generate image
generate1=uicontrol(fmain,'Style','pushbutton',...
    'Units','normalized',...
    'Position',[0.05 0.035 0.4 0.045],...
    'String','Generate',...
    'Enable','off',...
    'ForegroundColor',[1 1 1]*0.3,...
    'Callback',{@generate1_callback});

% save image
saveImg=uicontrol(fmain,'Style','pushbutton',...
    'Units','normalized',...
    'Position',[0.55 0.035 0.4 0.045],...
    'String','Save Image',...
    'Enable','off',...
    'ForegroundColor',[1 1 1]*0.3,...
    'Callback',{@saveImg_callback});


% edit texts
editShades1=uicontrol(fmain,'Style','edit',...
    'Units','normalized',...
    'Position',[0.85 0.175 0.05 0.05],...
    'String','9',...
    'Visible','off',...
    'BackgroundColor',[1 1 1],...
    'Callback',{@editShades1_callback});


% defining static texts
shades1Txt=uicontrol(fmain,'Style','text',...
    'Units','normalized',...
    'Position',[0.775 0.235 0.2 0.03],...
    'Visible','off',...
    'ForegroundColor',[1 1 1]*0.3,...
    'String','Number of Shades');

% display filename
fileTxt=uicontrol(fmain,'Style','text',...
    'Units','normalized',...
    'Position',[0.55 0.09 0.4 0.035],...
    'Visible','off',...
    'ForegroundColor',[1 1 1]*.3,...
    'FontSize',7,...
    'String','Output file: ');


% defining axes for input image
axes1Handle=axes('Position',[0.05 0.525 0.4 0.375]);
set(axes1Handle,'Visible','off');

% defining axes for image histogram
axes2Handle=axes('Position',[0.55 0.525 0.4 0.3]);
set(axes2Handle,'Visible','off');

% defining axes for output image
axes3Handle=axes('Position',[0.05 0.1 0.4 0.375]);
set(axes3Handle,'Visible','off');


%%%%%%%%% slider %%%%%%%%%
dxS=0; dyS=-0.03;
% start slider
editSlider(1)=uicontrol(fmain,'Style','slider',...
    'Units','normalized',...
    'Position',[dxS+0.52 dyS+0.49 0.46 0.035],...
    'Enable','off',...
    'SliderStep',[1/255 1/255],...
    'Value',0,...
    'Max',255,...
    'Min',0,...
    'Backgroundcolor',[1 1 1]*.9,...
    'Visible','off',...
    'Callback',{@slider_callback,1});

% end slider
editSlider(2)=uicontrol(fmain,'Style','slider',...
    'Units','normalized',...
    'Position',[dxS+0.52 dyS+0.45 0.46 0.035],...
    'Enable','off',...
    'SliderStep',[1/255 1/255],...
    'Value',255,...
    'Max',255,...
    'Min',0,...
    'Backgroundcolor',[1 1 1]*0.3,...
    'Visible','off',...
    'Callback',{@slider_callback,2});

% slider values
sliderVal(1)=uicontrol(fmain,'Style','edit',...
    'HorizontalAlignment','center',...
    'Units','normalized',...
    'Position',[dxS+0.52 dyS+0.4 0.05 0.04],...
    'String','0',...
    'Backgroundcolor',[1 1 1]*.9,...
    'ForegroundColor',[1 1 1]*0.3,...
    'Visible','off',...
    'Callback',{@sliderVal_callback,1});

sliderVal(2)=uicontrol(fmain,'Style','edit',...
    'HorizontalAlignment','center',...
    'Units','normalized',...
    'Position',[dxS+0.93 dyS+0.4 0.05 0.04],...
    'String','255',...
    'Backgroundcolor',[1 1 1]*0.3,...
    'ForegroundColor',[1 1 1]*0.9,...
    'Visible','off',...
    'Callback',{@sliderVal_callback,2});


%%%%%%%%% radio buttons %%%%%%%%%
dxR=.525; dyR=-.1;
% logarithmic
radioButtonTxt=uicontrol(fmain,'Style','text',...
    'Units','normalized',...
    'Position',[dxR dyR+0.385 0.25 0.03],...
    'Visible','off',...
    'ForegroundColor',[1 1 1]*0.3,...
    'String','Discretisation Method');

RadioB(1)=uicontrol(fmain,'Style','radiobutton',...
    'Units','normalized',...
    'Position',[dxR+0.05 dyR+0.325 0.15 0.05],...
    'String','Logarithmic',...
    'Visible','off',...
    'Value',0,...
    'ForegroundColor',[1 1 1]*0.3,...
    'Callback',{@radio_callback,1});
% linear
RadioB(2)=uicontrol(fmain,'Style','radiobutton',...
    'Units','normalized',...
    'Position',[dxR+0.05 dyR+0.275 0.15 0.05],...
    'String','Linear',...
    'Value',1,...
    'Visible','off',...
    'ForegroundColor',[1 1 1]*0.3,...
    'Callback',{@radio_callback,2});
% power-holic
RadioB(3)=uicontrol(fmain,'Style','radiobutton',...
    'Units','normalized',...
    'Position',[dxR+0.05 dyR+0.225 0.15 0.05],...
    'String','Power',...
    'Value',0,...
    'Visible','off',...
    'ForegroundColor',[1 1 1]*0.3,...
    'Callback',{@radio_callback,3});
editTxtRadio=uicontrol(fmain,'Style','edit',...
    'Units','normalized',...
    'Position',[dxR+0.17 dyR+0.23 0.05 0.04],...
    'String','2',...
    'Visible','off',...
    'BackgroundColor',[1 1 1],...
    'Callback',{@radio_callback,3});

set(get(fmain,'Children'),...
    'FontName','Comic Sans MS',...
    'FontSize',8);

ib=uicontrol(fmain,'Style','text',...
    'FontName','Comic Sans MS',...
    'FontSize',7,...
    'String',' Indraneel & Sucharita Biswas',...
    'Units','normalized',...
    'Position',[0.67 0.005 0.4 0.025]);

set(fileTxt,'FontSize',7)
    
% define application data handle
aData.thresh=[1 255];
aData.method=2;
aData.N=9;
aData.image=[];
setappdata(fmain,'aData',aData)



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% select input image
    function browse_callback(hObject,eventdata)
        
        aData=getappdata(fmain,'aData');
        
        [filename,pathname,fi]=uigetfile('*.jpg');
        if fi==0
            return
        else
            % activate other buttons
            set(generate1,'Enable','on')
            set(editSlider,'Enable','on')
            set(RadioB,'Enable','on')
            set(saveImg,'Enable','off')
            set(get(fmain,'Children'),'Visible','on');
            set(axes3Handle,'Visible','off')
            set(fileTxt,'String','Output file: ',...
                'FontSize',7,...
                'ForegroundColor',[1 1 1]*0.3)
            set(editTxtRadio,'Visible','off')
            set(fileTxt,'Visible','off')
        end

        cd(pathname)
        image=imread(filename);
        aData.filename=filename;
        
        axes(axes1Handle);
        if length(size(image))==3
            image=rgb2gray(image);
        end
        
        aData.image=image;
        imshow(image)
        
        % image histogram info
        for i=1:256
            T(i)=sum(sum(image==(i-1)))/(size(image,1)*size(image,2));
        end
        I=1:256;
        
        % save data
        aData.T=T;
        aData.I=I;
        % plot data
        axes(axes2Handle);
        plot(I,T,'-r',I([1 256]),T([1 256]),'ok')

        % setting axes aspect ratios
        set(axes2Handle,...
            'PlotBoxAspectRatio',[size(image,2), size(image,1), 1],...
            'YTick',[],...
            'FontName','Comic Sans MS',...
            'FontSize',8);
        tmp=get(axes1Handle,'Position'); tmp(1)=tmp(1)+0.5;
        set(axes2Handle,'Position',tmp);
        clear tmp
        axis([0 255 0 1.1*max(T)])
        
        setappdata(fmain,'aData',aData)

    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% slider numeric value
    function sliderVal_callback(hObject,eventdata,i)
        
        aData=getappdata(fmain,'aData');
        
        s=round(str2double(get(sliderVal,'String')));
        if s(2)<=0
            set(sliderVal(2),'String','');
            return
        end
        if s(1)>=255
            set(sliderVal(1),'String','');
            return
        end
        if s(1)>=s(2)
            if i==1
                if s(1)<255
                    s(2)=s(1)+1;
                else
                    s(2)=255;
                    s(1)=254;
                end
                set(sliderVal(2),'String',num2str(s(2)));
            else
                if s(2)>0
                    s(1)=s(2)-1;
                else
                    s(1)=0;
                    s(2)=1;
                end
                set(sliderVal(1),'String',num2str(s(1)));
            end
        end
        set(editSlider(1),'Value',s(1));
        set(editSlider(2),'Value',s(2));
        aData.thresh=s;
        
        % plot data
        axes(axes2Handle);
        plot(aData.I,aData.T,'-r',aData.I(s+1),aData.T(s+1),'ok')

        % setting axes aspect ratios
        set(axes2Handle,...
            'PlotBoxAspectRatio',[size(aData.image,2), size(aData.image,1), 1],...
            'YTick',[],...
            'FontName','Comic Sans MS',...
            'FontSize',8);
        tmp=get(axes1Handle,'Position'); tmp(1)=tmp(1)+0.5;
        set(axes2Handle,'Position',tmp);
        clear tmp
        axis([0 255 0 1.1*max(aData.T)])
        
        setappdata(fmain,'aData',aData);
        
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% threshold slider
    function slider_callback(hObject,eventdata,i)
        
        aData=getappdata(fmain,'aData');
        
        s(1)=round(get(editSlider(1),'Value'));
        s(2)=round(get(editSlider(2),'Value'));
        if s(1)>=s(2)
            if i==1
                if s(1)<255
                    s(2)=s(1)+1;
                else
                    s(2)=255;
                    s(1)=254;
                end
                set(editSlider(2),'Value',s(2));
            else
                if s(2)>0
                    s(1)=s(2)-1;
                else
                    s(1)=0;
                    s(2)=1;
                end
                set(editSlider(1),'Value',s(1));
            end
        end
        set(sliderVal(1),'String',num2str(s(1)));
        set(sliderVal(2),'String',num2str(s(2)));

        aData.thresh=s;
        % plot data
        axes(axes2Handle);
        plot(aData.I,aData.T,'-r',aData.I(s+1),aData.T(s+1),'ok')

        % setting axes aspect ratios
        set(axes2Handle,...
            'PlotBoxAspectRatio',[size(aData.image,2), size(aData.image,1), 1],...
            'YTick',[],...
            'FontName','Comic Sans MS',...
            'FontSize',8);
        tmp=get(axes1Handle,'Position'); tmp(1)=tmp(1)+0.5;
        set(axes2Handle,'Position',tmp);
        clear tmp
        axis([0 255 0 1.1*max(aData.T)])

        setappdata(fmain,'aData',aData);
        
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% select function type
    function radio_callback(hObject,eventdata,i)
        
        aData=getappdata(fmain,'aData');
        
        iv=zeros(3,1); iv(i)=1;
        for j=1:3
            set(RadioB(j),'Value',iv(j));
        end
        aData.method=i;
        
        if i==3
            set(editTxtRadio,'Visible','on')
            aData.pow=str2double(get(editTxtRadio,'String'));
        else
            set(editTxtRadio,'Visible','off');
        end
        
        setappdata(fmain,'aData',aData);
        
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
    function editShades1_callback(hObject,eventdata)
        
        aData=getappdata(fmain,'aData');
        
        shades1=str2double(get(editShades1,'String'));
        if isnan(shades1)
            set(editShades1,'String','');
            return
        end
        if round(shades1)~=shades1
            set(editShades1,'String','');
            return
        end
        aData.N=shades1;
        
        setappdata(fmain,'aData',aData);
        
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%% calculation %%%%%%%
    function generate1_callback(hObject,eventdata)
        
        aData=getappdata(fmain,'aData');

        thresh=aData.thresh;
        N=aData.N;
        method=aData.method;
        image=aData.image;
        
        N=N-1;
        %assignin('base','method',method)

        switch method
            case 1
                % log threshold
                if thresh(1)==0, thresh(1)=1; end
                threshT=exp(linspace(log(thresh(1)),log(thresh(2)),N+1));
                assignin('base','threshT',threshT)
            case 2
                % linear thresholds
                threshT=linspace(thresh(1),thresh(2),N+1);
                assignin('base','threshT',threshT)
                % gsv=round(exp(linspace(0,log(255),N+1)));
            case 3
                % inverse-log
                pow=aData.pow;
                threshT=(linspace((thresh(1)).^pow,(thresh(2)).^pow,N+1)).^(1./pow);
                assignin('base','threshT',threshT)
            otherwise
                % linear thresholds
                threshT=linspace(thresh(1),thresh(2),N+1);
        end

        %assignin('base','threshT',threshT)
        gsv=round(linspace(0,255,N+1));
        
        imageT=ones(size(image));
        imageT(image>=threshT(N))=255;
        for i=N:-1:2
            imageT(image<threshT(i) & image>=threshT(i-1))=round(gsv(i));
        end
        imageT(image<=threshT(1))=threshT(1);
        imageT=uint8(imageT);

        axes(axes3Handle);
        imshow(imageT)
        
        aData.imageT=imageT;

        set(saveImg,'Enable','on')
        set(fileTxt,'Visible','on')
        setappdata(fmain,'aData',aData);
        
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save image
    function saveImg_callback(hObject,eventdata)
        
        aData=getappdata(fmain,'aData');
        fname=double(aData.filename);
        newfilename=char([fname(1:end-4) double('-LoFiImg.jpg')]);
        imwrite(aData.imageT,newfilename)
        set(fileTxt,'String',newfilename,...
            'FontSize',7,...
            'ForegroundColor',[1 1 1]*0.3)
        
    end

end

Contact us