How to callback same function for changes in multiple uiobjects?

4 views (last 30 days)
I am creating a uifigure-based app programatically for de-noising the noisy images. The code for which is as follows:
function filteredImage
fig = uifigure;
g = uigridlayout(fig,[3 2]);
g.RowHeight = {30,30,'1x'};
g.ColumnSpacing = 10;
filterLabel = uilabel(g,"Text","Filter Type","WordWrap","on","FontSize",18,"FontWeight","bold");
filterLabel.Layout.Row = 1;
filterLabel.Layout.Column = 1;
% Choose type of filter to be displayed
filterType = uidropdown(g,"Editable","on","Position",[0 50 20 10],"FontSize",18);
filterType.Layout.Row = 1;
filterType.Layout.Column = 2;
filterType.Items = ["Arithmetic Mean Filter",
"Geometric Mean Filter",
"Weighted Average Filter"];
kernelDimlabel = uilabel("Parent",g,"Text","Kernel Dimensions","FontSize",18,"FontWeight","bold");
kernelDimlabel.Layout.Row = 2;
kernelDimlabel.Layout.Column = 1;
% Set the kernel size (since it is a square matrix, #rows = #columns)
kernelDim = uispinner("Parent",g,"Step",2,"Value",3,"Limits",[3 11],"FontSize",18);
kernelDim.Layout.Row = 2;
kernelDim.Layout.Column = 2;
% Noisy image displayed
im1 = uiimage(g,"ImageSource","poutsalt & pepper.png");
im1.Layout.Row = 3;
im1.Layout.Column = 1;
% Filtered image displayed
im2 = uiimage(g);
im2.Layout.Row = 3;
im2.Layout.Column = 2;
% Here, filterImage updates im2 whenever the value of filterType changes
filterType.ValueChangedFcn = @(src,event)filterImage(src,event,im1,im2,filterType,kernelDim);
% I want to update im2 when either the value of filterType changes OR when
% kernelDim changes
end
function filterImage(src,event,im1,im2,filterType,kernelDim)
kDim = kernelDim.Value;
I = imread(im1.ImageSource);
I_name = erase(im1.ImageSource,".png");
incr = floor(kDim/2);
im1_padded = double(padarray(I,[incr incr],0,'both'));
[r,c] = size(I);
switch filterType.Value
case "Arithmetic Mean Filter"
kernel = double(ones(kDim));
for i=1:r
for j=1:c
I_filtered(i+incr,j+incr) = (1/(kDim*kDim))*sum(sum(kernel.*im1_padded(i:i+kDim-1,j:j+kDim-1)));
end
end
ext = "_amf"+"_"+ string(kDim) + ".png";
case "Geometric Mean Filter"
kernel = double(ones(kDim));
for i=1:r
for j=1:c
I_filtered(i+incr,j+incr) = prod(prod(kernel.*im1_padded(i:i+kDim-1,j:j+kDim-1))).^(1/(kDim*kDim));
end
end
ext = "_gmf"+"_"+ string(kDim) + ".png";
case "Weighted Average Filter"
if kDim == 3
kernel = (1/16)*[1 2 1;
2 4 2;
1 2 1];
else
kernel = (1/52)*[1 1 2 1 1;
1 2 4 2 1;
2 4 8 4 2;
1 2 4 2 1;
1 1 2 1 1];
end
for i=1:r
for j=1:c
I_filtered(i+incr,j+incr) = sum(sum(kernel.*im1_padded(i:i+kDim-1,j:j+kDim-1)));
end
end
ext = "_waf"+"_"+ string(kDim) + ".png";
end
I_filtered = uint8(I_filtered);
filteredImagePath = strcat(I_name,ext);
imwrite(I_filtered,filteredImagePath);
im2.ImageSource = filteredImagePath;
end
As of now I am getting the filtered image output. Initially there's no image in im2. But it appears only after I change the kernelDim followed by filterType. One obvious way is to explicitly write the code for initial values, but I want the function filterImage to somehow do it.
Please suggest techniques to do the same in an efficient manner.

Answers (1)

Jaimin
Jaimin on 16 Sep 2024
Edited: Jaimin on 16 Sep 2024
The“filterImage”function can be utilized for initialization of “im2” with some minor modifications to the code.
I have attached the code here for better understanding.
function filteredImage
fig = uifigure;
g = uigridlayout(fig,[3 2]);
g.RowHeight = {30,30,'1x'};
g.ColumnSpacing = 10;
filterLabel = uilabel(g,"Text","Filter Type","WordWrap","on","FontSize",18,"FontWeight","bold");
filterLabel.Layout.Row = 1;
filterLabel.Layout.Column = 1;
% Choose type of filter to be displayed
filterType = uidropdown(g,"Editable","on","Position",[0 50 20 10],"FontSize",18);
filterType.Layout.Row = 1;
filterType.Layout.Column = 2;
filterType.Items = ["Arithmetic Mean Filter",
"Geometric Mean Filter",
"Weighted Average Filter"];
kernelDimlabel = uilabel("Parent",g,"Text","Kernel Dimensions","FontSize",18,"FontWeight","bold");
kernelDimlabel.Layout.Row = 2;
kernelDimlabel.Layout.Column = 1;
% Set the kernel size (since it is a square matrix, #rows = #columns)
kernelDim = uispinner("Parent",g,"Step",2,"Value",3,"Limits",[3 11],"FontSize",18);
kernelDim.Layout.Row = 2;
kernelDim.Layout.Column = 2;
% Noisy image displayed
im1 = uiimage(g,"ImageSource","poutsalt & pepper.png");
im1.Layout.Row = 3;
im1.Layout.Column = 1;
% Filtered image displayed
im2 = uiimage(g);
im2.Layout.Row = 3;
im2.Layout.Column = 2;
% Define the function to update the filtered image
updateFilteredImage = @(src,event)filterImage(src,event,im1,im2,filterType,kernelDim);
% Assign ValueChangedFcn to both filterType and kernelDim
filterType.ValueChangedFcn = updateFilteredImage;
kernelDim.ValueChangedFcn = updateFilteredImage;
% Call filterImage initially to display the image with default values
filterImage([],[],im1,im2,filterType,kernelDim);
end
function filterImage(~,~,im1,im2,filterType,kernelDim)
kDim = kernelDim.Value;
I = imread(im1.ImageSource);
I_name = erase(im1.ImageSource,".png");
incr = floor(kDim/2);
im1_padded = double(padarray(I,[incr incr],0,'both'));
[r,c] = size(I);
switch filterType.Value
case "Arithmetic Mean Filter"
kernel = double(ones(kDim));
for i=1:r
for j=1:c
I_filtered(i+incr,j+incr) = (1/(kDim*kDim))*sum(sum(kernel.*im1_padded(i:i+kDim-1,j:j+kDim-1)));
end
end
ext = "_amf"+"_"+ string(kDim) + ".png";
case "Geometric Mean Filter"
kernel = double(ones(kDim));
for i=1:r
for j=1:c
I_filtered(i+incr,j+incr) = prod(prod(kernel.*im1_padded(i:i+kDim-1,j:j+kDim-1))).^(1/(kDim*kDim));
end
end
ext = "_gmf"+"_"+ string(kDim) + ".png";
case "Weighted Average Filter"
if kDim == 3
kernel = (1/16)*[1 2 1;
2 4 2;
1 2 1];
else
kernel = (1/52)*[1 1 2 1 1;
1 2 4 2 1;
2 4 8 4 2;
1 2 4 2 1;
1 1 2 1 1];
end
for i=1:r
for j=1:c
I_filtered(i+incr,j+incr) = sum(sum(kernel.*im1_padded(i:i+kDim-1,j:j+kDim-1)));
end
end
ext = "_waf"+"_"+ string(kDim) + ".png";
end
I_filtered = uint8(I_filtered);
filteredImagePath = strcat(I_name,ext);
imwrite(I_filtered,filteredImagePath);
im2.ImageSource = filteredImagePath;
end
I hope this will be helpful.

Categories

Find more on MATLAB in Help Center and File Exchange

Products


Release

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!