getting coordinates from a picture

Hi! I have an image that I would like to get the coordinates from. Its a 2D image. I need to perform some operation with the image. I need to get the coordinates of some points I choose and get them saved. I am aware of the data cursor, but since I have a huge number of points, manual operation will be of no way.
lets say, I have this basic structure of a thermal fin. I need say 1000 points from its boundary.Is there any way in matlab, I can import the image, and save the coordinates of the boundary, distributed evenly over.
I hope my question is clear.
thanks in advance!!

 Accepted Answer

Image Analyst
Image Analyst on 2 Oct 2014
Edited: Image Analyst on 16 Jul 2019
Well, you could use image analysis:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 36;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
return;
end
end
%===============================================================================
% Read in a standard MATLAB color demo image.
folder = 'C:\Users\aaditya\Documents\Temporary';
baseFileName = 'part1.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows, columns, numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 2, 1);
imshow(rgbImage);
axis on;
title('Original Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'Outerposition', [0, 0, 1, 1]);
% Extract the individual red, green, and blue color channels.
% redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
% blueChannel = rgbImage(:, :, 3);
% Get the binaryImage
binaryImage = greenChannel < 200;
% Display the original color image.
subplot(2, 2, 2);
imshow(binaryImage);
axis on;
title('Binary Image', 'FontSize', fontSize);
% Find the baseline
verticalProfile = sum(binaryImage, 2);
lastLine = find(verticalProfile, 1, 'last')
% Scan across columns finding where the top of the hump is
for col = 1 : columns
yy = lastLine - find(binaryImage(:, col), 1, 'first');
if isempty(yy)
y(col) = 0;
else
y(col) = yy;
end
end
subplot(2, 2, 3);
plot(1 : columns, y, 'b-', 'LineWidth', 3);
grid on;
title('Y vs. X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
Of course you'll get better results if you use a PNG image rather than that crummy JPG which has all kinds of bad compression artifacts.

15 Comments

WOW !! that was awesome !! thanks a ton! I require this for my project and you just made my life a whole lot easier!! Hats off!! have a great day!
thank you so much !!! i guess it will help me alot in my project. Cheers !!!
yeshis, you're welcome. Be sure to see all the other nice things in my File Exchange, especially the Image Segmentation Tutorial.
Thank you so much..!! Please can you tell me how to extract and save the coordinates of the boundary for this image...!! .
The values are [1 : columns, y] for [x, y].
Or you can call bwboundaries()
boundaries = bwboundaries(binaryImage);
Sir .! Please can you place the "boundaries = bwboundaries(binaryImage)" in the above code.. I am unable to place it
Just place it at the very end of the code. Why do you want the boundary of that binary image anyway? Please check out my image segmentation tutorial in my File Exchange where I do outlining of blobs.
wick
wick on 18 Jul 2019
Edited: wick on 18 Jul 2019
Sir..Actually I want to extract data points (X values and Y values), along with this type of image boundries (like curve graphs) automatically, without manually selecting points. I couldn't find any code or resource to do this task automatically.can you please help me ?
I thought I did. I gave you code, plus gave you a link to a full blown, extremely well commented example in my File Exchange. Did you even TRY either of the code samples?
Again, if you have your binary image, just do
boundaries = bwboundaries(binaryImage);
to get a list of (x,y) coordinates without having to manually specify any starting point. I guess I don't understand why you're not getting it. If you still need help, then post your code (so far) and your image, and I'll do it for you in a few seconds.
wick
wick on 20 Jul 2019
Edited: wick on 20 Jul 2019
Sir I want this kind of output for my project.I want to extract X and Y values along with the curve boundry and save it as a separate excel sheet . I want to get those values automatically without clicking on the curve boundy. Sir I tried what you have said and I placed the "boundaries = bwboundaries(binaryImage);" code at the very end and it didnt work.I want to do this for any kind of curve graphs.I attached the image related to the above picture. Sir please give me a solution..
Sir at the end of the code (the code you have given) I placed those coded lines and I tried to save the output as a separate file, But it won't work.
% Display the original color image.
subplot(2, 2, 2);
imshow(binaryImage);
axis on;
title('Binary Image', 'FontSize', fontSize);
% Find the baseline
verticalProfile = sum(binaryImage, 2);
lastLine = find(verticalProfile, 1, 'last')
% Scan across columns finding where the top of the hump is
for col = 1 : columns
yy = lastLine - find(binaryImage(:, col), 1, 'first');
if isempty(yy)
y(col) = 0;
else
y(col) = yy;
end
end
subplot(2, 2, 3);
plot(1 : columns, y, 'b-', 'LineWidth', 3);
grid on;
title('Y vs. X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
boundaries = bwboundaries(binaryImage);
xlswrite([fullFileName '_raw.xls'],boundaries,'Sheet1','A1');
I'm not really sure what you want or why my code can't be adapted to what you want. So I've done it two ways for you.
  1. One finds only the y value (line number) of the top of the hump, along with the x value (column) where it occurs. These are stored in xTop and yTop and are shown in blue in the lower left.
  2. The other method finds the coordinates of the complete outline of the hemispherical blob, and those are stored in xOutline and yOutline and drawn in red over the binary image in the lower right.
Hopefully one of them is what you want. Note: nowhere in my code am I asking the user or the programmer to specify any point on any image. If this doesn't answer your question, improve your question and plot it as a new question.
0000 Screenshot.png
Hello,Thanks for your code,but i have a question about this,when i run this the .xls file doesn't any data, i don't how to solve it.
Image Analyst, could you post the method 2 that you mentioned previously?
2. The other method finds the coordinates of the complete outline of the hemispherical blob, and those are stored in xOutline and yOutline and drawn in red over the binary image in the lower right.
Xavier, I'm not sure what happened to the code. Either I forgot to attach it or one of the other moderators accidentally deleted the attachment. So I had to recreate it, but it was very simple. Here it is:
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 = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'curve.png';
% Get the full filename, with path prepended.
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);
% 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(grayImage);
% 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(:, :, 2); % Take green channel.
end
% Display the image.
subplot(2, 2, 1);
imshow(grayImage);
axis('on', 'image');
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get a mask that is the entire image.
% mask = true(size(grayImage));
% Alternative : get a mask that is the thresholded part of the image.
threshold = 195;
binaryImage = grayImage ~= threshold;
subplot(2, 2, 2);
imshow(binaryImage, []);
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
% Find the top boundary
yTop = zeros(1, columns);
for col = 1 : columns
top = find(binaryImage(:, col), 1, 'first');
if ~isempty(top)
yTop(col) = top;
end
end
subplot(2, 2, 3);
x = 1 : columns;
plot(x, yTop, 'b-', 'LineWidth', 3);
grid on;
title('Y vs. X', 'FontSize', fontSize);
xlabel('Xtop', 'FontSize', fontSize);
ylabel('Ytop', 'FontSize', fontSize);
% 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.
subplot(2, 2, 4);
imshow(grayImage); % Optional : show the original image again. Or you can leave the binary image showing if you want.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(binaryImage);
% 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 x.
plot(x, y, 'r-', 'LineWidth', 3); % Plot boundary in red.
end
hold off;
title('Binary Image with Full Boundary', 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
@Erkan Karaoglu, let's not start a new discussion in @aaditya's 7 year old thread. Please start your own thread and attach the original grayscale thermal images rather than the pseudocolored ones. Also take the picture with the scene perpendicular to the optic axis, not an an oblique angle (bad for a number of reasons).

Sign in to comment.

More Answers (1)

Venkatkumar Muneeswaran
Venkatkumar Muneeswaran on 15 Jun 2023
Edited: Venkatkumar Muneeswaran on 15 Jun 2023
Could you pleae let me know how do i get the data from this plot?

3 Comments

As of now I am using Similar to that, but Is ther any otherway without picking the points in the image and directly recognize the line/dashed line plot in the image?
Image Analyst
Image Analyst on 15 Jun 2023
Edited: Image Analyst on 15 Jun 2023
Yes, but it will be complicated. Probably too complicated for you to program up. You'd have to segment the image to find the curved line, and the axes (box) then find the limits of the axes to spatially calibrate it. Not super trivial. Why don't you just use imfreehand to trace the curve? Demo attached.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!