How to callback same function for changes in multiple uiobjects?

4 次查看(过去 30 天)
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.

回答(1 个)

Jaimin
Jaimin 2024-9-16
编辑:Jaimin 2024-9-16
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.

产品


版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by