You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Detect the shape in MATLAB
6 views (last 30 days)
Show older comments
Hello, I hope you are doing well.
I have the image of 1000x1000.I have attached the image below I want to detect the number of lines in the image and pixel value of each line. How can i do it in MATLAB
as you can see in image, there is four lines, is Hough transform work on this or any image processing.
For example line is at 720, then it show pixel value 720
2 Comments
Med Future
on 16 Mar 2022
Yes line are Parallel. Then how can i detect?
Accepted Answer
Image Analyst
on 15 Mar 2022
% Make the image binary, if it's not already.
binaryImage = grayImage > 128;
% Count the lines.
[LabeledImage, numLines] = bwlabel(binaryImage);
18 Comments
Med Future
on 16 Mar 2022
@Image Analyst Now the image is in uint8 form.
I also want The pixel value for the image. How can i find that?
Image Analyst
on 16 Mar 2022
You can get the intensity for each blob (line) individually using regionprops():
props = regionprops(labeledImage, grayImage, 'MeanIntensity');
meanIntensities = [props.MeanIntensity]
The "pixel value for the image" is the image variable itself, but you haven't really explained what that means. You can get the pixel value anywhere just by giving the row and column, like
grayLevel = grayImage(row, col);
where you assign some numerical value to row and col.
If you want the MEAN pixel value for the whole image, use mean2()
meanValue = mean2(grayImage);
Med Future
on 16 Mar 2022
@Image Analyst pixel value means where is 255 exist for example in this image 255 present in 577,392 and 686
so i want that value
Image Analyst
on 16 Mar 2022
OK, here is a full demo. Tell me if this is what you want:
% 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 = 22;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image_2732.png';
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
rgbImage = 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(rgbImage)
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 blue channel.
grayImage = rgbImage(:, :, 3);
else
grayImage = rgbImage;
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 1, 1);
imshow(grayImage);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Binarize the image to get a mask.
mask = grayImage >= 128;
% Display mask image.
subplot(2, 1, 2);
imshow(mask);
hold on;
impixelinfo;
axis('on', 'image');
drawnow;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Get a labeled image and count of the number of distinct regions.
[labeledImage, numRegions] = bwlabel(mask);
caption = sprintf('Binary Image with %d lines', numRegions);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Get all the blob properties. Can only pass in originalImage in version R2008a and later.
props = regionprops(labeledImage, 'Area', 'Centroid');
allLengths = [props.Area]
centroids = vertcat(props.Centroid);
% Put a thick red line wherever there is a line. This is because on the figure the lines are so thin they're not visible.
hold on;
for k = 1 : numRegions
x1 = centroids(k, 1) - allLengths(k)/2;
if x1 < 1
x1 = 1;
elseif x1 > columns
x1 = columns;
end
y1 = centroids(k, 2);
x2 = centroids(k, 1) + allLengths(k)/2;
if x2 < 1
x2 = 1;
elseif x2 > columns
x2 = columns;
end
y2 = y1; % Assumes perfectly horizontal lines.
plot([x1,x2], [y1,y2], 'r-', 'LineWidth', 4);
xt = props(k).Centroid(1);
yt = props(k).Centroid(2);
str = sprintf('Length = %d at line %d', allLengths(k), y1);
text(xt, yt, str, 'Color', 'r', 'FontWeight', 'bold', 'HorizontalAlignment', 'Center', 'VerticalAlignment','bottom', 'FontSize',15);
end
hold off;
% Tell the user
message = sprintf('Done!\n');
uiwait(helpdlg(message))
Med Future
on 19 Mar 2022
@Image Analyst Thanks for you answer, Can you please modified the code that if two lines are on same value they should be count as 1 for example in above picture same value e.g line 577 are two times, they should be count as one line
Image Analyst
on 19 Mar 2022
@Med Future you just need to use unique(). This will throw out duplicate line numbers. Add these lines to the end of my code (also attached as testGrayImage.m):
% Get the row number the white lines are on
whiteLineRows1 = centroids(:, 2)
% Some of the lines are separated but are on the same line.
% The poster wants any on the same line to be considered as they are on the same line.
% To do that use unique.
whiteLineRows2 = unique(whiteLineRows1)
You'll see
whiteLineRows1 =
577
686
392
577
whiteLineRows2 =
392
577
686
I think simple thresholding is simpler than using a hough transform.
By the way, the code also works for your second image.
Med Future
on 19 Mar 2022
@Image Analyst Thanks for you answer. I have the following two image i want to detect there minimum and maximum value
for example sinewave ,i want it maximoum value and minimum value same like above you done for line. should i post another question for this?
Image Analyst
on 19 Mar 2022
Yes, probably. There could be qualifications depending on exactly what you want but you could use
[r, c] = find(binaryImage);
topLine = min(r);
If not, then start a new question. Like maybe the line is actually thicker than a single pixel wide curve, and you want the top line and bottom line for each and every column in the image, or some variation of that.
Med Future
on 19 Mar 2022
@Image Analyst Did the above algo work on this image i have attached below?
also please explain the algo you are done above
Image Analyst
on 19 Mar 2022
Yes it works with that image. It will find hundreds of separate lines because your lines are broken up into many, many separate segments, each with their own endpoints. However extracting the y values and using unique() will get you just the line numbers that they're on even though they're all broken up.
Here is what you get:
whiteLineRows2 =
104
108
224
407
867
Code is attached.
Med Future
on 19 Mar 2022
because they are the lines i want
Med Future
on 19 Mar 2022
@Image Analyst i want to plot only unique lines How can i do that?
Image Analyst
on 19 Mar 2022
Then don't plot individual ones in the loop and call yline() after the loop. Solution attached.
% Put a thick red line wherever there is a line. This is because on the figure the lines are so thin they're not visible.
hold on;
for k = 1 : numRegions
x1 = centroids(k, 1) - allLengths(k)/2;
if x1 < 1
x1 = 1;
elseif x1 > columns
x1 = columns;
end
y1 = centroids(k, 2);
x2 = centroids(k, 1) + allLengths(k)/2;
if x2 < 1
x2 = 1;
elseif x2 > columns
x2 = columns;
end
y2 = y1; % Assumes perfectly horizontal lines.
% plot([x1,x2], [y1,y2], 'r-', 'LineWidth', 4);
% xt = props(k).Centroid(1);
% yt = props(k).Centroid(2);
% str = sprintf('Length = %d at line %d', allLengths(k), y1);
% text(xt, yt, str, 'Color', 'r', 'FontWeight', 'bold', 'HorizontalAlignment', 'Center', 'VerticalAlignment','bottom', 'FontSize',15);
end
hold off;
% Get the row number the white lines are on
whiteLineRows1 = centroids(:, 2)
% Some of the lines are separated but are on the same line.
% The poster wants any on the same line to be considered as they are on the same line.
% To do that use unique.
whiteLineRows2 = unique(whiteLineRows1)
hold on;
yline(whiteLineRows2, 'LineWidth', 2, 'Color', 'r');
Med Future
on 20 Mar 2022
@Image Analyst Okay let me check it
Med Future
on 21 Mar 2022
@Image Analyst when i run the above code
- testGrayImage.m The command
- yline(whiteLineRows2, 'LineWidth', 2, 'Color', 'r');
plot straight line on Y axis it will be good in case of this im_001008.png . but when this image_2732.png same straight line occurs but in this case small lines should be plot.
Image Analyst
on 21 Mar 2022
I don't know what that means. It plots a line all the way across - that is how yline() works. You said that line segments on the same line should be considered one line even if they have a gap. If you don't want the line drawn all the way across, you can use plot() or line() to plot line segments.
Med Future
on 25 Mar 2022
@Image Analyst Thanks for your answer , Like in first image i have half lines and in second image i have full lines , i just want this algo to be that if half line comes it detect half lines and plot y axis half lines as you shared above, if full lines image comes it draw full lines image. the rest of the things are fine.
Image Analyst
on 25 Mar 2022
I've given it to you both ways. First I found line segments, with the starting and ending points, then you said you wanted "only unique lines" so if two blobs were on the same line/row, I used unique() to get only unique lines. So if two blobs were on the same row, I'd draw only one line across the whole row. So now you have it both ways. Does that not solve the problem?
More Answers (1)
yanqi liu
on 16 Mar 2022
img = imread('https://ww2.mathworks.cn/matlabcentral/answers/uploaded_files/928244/image_2732.png');
bw = im2bw(img);
% 霍夫分析
[H,T,R] = hough(bw);
P = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
lines = houghlines(bw,T,R,P,'FillGap',5,'MinLength',7);
max_len = 0;
line_r = [];
figure; imshow(img, []); hold on;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','cyan');
p = [];
xy = round(xy);
for j = min(xy(:,1)) : max(xy(:,1))
p = [p img(xy(1,2), j)];
end
text(xy(1,1),xy(1,2)-15, sprintf('pixel value = %.2f', mean(p)), 'color', 'r');
end
9 Comments
Med Future
on 16 Mar 2022
@yanqi liu Thanks for your answer, but the pixel value you show is 255
and there should be three lines because the the small line at the end of right side is the replication of 577
I want the value where 255 have present for example in this image 255 present in 577,392 and 686
Med Future
on 16 Mar 2022
Edited: Med Future
on 16 Mar 2022
@yanqi liu in lines structure i see the value and start and end value of line ( points1 and points2)
can you please check and print pixel value for that?
Med Future
on 16 Mar 2022
@yanqi liu I have attached the image the two lines are not detected. only three are detected
Image Analyst
on 16 Mar 2022
Attach the actual image that you read in, not a screen capture of the final output.
Med Future
on 19 Mar 2022
@yanqi liu i have attached the image below
Image Analyst
on 19 Mar 2022
It should. It will find hundreds of separate lines because your lines are broken up into many, many separate segments, each with their own endpoints. However extracting the y values and using unique() will get you just the line numbers that they're on even though they're all broken up.
Med Future
on 19 Mar 2022
@Image Analyst dont understand you answer.
Image Analyst
on 19 Mar 2022
Sorry - I put it in the wrong place. it was meant to be a reply to your comment to me
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)