Code covered by the BSD License  

Highlights from
Can you hear the Image? Tool that allows you to transform image into audible sounds

image thumbnail

Can you hear the Image? Tool that allows you to transform image into audible sounds

by

 

This demo transforms image spatial information to sounds. It helps blind to "see" the image.

SOI_SoundsOfImages(varargin)
function SOI_SoundsOfImages(varargin)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SOI_SoundsOfImages - loads image and allows to produce sounds from different areas.
% Sound generation is based on spatial characteristics of the image in the region of interest.
% ROI is controlled by rectangle, which is moved by the user.
% 
% Input:
%   Image and User cursor location
% Output:
%   Sound
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%---------------------------------
% Vers  Date      Who Description:
%---------------------------------
% 03   04.09.12  UD  Resolving play in Matlab 2011b. 
%                    Unfortunately only obsolete function wavplay is working. 
%                    The solution for old Matlab versions is not tested.
% 02   18.04.11  UD  Adding more GUI controls 
% 01   17.04.11  UD  Created 
%---------------------------------

% test vector
y = []; Fs = [];
load handel;

% audio player handle
%aph             = audioplayer(y,Fs,8);
% if (~isempty(daqfind))
%     stop(daqfind)
% end
% ao = analogoutput('winsound', 0);
% addchannel(ao, [1 2]);
% set(ao, 'StandardSampleRates','Off')
% set(ao, 'SampleRate', Fs);

%cdata			= [];
rph             = [];
lph             = [];
imdatadir       = pwd;   % contains the input images latest path
userData        = [];   % container of the results
imLoad          = [];   % the original image
imTrans         = [];   % transformed image
imLoadH         = []; % handle to the image
imTransH        = [];  % transformed image horizontal edges
imTransV        = [];  % transformed image vertical edges
imTransNormEdge = [];  % edge norm
imEdgeH         = [];  % handles to edge display
ThrEdge         = (15*8); % image threshold : 7 gray level diffrence, 4 - sobel mask
imEdgeThr       = [];   % thresholded image of significant edges
indEgde         = [];   % contains edge indices

% create sound parameters
sndAlgorithm    = 1;   % default sound algorithm
Fs              = 8e3;  % sound frequency Hz
sndData         = [];  % contains sound samples
sndFreqNum      = 8;   % number of different frequencies 
sndTimeLen      = 512; % number of samples for time gen
sndTime         = 2*pi*(1:sndTimeLen)'/Fs;
%sndFreq         = zeros(sndTimeLen,1);  % vector of freq 
sndFreq         = floor(logspace(log10(600),log10(sndTimeLen*6),sndFreqNum)); % must be row vector
%sndFreq         = floor(linspace(100,sndTimeLen-10,sndFreqNum)); % must be row vector
sndAmp          = ones(sndFreqNum,1);  % amplitude of different freq
sndAmp          = sndAmp./4; % must have norm 1 column vector
sndAmpDefault   = sndAmp*0;
angleBins       = linspace(-pi,pi - 2*pi/sndFreqNum,sndFreqNum); % contains hist bins for sound
sndWindow       = hamming(sndTimeLen);

% % init windows output device
% ao              = analogoutput('winsound', 0);
% addchannel(ao, [1 2]);
% set(ao, 'StandardSampleRates','Off')
% set(ao, 'SampleRate', Fs);


% create window cursor - user dragable rectangle
winHalfLen      = 16;
winX            = [-winHalfLen -winHalfLen winHalfLen winHalfLen -winHalfLen];
winY            = [-winHalfLen winHalfLen winHalfLen -winHalfLen -winHalfLen];
winLR           = [1 1]; % defines region coordinates
winUD           = [1 1];
rectH           = []; % user rectangle

% different params
[nrows,ncols] = size(imLoad);        


% check what we got as input
error(nargchk(0, 1, nargin))
if nargin > 0
%    switch class(varargin{1})
%         case 'cell' % got cell array 
%             results = varargin{1};
%         case 'char'
%             try
%                 load(varargin{1}, 'results');
%             catch
%                 h = errordlg(lasterr);
%                 waitfor(h);
%             end
%     end
end


