Gabor Filter demo
A GUI to interact with the 5 different Gabor filter parameters, while visualizing the resulting filter.
function varargout = gabor_filter_gui(ksize) % create the UI if nargin < 1, ksize = [121 121]; end h = buildGUI(ksize); if nargout > 0, varargout{1} = h; end end function onChange(~,~,h) %ONCHANGE Event handler for UI controls % retrieve current values from UI controls sigma = get(h.slid(5), 'Value') / 10; theta = get(h.slid(4), 'Value') * pi/180; lambda = get(h.slid(3), 'Value'); gamma = get(h.slid(2), 'Value') / 100; psi = get(h.slid(1), 'Value') * pi/180; % create Gabor filter kernel = cv.getGaborKernel('KSize',[h.ksize(2) h.ksize(1)], ... 'Sigma',sigma, 'Theta',theta, 'Lambda',lambda, ... 'Gamma',gamma, 'Psi',psi); % normalize filter to [0,1] range and resize it kernel = cv.normalize(kernel, 'NormType','MinMax'); kernel = cv.resize(kernel, [h.sz(2) h.sz(1)]); % show result set(h.img, 'CData',kernel) set(h.txt(5), 'String',sprintf('Sigma = %.2f',sigma)) set(h.txt(4), 'String',sprintf('Theta = %.2f',theta)) set(h.txt(3), 'String',sprintf('Lambda = %.2f',lambda)) set(h.txt(2), 'String',sprintf('Gamma = %.2f',gamma)) set(h.txt(1), 'String',sprintf('Psi = %.2f',psi)) drawnow end function onType(~,e,h) %ONTYPE Event handler for key press on figure % handle keys switch e.Key case {'q', 'escape'} close(h.fig) return case 'h' onHelp([],[]); case 'r' onReset([],[],h); end end function onReset(~,~,h) set(h.slid(5), 'Value',400); % sigma set(h.slid(4), 'Value',0); % theta set(h.slid(3), 'Value',11); % lambda set(h.slid(2), 'Value',100); % gamma set(h.slid(1), 'Value',90); % psi onChange([],[],h); end function onHelp(~,~) %ONHELP Display usage help dialog helpdlg({ 'This GUI allows to interact with the 5 different Gabor filter' 'parameters, while visualizing the resulting filter.' '' 'Hot keys:' 'ESC, q - quit the program' 'r - reset parameters to original values' 'h - this help dialog' }); end function h = buildGUI(ksize) %BUILDGUI Creates the UI % parameters sigma = 400; sigma_max = 1000; theta = 0; theta_max = 180; lambda = 11; lambda_max = 100; gamma = 100; gamma_max = 200; psi = 90; psi_max = 180; sz = [512 512]; % build the user interface (no resizing to keep it simple) h = struct(); h.ksize = ksize; % size of the filter h.sz = sz; % size of the image to show h.fig = figure('Name','Gabor Filter Demo', ... 'NumberTitle','off', 'Menubar','none', 'Resize','off', ... 'Position',[200 200 sz(2) sz(1)+129]); if ~mexopencv.isOctave() %HACK: not implemented in Octave movegui(h.fig, 'center'); end h.ax = axes('Parent',h.fig, 'Units','pixels', 'Position',[1 130 sz(2) sz(1)]); if ~mexopencv.isOctave() h.img = imshow(zeros(sz), 'Parent',h.ax); else %HACK: https://savannah.gnu.org/bugs/index.php?45473 axes(h.ax); h.img = imshow(zeros(sz)); end text(5, 5, sprintf('KSize = %dx%d', ksize(2), ksize(1)), ... 'Color','y', 'VerticalAlignment','top'); props = {'Parent',h.fig, 'Style','text', 'String','', ... 'FontSize',11, 'HorizontalAlignment','left'}; h.txt(5) = uicontrol(props{:}, 'Position',[5 5 120 20]); h.txt(4) = uicontrol(props{:}, 'Position',[5 30 120 20]); h.txt(3) = uicontrol(props{:}, 'Position',[5 55 120 20]); h.txt(2) = uicontrol(props{:}, 'Position',[5 80 120 20]); h.txt(1) = uicontrol(props{:}, 'Position',[5 105 120 20]); props = {'Parent',h.fig, 'Style','slider', 'Min',0}; h.slid(5) = uicontrol(props{:}, 'Position',[125 5 sz(2)-125-5 20], ... 'Value',sigma, 'Max',sigma_max, 'SliderStep',[10 100]./(sigma_max-0)); h.slid(4) = uicontrol(props{:}, 'Position',[125 30 sz(2)-125-5 20], ... 'Value',theta, 'Max',theta_max, 'SliderStep',[2 20]./(theta_max-0)); h.slid(3) = uicontrol(props{:}, 'Position',[125 55 sz(2)-125-5 20], ... 'Value',lambda, 'Max',lambda_max, 'SliderStep',[1 10]./(lambda_max-0)); h.slid(2) = uicontrol(props{:}, 'Position',[125 80 sz(2)-125-5 20], ... 'Value',gamma, 'Max',gamma_max, 'SliderStep',[2 20]./(gamma_max-0)); h.slid(1) = uicontrol(props{:}, 'Position',[125 105 sz(2)-125-5 20], ... 'Value',psi, 'Max',psi_max, 'SliderStep',[2 20]./(psi_max-0)); % hook event handlers, and trigger default start opts = {'Interruptible','off', 'BusyAction','cancel'}; set(h.slid, 'Callback',{@onChange,h}, opts{:}); set(h.fig, 'WindowKeyPressFcn',{@onType,h}, opts{:}); onChange([],[],h); end