How to remove frame appear as a result of thresholding
Show older comments
When I use file exchange https://www.mathworks.com/matlabcentral/fileexchange/12191-bilateral-filtering
it is working well but when I take the result as input to to get threshold the result appear with outerframe as shown in attachment
how can I remove this frame or not allowed it to appear?
Answers (2)
Your image has a white border that you need to trim out.
bb1 = imread('bb1.jpg');
imshow(bb1); title('original');
set(gca, 'visible', 'on')
is_all_white = all(bb1 == 255, 3);
vert_profile = ~all(is_all_white, 1);
horz_profile = ~all(is_all_white, 2);
first_col = find(vert_profile, 1);
last_col = find(vert_profile, 1, 'last');
first_row = find(horz_profile, 1);
last_row = find(horz_profile, 1, 'last');
bb1_cropped = bb1(first_row:last_row, first_col:last_col, :);
imshow(bb1_cropped); title('cropped');
set(gca, 'visible', 'on');
4 Comments
yasmin ismail
on 11 Jul 2023
There's still a white border because the image is a JPG. The edge transitions are not white or uniform, so you have to be more aggressive to cut off as much as the artifacts as you can.
bb1 = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1431283/bb1.jpg');
is_all_white = all(bb1 > 200, 3);
vert_profile = ~all(is_all_white, 1);
horz_profile = ~all(is_all_white, 2);
first_col = find(vert_profile, 1);
last_col = find(vert_profile, 1, 'last');
first_row = find(horz_profile, 1);
last_row = find(horz_profile, 1, 'last');
bb1_cropped = bb1(first_row:last_row, first_col:last_col, :);
imshow(bb1_cropped)
Does the cropped image have any remaining light remnants of the padding? Yes. JPG ruins hard edges. Is the cropped image the same size as the original photo? Very unlikely. It's probably scaled by some unknown amount, because it's a screenshot.
yasmin ismail
on 30 Jul 2023
DGM
on 30 Jul 2023
Note that there are two separate issues. The primary problem is that the image is at some point being padded by capturing a screenshot. The padding will create false edges no matter what image format is used. The use of JPG simply degrades the image further, making it slightly more problematic to crop the result.
Given the inconsistent and nonstandard geometry of both the padded and base images in these samples, that's by far the most likely reason they've appear this way.
If you save an image by displaying it and then taking a screenshot with saveas(), print(), etc, the result will not reliably be the same size as the original, and it will contain an unpredictable amount of white padding. In other words, a screenshot is not a faithful copy of the image stored in memory. Save the image directly using imwrite().
Image Analyst
on 27 Jul 2023
0 votes
Avoid the white frame altogether by using imwrite to save the image, rather than saveas or print or whatever other function you're using.
17 Comments
yasmin ismail
on 30 Jul 2023
Edited: yasmin ismail
on 30 Jul 2023
Image Analyst
on 30 Jul 2023
You can just use the varaible still in memory. You do not HAVE to save it out to a disk file. If you want to save other variables to a .mat file, you can do so with the save() function, though it's not necessary unless you're recalling those variables from a completely different program. Otherwise in your same program. just use the variables by passing them to other functions via the argument list.
yasmin ismail
on 30 Jul 2023
Image Analyst
on 30 Jul 2023
Like this
rgbImage = imread(filename);
imshow(rgbImage);
% Now process it immediately and directly.
% There is absolutely no need to save rgbImage or
% the figure window (screenshot) to disk before using it again.
outputImage = AnalyzeSingleImage(rgbImage);
% Now do something with this next image, like display it.
% There is absolutely no need to save rgbImage or the figure window (screenshot) to disk before using it again.
imshow(outputImage);
msgbox('done');
% Define some function that does something.
function outputImage = AnalyzeSingleImage(rgbImage)
outputImage = rgbImage - 50;
Notice that nowhere in that code did I use saveas(), print(), imwrite() to save any images to disk. I just used the variables because they were already in memory.
yasmin ismail
on 31 Jul 2023
Edited: Image Analyst
on 31 Jul 2023
yasmin ismail
on 31 Jul 2023
Image Analyst
on 31 Jul 2023
Edited: Image Analyst
on 31 Jul 2023
@yasmin ismail you didn't define your segmentation function AnalyzeSingleImage, so of course it throws an error. Do you want to just do simple thresholding like you do later in your script? Anyway, I'm not sure what is the name of the variable that you (incorrectly) think that you must save for use later?
[EDIT] Here, I did my best to try to interpret what you've done and improve it. One thing is strange though -- your original image is pretty much binary already. Did you already segment it somehow? Or did you attach the wrong image. Anyway, again, no saving of the variable to a disk file was needed or performed so not sure why you think you need to.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
filename = 'c1-1fsr.png';
rgbImage = imread(filename);
subplot(1, 2, 1);
imshow(rgbImage);
% Now it's gray scale with range of 0 to 255.
impixelinfo; % Let user mouse around and see values in the status line at the lower right.
title('Original Input Image', 'FontSize', fontSize);
% Now segment the image.
% Strange though -- it seems to be binary (i.e. segmented) already
% or the image is way over exposed.
outputImage = AnalyzeSingleImage(rgbImage);
% Display output image.
subplot(1, 2, 2);
imshow(outputImage); % Result of process 1
title('Output Mask Image', 'FontSize', fontSize);
msgbox('done');
%===============================================================================
% Now your segmentation app - simple global thresholding.
function mask = AnalyzeSingleImage(grayImage)
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
% grayImage = rgb2gray(outputImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
grayImage = grayImage(:, :, 3); % Take Blue channel.
else
grayImage = grayImage; % It's already gray scale.
end
% Binarize the image.
% mask = imbinarize(grayImage);
lowThreshold = 0;
highThreshold = 220;
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, grayImage);
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
end