% create figure without standard toolbar
fig = figure(...
    'ToolBar', 'none'...
    ,'Menubar', 'none'...
    ,'Units', 'pixels'...
    ,'NumberTitle', 'off'...
    ,'Name', 'Sounds Of Images'...
    ,'ResizeFcn', @figure_resize...
    ,'PaperPositionMode', 'auto'...
    ,'DoubleBuffer','on'...
    ,'InvertHardcopy','off'...
    ,'CloseRequestFcn',@figure_closefcn...
    ,'WindowButtonMotionFcn',@play_sounds ...
    );


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% create menu bar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fmh = uimenu('Label','File ...');
      uimenu(fmh,'Label','Open','Callback',@load_uifile);
      uimenu(fmh,'Label','Save','Callback','');
      uimenu(fmh,'Label','Quit','Callback','delete(gcf)','Separator','on','Accelerator','Q');

imh = uimenu('Label','Image ...');
      uimenu(imh,'Label','Reset to Original Image','Callback',{@scale_Image,1});
      uimenu(imh,'Label','Scale Image Size by 1/2',   'Callback',@scale_Image);
      uimenu(imh,'Label','Scale Window Size by 2',  'Callback',{@scale_Window,1});
      uimenu(imh,'Label','Scale Window Size by 1/2',  'Callback',{@scale_Window,-1});
      uimenu(imh,'Label','Show Edges',      'Callback',@show_ImageEdges,'Checked','off','Separator','on');
      
smh = uimenu('Label','Sound ...');
      uimenu(smh,'Label','Algorithm 1',     'Callback',{@select_SoundAlgorithm,1},'Checked','on');
      uimenu(smh,'Label','Algorithm 2',     'Callback',{@select_SoundAlgorithm,2},'Checked','off');
      uimenu(smh,'Label','Check Your Computer Sound','Callback',@check_Sound,'Separator','on');
      uimenu(smh,'Label','Test Sound Generation','Callback',@test_SoundGen);
     
  
hmh = uimenu('Label','Help ...');
      uimenu(hmh,'Label','How To...',   'Callback',@show_HelpHowTo);
      uimenu(hmh,'Label','About',       'Callback',@show_HelpAbout);
      
      
      


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% create left panel (for axes)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pos = get_lpanel_position;
lph = uipanel(...
    'Parent', fig...
    ,'Units', 'pixels'...
    ,'Position', pos...
    ,'ResizeFcn', @lpanel_resize...
    );


% create axes
axh = axes(...
    'Parent', lph ...
    ,'Units', 'normalized'...
    ,'HitTest','off'...
    ,'Position', [0 0 1 1]...
    ,'XTick', []...
    ,'YTick', []...
    );
%axis image;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% position control
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% left side panel position
    function pos = get_lpanel_position
        orig_units = get(fig, 'Units');
        set(fig, 'Units', 'pixels');
        fpos = get(fig, 'Position'); %figure position
        set(fig, 'Units', orig_units);

        %rpos = get_rpanel_position; % right side panel position

        pos(1) = 0;
        pos(2) = 0;
        pos(3) = fpos(3) ; %- rpos(3) - 1;
        pos(4) = fpos(4);
    end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% resizing window we must update internal elements
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function figure_resize(varargin)
        lpos = get_lpanel_position;
        set(lph, 'Position', lpos);
    end

% 
    function lpanel_resize(varargin)
        % axes are resized automatically
    end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%    Helper functions   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% clear axes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function show_HelpHowTo(varargin)
        web('README.txt');
        
    end % show_HelpHowTo


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% show help about using this Tool
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function show_HelpAbout(src,event)
        warndlg('This tool has been created by Uri Dubin. Version 03.');
        
    end % show_HelpAbout



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% close
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    function figure_closefcn(src,evnt)
    % User-defined close request function 
       % delete(ao);
        delete(gcf);
    end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%                                                                                                                                                                            %%%%%%%
