Boundaries in an image

Hi,
I have to trace the boundaries in the image (attached original image).
I have to trace only one boundary as indicated in the image.
I tried this for only one image, how can I do this for number of images?
Waiting for a kind response.
Regards
Tayyaba
grayImage = imread('0002.tif');
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
grayImage = rgb2gray(grayImage);
end
% Display the image.
subplot(2, 3, 1);
imshow(grayImage, []);
title('Original Grayscale Image');
impixelinfo;
% Crop image
% grayImage = imcrop(grayImage);
Img = imcrop(grayImage,[670 60 800 500]);
% Update size.
[rows, columns, numberOfColorChannels] = size(Img);
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image
mask = Img < 22; %imbinarize(grayImage);
% Display the mask.
subplot(2, 3, 4);
imshow(mask, []);
impixelinfo;
title('Initial Binary Image');
impixelinfo;
% Fill interior holes.
mask = imfill(mask, 'holes');
% Get rid of particles smaller than 10000 in size
mask = bwareaopen(mask,10000);
subplot(2, 3, 5);
imshow(mask, []);
impixelinfo;
title('Final Binary Image');
impixelinfo;
% Get boundaries
boundaries = bwboundaries(mask);
subplot(2, 3, 6);
imshow(grayImage); % Show cropped image again.
hold on;
for k = 1 : length(boundaries)
thisBoundary = boundaries{k};
x = thisBoundary(:, 2);
y = thisBoundary(:, 1);
plot(x, y, 'r-', 'LineWidth', 2);
end
%Specifing limits to get rid of the outer boundary
xlim([5 500]);
ylim([5 500]);
title('Image With Boundaries');

Answers (2)

Aakash
Aakash on 15 Jun 2023
Moved: Image Analyst on 15 Jun 2023

0 votes

By number of images I'm assuming you want to repeat this on multiple images, so put all the images in a seperate folder and read from it using a for loop.
You can try out this code:
path=dir(your_image_folder_path);//as string
n=length(path);
for i=3:n
str=path(i).name;
[p ,fname]=fileparts(str);
str=[your_image_folder_path,str];
im=imread(str);
// your code as shown above
Image Analyst
Image Analyst on 15 Jun 2023

0 votes

See the FAQ to get code snippets for processing a sequence of files:

8 Comments

By the way, your algorithm is not good. Attach the image if you want me to fix it.
Thanks, I am attaching the image again.
Please let me know how to proceed correctly.
Regards
Tayyaba
Try this. But you have horrendously bad JPG artifacts in your image that are preventing us from getting a good image. I STRONGLY recommend you save the image in a lossless format such as PNG, TIFF, or BMP.
% Demo by Image Analyst
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;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN TEST IMAGE
folder = pwd;
baseFileName = 'Tayyaba.jpeg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
% 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.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the max channel.
% grayImage = max(grayImage, [], 3);
% Extract the green channel.
grayImage = grayImage(:, :, 2);
end
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
g.NumberTitle = 'off';
g.Name = 'Demo by Image Analyst'
drawnow;
% Erase white line at top.
grayImage(1:60, :) = 0;
%--------------------------------------------------------------------------------------------------------
% Threshold to create mask of the dark spot.
lowThreshold = 20;
highThreshold = 255;
% 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;
% mask = grayImage > 22; % From Tayyaba.
% Fill holes.
mask = imfill(mask, 'holes');
% Check the areas of the initial mask
props = regionprops(mask, 'Area');
allAreas = sort([props.Area])
% Take largest blob only.
mask = bwareafilt(mask, 1);
subplot(2, 2, 2);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get the areas and center of the final square blobs.
props = regionprops(mask, grayImage, 'Area', 'Centroid', 'MeanIntensity');
allAreas = sort([props.Area])
meanBlobGrayLevels = [props.MeanIntensity];
subplot(2, 2, 3);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get boundary of region and plot it over original image.
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(mask);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k}; % Get boundary for this specific blob.
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
hold off;
caption = sprintf('Mean Area = %.1f pixels with a threshold of %d.', mean(allAreas), highThreshold);
fontSize = 15;
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
Thank you very much for your kind reply.
It works :)
Still I have to run the code over number of images and also to get the variation of boundary with time.Therefore I input images with 'K' as file names and at the end I defined time based on the images and plot boundary verses time. But it gives me an error:
Error using plot
Invalid data argument.
Error in Bend_test (line 83)
plot(time, boundaries(1,:),'-+');
Is there anything missing with this ?
code is attached.
Regards
Tayyaba
clear all;
clc;
close all;
workspace;
format long g;
format compact;
fontSize = 18;
markerSize = 40;
all_files = dir('Y:\SF\images\*.tif');
numfiles = length(all_files);
for k = 1: numfiles
fileName = strcat('Y:\SF\images\',all_files(k).name);
grayImage = imread(fileName);
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
% 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.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the max channel.
% grayImage = max(grayImage, [], 3);
% Extract the green channel.
grayImage = grayImage(:, :, 2);
end
% Erase white line at top.
grayImage(1:60, :) = 0;
%--------------------------------------------------------------------------------------------------------
% Threshold to create mask of the dark spot.
lowThreshold = 20;
highThreshold = 255;
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Fill holes.
mask = imfill(mask, 'holes');
% Check the areas of the initial mask
props = regionprops(mask, 'Area');
allAreas = sort([props.Area])
% Take largest blob only.
mask = bwareafilt(mask, 1);
subplot(2, 2, 2);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get the areas and center of the final square blobs.
props = regionprops(mask, grayImage, 'Area', 'Centroid', 'MeanIntensity');
allAreas = sort([props.Area])
meanBlobGrayLevels = [props.MeanIntensity];
subplot(2, 2, 3);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get boundary of region and plot it over original image.
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(mask);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for n = 1 : numberOfBoundaries
thisBoundary = boundaries{n}; % Get boundary for this specific blob.
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
end
hold on
time = 0:1/k:1-1/k;
plot(time, boundaries(1,:),'-+');
hold off;
caption = sprintf('Mean Area = %.1f pixels with a threshold of %d.', mean(allAreas), highThreshold);
fontSize = 15;
title(caption, 'FontSize', fontSize);
axis('on', 'image');
hold on
I have the resulting edge in pixel, can I write a code to convert it into millimetres according to my scale? And also if I need to calculate the standard deviation of the mean image (out of 500 images for example) how can I do this by using the same code of edge detection? Thanks Tayyaba
@Tayyaba Bano first get the mean image. Then use std.
To process a sequence of images, see the code snippet in the FAQ: Process a sequence of files
To get the mean image, see attached example. It's a general purpose one for averaging RGB images of different sizes, but I think it should work also with gray scale images, or if all the images are the same size. I just made it very robust to handle all possible situations.
Thank you very much for your kind reply,
initially I imported number of images for example 500 and get a single image with bounadries out of those 500 images. Is this also an avereaged imaged? because i did not divide it by nr of images to take average.
Regards
Tayyaba
You did not describe the operations you did when you "get a single image with bounadries out of those 500 images", so how could I know what you did? Why are you talking about boundaries now when before you were only talking about averaging images?
If you want the average shape of objects, then see my attached demo that finds the average shape.

Sign in to comment.

Categories

Asked:

on 15 Jun 2023

Commented:

on 26 Jun 2024

Community Treasure Hunt

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

Start Hunting!