Detect the shape in MATLAB
5 次查看(过去 30 天)
显示 更早的评论
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 个评论
Jan
2022-3-15
Are the lines parallel to the X axis in all cases? Then there are much cheaper methods than a Hough transformation.
采纳的回答
Image Analyst
2022-3-15
% Make the image binary, if it's not already.
binaryImage = grayImage > 128;
% Count the lines.
[LabeledImage, numLines] = bwlabel(binaryImage);
18 个评论
Med Future
2022-3-16
@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
2022-3-16
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
2022-3-16
@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
2022-3-16
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
2022-3-19
@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
2022-3-19
@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
2022-3-19
@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
2022-3-19
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
2022-3-19
@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
2022-3-19
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.
Image Analyst
2022-3-19
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
2022-3-21
@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
2022-3-21
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
2022-3-25
@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
2022-3-25
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?
更多回答(1 个)
yanqi liu
2022-3-16
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 个评论
Med Future
2022-3-16
@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
2022-3-16
编辑:Med Future
2022-3-16
@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
2022-3-16
@yanqi liu I have attached the image the two lines are not detected. only three are detected
Image Analyst
2022-3-16
Attach the actual image that you read in, not a screen capture of the final output.
yanqi liu
2022-3-17
yes,sir,may be upload your real image,or modify parameter,such as
P = houghpeaks(H,3,'threshold',ceil(0.1*max(H(:))));
lines = houghlines(bw,T,R,P,'FillGap',5,'MinLength',3);
Image Analyst
2022-3-19
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.
Image Analyst
2022-3-19
Sorry - I put it in the wrong place. it was meant to be a reply to your comment to me
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- 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)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)