How to fitline on my binary image and find distance
10 ビュー (過去 30 日間)
古いコメントを表示
Hello,
I have a question about my image processing problem. I have convert the image into binary and now i would like to use fitline on my image. Basically want to smooth the line with the curve. I am a beginner for MATLAB software. Please help me to find the solution. Also i want to find distance of one thin line to thick line (top to bottom).
I am attachng my picture as png. Also my code is there.
0 件のコメント
採用された回答
Image Analyst
2020 年 6 月 27 日
Your question is very unclear and ambiguous. Like, exactly what does "want to find distance of one thin line to thick line (top to bottom)" mean??? Where are thin lines and where are the thick lines in your image?
Here is another guess at what you might mean. I just find the topmost and bottommost white pixel in the image for each column, and compute the distance (height) between them:
% 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;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image.jpeg';
% 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
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image
binaryImage = imbinarize(grayImage);
% Get rid of big white frame around the border of the image.
binaryImage = imclearborder(binaryImage);
subplot(2, 2, 2);
imshow(binaryImage, []);
impixelinfo;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
% Scan image finding the distance from topmost white pixel to bottommost.
topRows = nan(1, columns);
bottomRows = nan(1, columns);
for col = 1 : columns
thisColumn = binaryImage(:, col);
t = find(thisColumn, 1, 'first');
if ~isempty(t)
topRows(col) = t;
bottomRows(col) = find(thisColumn, 1, 'last');
end
end
% Plot top rows and bottom rows.
subplot(2, 2, 3);
x = 1 : columns;
plot(x, topRows, 'b-', 'LineWidth', 2);
grid on;
hold on;
plot(x, bottomRows, 'r-', 'LineWidth', 2);
title('Top and Bottom Rows', 'FontSize', fontSize);
xlabel('Column', 'FontSize', fontSize);
ylabel('Row', 'FontSize', fontSize);
legend('Top Rows', 'Bottom Rows');
% Plot heights.
heights = bottomRows - topRows;
subplot(2, 2, 4);
x = 1 : columns;
plot(x, heights, 'b-', 'LineWidth', 2);
grid on;
title('Heights', 'FontSize', fontSize);
xlabel('Column', 'FontSize', fontSize);
ylabel('Height in Rows', 'FontSize', fontSize);
0 件のコメント
その他の回答 (3 件)
Image Analyst
2020 年 6 月 27 日
Did you try polyfit() to fit a line to the pixels?
% 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;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image.jpeg';
% 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
subplot(2, 1, 1);
imshow(grayImage, []);
impixelinfo;
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image
binaryImage = imbinarize(grayImage);
% Get rid of big white frame around the border of the image.
binaryImage = imclearborder(binaryImage);
subplot(2, 1, 2);
imshow(binaryImage, []);
impixelinfo;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
% Get all coordinates
[y, x] = find(binaryImage);
% Fit a line through them
coefficients = polyfit(x, y, 1)
% Get a fitted line
xFit = 1 : columns;
yFit = polyval(coefficients, xFit);
% Plot the line in red over the image.
hold on;
plot(xFit, yFit, 'r-', 'LineWidth', 2);
% Put the equation up
txt = sprintf('y = (%f) * x + (%f)', coefficients(1), coefficients(2));
text(100, 200, txt, 'Color', 'r', 'FontSize', 15, 'FontWeight', 'bold');
19 件のコメント
Image Analyst
2020 年 7 月 16 日
Try scanning column by column. If there are exactly two regions, go from the top or center of the first region to the top of the second region. Or you could just measure the height of the black gap between them. It just depends on what your definition of distance is.
clc; % Clear the command window.
fprintf('Beginning to run %s.m ...\n', mfilename);
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing
fontSize = 15;
mask = imread('image.bmp');
mask = mask(:, :, 1) > 0;
hFig = figure;
subplot(2, 1, 1);
imshow(mask);
hold on;
hFig.WindowState = 'maximized';
[rows, columns] = size(mask)
distances = zeros(1, columns);
distances2 = zeros(1, columns);
for col = 1 : columns
thisColumn = mask(:, col);
props = regionprops(thisColumn, 'Centroid', 'PixelList');
if length(props) == 2
% Only two regions which is what we need.
% Get the center of the thick top line.
yCentroid = props(1).Centroid(2);
yTop = props(1).PixelList(1,2);
% Get the top of the bottom region.
yTop2 = props(2).PixelList(1,2);
distances(col) = abs(yTop2 - yCentroid);
distances2(col) = abs(yTop2 - yTop);
line([col, col], [yTop, yTop2], 'Color', 'r');
end
end
subplot(2, 1, 2);
plot(distances, 'b-', 'LineWidth', 2);
hold on;
plot(distances2, 'r-', 'LineWidth', 2);
xlim([1, columns]);
grid on;
xlabel('Column', 'FontSize', fontSize);
ylabel('Distance', 'FontSize', fontSize);
legend('Distance from Centroid', 'Distance between tops');
Prashant
2020 年 7 月 16 日
編集済み: Prashant
2020 年 7 月 16 日
1 件のコメント
Image Analyst
2020 年 7 月 16 日
You need to clear that border with imclearborder. My code looks for exactly 2 regions but if you have that white border all around, then the columns with the two regions are not the places you want. They'll be the placed with no blob and just the places with the white frame. Why is there a white frame around your image anyway?
Prashant
2020 年 7 月 16 日
39 件のコメント
Image Analyst
2020 年 10 月 1 日
I'd sum the inverted image vertically to get the horizontal profile, and then look for peaks.
horizontalProfile = sum(255 - grayImage);
plot(horizontalProfile, 'b-', 'LineWidth', 2);
grid on;
[peakValues, peakLocations] = findpeaks(horizontalProfile);
plot(peakLocations, peakValues, 'rv', 'MarkerSize', 15, 'LineWidth', 2);
参考
カテゴリ
Help Center および File Exchange で Computer Vision with Simulink についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!