%%%%                Main functions                                                                                           %%%%%%%
%%%%                                                                                                                                                                            %%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load file by means of uigetfile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function load_uifile(varargin)
    %PhasePar = [];PhaseTSet = []; 
    cdir = pwd;
    %cd('..\Tmp\');
    cd(imdatadir);
    [fileN,pathName] = uigetfile({'*.jpg;*.JPG;*.tif;*.tiff;*bmp;*.png'}, 'Select Image Data',...
        'Image Files', 'MultiSelect','off'); %,imdatadir);
    cd(cdir)
    
    if isequal(fileN,0),
        return;
    elseif ~isa(fileN,'cell'),
        fileName{1} = fileN; % convert to cell object
    else
        fileName    = fileN;
    end
    imdatadir = pathName;

    % check if the data is already there
    userData.fileName   = fileName;
    userData.pathName   = pathName;
        
    
    % check index
    idx = 1;

    %determine file type
    fname       = fullfile(userData.pathName, userData.fileName{idx}) ;
    imLoad      = imread(fname);
    if ndims(imLoad) == 3, imLoad = rgb2gray(imLoad); end;
    if ~isa(imLoad,'uint8'), 
        MaxV     = double(max(imLoad(:))); 
        imLoad   = uint8(double(imLoad)./MaxV*255);
    end;

    % test
    %imLoad    = ones(256); imLoad(100:162,100:162) = 80;
    
    imTrans  = imLoad; 
    disp_results();
    
    
    end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display images and user selections
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function ret = disp_results(varargin)
            
        ret = 0;
        
        % check
        if isempty(imLoad),
            warndlg(' No data has been loaded.')
            return;
        end;
        
       [nrows,ncols] = size(imTrans);             
       imLoadH = image(imTrans,'Parent', axh); colormap(gray(256));
       set(imLoadH,'EraseMode','none');

       hold on;
       rectH = plot(axh,winX,winY,'visible','off');
       hold off;
       
       % update edge data
       compute_ImageEdges();       
       
       % delete edges
        %delete(imEdgeH);

       ret = 1;
            
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% scale the current image by 1/2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function scale_Image(varargin)
        
       if isempty(imTrans), return; end;
        
       if length(varargin) < 3, % no additional input exists 
           imTrans  = imresize(imTrans,.5); 
       else
           imTrans  = imLoad;
       end;
       disp_results(); 
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% scale the current Window by 2 or 1/2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function scale_Window(varargin)
        
        if isempty(imTrans), return; end;
        
        if varargin{3} > 0, %scale up
            winHalfLen      = min(winHalfLen*2,64);
        else
            winHalfLen      = max(winHalfLen/2,4);
        end;
        
        winX            = [-winHalfLen -winHalfLen winHalfLen winHalfLen -winHalfLen];
        winY            = [-winHalfLen winHalfLen winHalfLen -winHalfLen -winHalfLen];
        
        disp_results();
    end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Edge Detection 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function compute_ImageEdges(varargin)
        
        %H			= fspecial('sobel');
        H           = conv2(fspecial('sobel'),fspecial('gaussian',[5 5],3));
        H           = H./norm(H(:));
        imTransH    = imfilter(double(imTrans),H','replicate');
        imTransV	= imfilter(double(imTrans),H,'replicate');

        % % show
        % set(gcf,'CurrentAxes',axh);
        % figure(FigNum),FigNum=FigNum+1;
        % imagesc(Im),colormap(gray);
        % hold on;
        % quiver(ImV,ImH);
        % hold off;
        % title('Original Image with edges');
         % show long edges only
        imTransNormEdge    = sqrt(imTransH.^2 + imTransV.^2);
        imEdgeThr          = imTransNormEdge > ThrEdge;   
%         imTransH           = imTransH.*imEdgeThr;
%         imTransV           = imTransV.*imEdgeThr;


        % figure(FigNum),
        % hold on;
        % quiver(x(IndEgde),y(IndEgde),ImH(IndEgde),ImV(IndEgde),'r');
        % hold off;
        % title('Original Image with Strong edges');
       

    end % compute_ImageEdges


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display the edge info on the current image
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function show_ImageEdges(varargin)

        if strcmp(get(gcbo, 'Checked'),'on')
            set(gcbo, 'Checked', 'off');
            delete(imEdgeH)
            return;
        else 
            set(gcbo, 'Checked', 'on');
        end        
        
        indEgde     = find(imEdgeThr);
        [x,y]       = meshgrid(1:ncols,1:nrows);
        
        set(fig,'CurrentAxes',axh);
        hold on;
        imEdgeH = quiver(x(indEgde),y(indEgde),imTransH(indEgde),imTransV(indEgde),1,'g');
        hold off;
       
        
    end % show_ImageEdges

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% compute sound algorithm parameters from the image
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function compute_SoundAmpFromWindow(varargin)

        sndAmp = sndAmpDefault;
       % check the valid window
        if strcmp(get(rectH,'Visible'),'off'), return; end;
        
        % get edge information
        indEgde     = find(imEdgeThr(winUD(1):winUD(2),winLR(1):winLR(2)));
        if isempty(indEgde), sndAmp = sndAmp*0; return; end;
            
        imTransVtmp = imTransV(winUD(1):winUD(2),winLR(1):winLR(2));
        imTransHtmp = imTransH(winUD(1):winUD(2),winLR(1):winLR(2));
        
        angleEdge   = atan2(imTransVtmp(indEgde),imTransHtmp(indEgde));
        angleHist   = hist(angleEdge,angleBins);
        sndAmp      = angleHist(:)/sum(angleHist);     
       
        fprintf(' %3d',round(sndAmp*100)); fprintf('\n');
        
    end % compute_SoundAmpFromWindow

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% select sound algorithm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function select_SoundAlgorithm(varargin)

        % set all the features off
        set(get(smh,'Children'),'Checked','off');
        
        if strcmp(get(gcbo, 'Checked'),'on')
            set(gcbo, 'Checked', 'off');
            sndAlgorithm    = 1;   % default sound algorithm
        else 
            set(gcbo, 'Checked', 'on');
            sndAlgorithm    = varargin{3};   % selected sound algorithm
       end        
        
    end % select_SoundAlgorithm

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check sound of  your system
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     function check_Sound(varargin) 
        if ~exist('handel.mat','file'),
            warndlg('It is possible that your Matlab does not contain audiovideo toolbox. Can not play sounds.')
        end;
        wavplay(y,Fs,'async');
        warndlg('You must hear sound now. If you dont - check your sound system.');
     end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% play sound in your system
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     function test_SoundGen(varargin) 

%        sndData         = int8(128*sin(sndTime*sndFreq)*sndAmp.*sndWindow);
%        sound(double(sndData)/128,Fs,8);
%         sndData             = int8(128*sin(sndTime*sndFreq)*sndAmp);
        sndData               = sin(sndTime*sndFreq)*sndAmp;
        
        %if isplaying(aph),
        %    stop(aph)
        %end;

         %if ~isplaying(aph),
%             aph                 = audioplayer(sndData,Fs,8);
%          	%playblocking(aph); 
%          	play(aph); 
         %end;
         
%         % daq
%         if isrunning(ao), stop(ao); end;
%          
%          % could have stereo effect 
%         data = [sndData sndData];
%         putdata(ao, data);
%         start(ao);

        wavplay(sndData,Fs,'sync');
         
     end
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Main callback - combine move with sound
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    function play_sounds(varargin)
        % determine if the cursor is over the panel
        
        % check the image
        if isempty(imTrans), return; end;
        
        cp   = get(axh,'CurrentPoint');
        px   = round(cp(1,1));
        py   = round(cp(1,2));

        % if insight rectangle - highlight
        if winHalfLen < px && px < ncols - winHalfLen &&...
           winHalfLen < py && py < nrows - winHalfLen,
            set(rectH,'xdata',px+winX,'ydata',py + winY,'Visible','on');
            winLR           = [px-winHalfLen px+winHalfLen]; % defines region coordinates
            winUD           = [py-winHalfLen py+winHalfLen];
        else
            set(rectH,'Visible','off');
            winLR           = [1 1]; % defines region coordinates
            winUD           = [1 1];
        end;
        
        %winInd              = 
        
        % call amp vector
        compute_SoundAmpFromWindow();       
        
        % call sound gen function
        test_SoundGen() ;       
        %clock
        
    end % play_sounds
 
 
end % all the functions

% [EOF] 

Contact us