yasmin ismail
on 1 Aug 2023
Edited: yasmin ismail
on 1 Aug 2023
Look, I'll run it right here in the Answers edit box:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
filename = 'c1-1fsr.png';
rgbImage = imread(filename);
subplot(1, 2, 1);
imshow(rgbImage);
% Now it's gray scale with range of 0 to 255.
impixelinfo; % Let user mouse around and see values in the status line at the lower right.
title('Original Input Image', 'FontSize', fontSize);
% Now segment the image.
% Strange though -- it seems to be binary (i.e. segmented) already
% or the image is way over exposed.
outputImage = AnalyzeSingleImage(rgbImage);
% Display output image.
subplot(1, 2, 2);
imshow(outputImage); % Result of process 1
title('Output Mask Image', 'FontSize', fontSize);
msgbox('done');
%===============================================================================
% Now your segmentation app - simple global thresholding.
function mask = AnalyzeSingleImage(grayImage)
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
% grayImage = rgb2gray(outputImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
grayImage = grayImage(:, :, 3); % Take Blue channel.
else
grayImage = grayImage; % It's already gray scale.
end
% Binarize the image.
% mask = imbinarize(grayImage);
lowThreshold = 0;
highThreshold = 220;
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, grayImage);
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
end
See it runs. I'm not sure what you mean when you say that the input argument variable is not existing before this call (line of code):
outputImage = AnalyzeSingleImage(rgbImage);
rgbImage certainly does exist. I think you must not have had much coding experience where you call functions or subroutines or methods. The name of the variables in the main, calling program can be totally different than the names you use in the function definition line. This is a very fundamental concept in programming that you need to learn. So the AnalyzeSingleImage calls the input argument grayImage and uses it, converting it to gray scale in the case where it's not, like in this case where it's an RGB image. That's perfectly fine and normal. The main program also calls the output of the function "outputImage" while in the function itself it's called "mask". Again, perfectly normal. I think you need to review the introductory training material about how to pass data to functions and get output back from those functions. You will learn that you can call the variables completely independent names in the main calling routine and the function. When you think about it it makes sense, because functions are written as a utility that could be called by any number of routines later, unknown to the function author. And those programs have their own names for the variables. It is not required for them to make copies of their variables with their preferred names to have the same name as the function. That would be VERY inconvenient and that is why it's not required. Though you CAN use the same name if you want to because the names are completely independent.
yasmin ismail
on 1 Aug 2023
Edited: yasmin ismail
on 1 Aug 2023
Image Analyst
on 1 Aug 2023
The code you posted does not call AnalyzeSingleImage at all so it can't throw that error.
And the program that DID throw that error, recall_mat.m, you forgot to attach, thus delaying a solution once more.
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:
PLEASE read the above so we don't waste anymore time.
yasmin ismail
on 1 Aug 2023
Image Analyst
on 1 Aug 2023
See in my code where at the end of AnalyzeSingleImage it has this:
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
end
The end is important. Whenever you have a function in a script, the function must come AFTER the script and must end with an "end". You can't do what you tried, and that is to continue on with the script after the function has been defined. You did
% Fill holes.
mask = imfill(mask, 'holes');
subplot(2, 3, 2);
and so on. No, you can't do that because then it would be like AnalyzeSingleImage is inserted into the middle of your script rather than at the end. That's not allowed. All functions must follow all script lines, not be placed in the middle of your script.
yasmin ismail
on 2 Aug 2023
Image Analyst
on 2 Aug 2023
If you use a function like AnalyzeSingleImage, it MUST be defined AFTER all your script functions, or else be in a separate AnalyzeSingleImage.m m-file. So from this:
function mask = AnalyzeSingleImage(grayImage)
all the way down to the final
end % of the AnalyzeSingleImage function definition
of the function must ALL be at the very end of your script.
You can still CALL the function above its definition, anywhere and as many times as you want in your script. It just has to be DEFINED at the bottom.
yasmin ismail
on 2 Aug 2023
Image Analyst
on 3 Aug 2023
You need to also define fontSize inside AnalyzeSingleImage(). Since it was not passed in via the argument list, the function has no idea what that is, so you need to assign it to some value, like you did in the main program.
Categories
Find more on Explore and Edit Images with Image Viewer App in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



