Image 如何在Matlab中获得图像中n条曲线的长度?
目前,我一直致力于获取曲线的长度,通过下面的代码,我成功地获取了图像中存在的曲线的长度 然后我粘贴了用于获取简单图像曲线长度的代码。我所做的是:Image 如何在Matlab中获得图像中n条曲线的长度?,image,matlab,curves,Image,Matlab,Curves,目前,我一直致力于获取曲线的长度,通过下面的代码,我成功地获取了图像中存在的曲线的长度 然后我粘贴了用于获取简单图像曲线长度的代码。我所做的是: 我得到了图像的列和行 我得到了x中的列和y中的行 根据公式,我得到了曲线的系数 寓言 建立方程式 执行弧长公式以获得曲线的长度 grayImage = imread(fullFileName); [rows, columns, numberOfColorBands] = size(grayImage); if numberOfColorBands &
grayImage = imread(fullFileName);
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
grayImage = grayImage(:, :, 2); % Take green channel.
end
subplot(2, 2, 1);
imshow(grayImage, []);
% Get the rows (y) and columns (x).
[rows, columns] = find(binaryImage);
coefficients = polyfit(columns, rows, 2); % Gets coefficients of the formula.
% Fit a curve to 500 points in the range that x has.
fittedX = linspace(min(columns), max(columns), 500);
% Now get the y values.
fittedY = polyval(coefficients, fittedX);
% Plot the fitting:
subplot(2,2,3:4);
plot(fittedX, fittedY, 'b-', 'linewidth', 4);
grid on;
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
% Overlay the original points in red.
hold on;
plot(columns, rows, 'r+', 'LineWidth', 2, 'MarkerSize', 10)
formula = poly2sym([coefficients(1),coefficients(2),coefficients(3)]);
% formulaD = vpa(formula)
df=diff(formula);
df = df^2;
f= (sqrt(1+df));
i = int(f,min(columns),max(columns));
j = double(i);
disp(j);
我认为你应该浏览图片,询问是否有一个“1”,如果是,询问以下内容,从而确定曲线的起点,获得长度并将其保存在BD中,我对代码不是很在行,但这是我的想法我尝试了这篇文章,但我不太了解,但想法123听起来很棒,这篇关于GUI的帖子我建议您看看Hough转换: 您将需要图像处理工具箱。否则,你必须发展自己的逻辑 更新1 我花了两个小时思考你的问题,我只能提取第一条曲线。问题是定位曲线的起点。无论如何,这是我提出的代码,希望能给你一些进一步开发的想法
clc;clear;close all;
grayImage = imread('2.png');
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
grayImage = grayImage(:, :, 2); % Take green channel.
end
% find edge.
bw = edge(grayImage,'canny');
imshow(bw);
[x, y] = find(bw == 1);
P = [x,y];
% For each point, find a point that is of distance 1 or sqrt(2) to it, i.e.
% find its connectivity.
cP = cell(1,length(x));
for i = 1:length(x)
px = x(i);
py = y(i);
dx = x - px*ones(size(x));
dy = y - py*ones(size(y));
distances = (dx.^2 + dy.^2).^0.5;
cP{i} = [x(distances == 1), y(distances == 1);
x(distances == sqrt(2)), y(distances == sqrt(2))];
end
% pick the first point and a second point that is connected to it.
fP = P(1,:);
Q(1,:) = fP;
Q(2,:) = cP{1}(1,:);
m = 2;
while true
% take the previous point from point set Q, when current point is
% Q(m,1)
pP = Q(m-1,:);
% find the index of the current point in point set P.
i = find(P(:,1) == Q(m,1) & P(:,2) == Q(m,2));
% Find the distances from the previous points to all points connected
% to the current point.
dx = cP{i}(:,1) - pP(1)*ones(length(cP{i}),1);
dy = cP{i}(:,2) - pP(2)*ones(length(cP{i}),1);
distances = (dx.^2 + dy.^2).^0.5;
% Take the farthest point as the next point.
m = m+1;
p_cache = cP{i}(find(distances==max(distances),1),:);
% Calculate the distance of this point to the first point.
distance = ((p_cache(1) - fP(1))^2 + (p_cache(2) - fP(2))^2).^0.5;
if distance == 0 || distance == 1
break;
else
Q(m,:) = p_cache;
end
end
% By now we should have built the ordered point set Q for the first curve.
% However, there is a significant weakness and this weakness prevents us to
% build the second curve.
更新2 自上次更新以来,还有一些工作要做。我现在可以分开每条曲线了。我在这里看到的唯一问题是要有一个好的曲线拟合。我建议使用B样条曲线或贝塞尔曲线,而不是多项式拟合。我想我就到此为止,剩下的事情就交给你去解决了。希望这有帮助 请注意,以下脚本使用图像处理工具箱查找曲线的边
clc;clear;close all;
grayImage = imread('2.png');
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
grayImage = grayImage(:, :, 2); % Take green channel.
end
% find edge.
bw = edge(grayImage,'canny');
imshow(bw);
[x, y] = find(bw == 1);
P = [x,y];
% For each point, find a point that is of distance 1 or sqrt(2) to it, i.e.
% find its connectivity.
cP =[0,0]; % add a place holder
for i = 1:length(x)
px = x(i);
py = y(i);
dx = x - px*ones(size(x));
dy = y - py*ones(size(y));
distances = (dx.^2 + dy.^2).^0.5;
c = [find(distances == 1); find(distances == sqrt(2))];
cP(end+1:end+length(c),:) = [ones(length(c),1)*i, c];
end
cP (1,:) = [];% remove the place holder
% remove duplicates
cP = unique(sort(cP,2),'rows');
% seperating curves
Q{1} = cP(1,:);
for i = 2:length(cP)
cp = cP(i,:);
% search for points in cp in Q.
for j = 1:length(Q)
check = ismember(cp,Q{j});
if ~any(check) && j == length(Q) % if neither has been saved in Q
Q{end+1} = cp;
break;
elseif sum(check) == 2 % if both points cp has been saved in Q
break;
elseif sum(check) == 1 % if only one of the points exists in Q, add the one missing.
Q{j} = [Q{j}, cp(~check)];
break;
end
end
% review sets in Q, merge the ones having common points
for j = 1:length(Q)-1
q = Q{j};
for m = j+1:length(Q)
check = ismember(q,Q{m});
if sum(check)>=1 % if there are common points
Q{m} = [Q{m}, q(~check)]; % merge
Q{j} = []; % delete the merged set
break;
end
end
end
Q = Q(~cellfun('isempty',Q)); % remove empty cells;
end
% each cell in Q represents a curve. Note that points are not ordered.
figure;hold on;axis equal;grid on;
for i = 1:length(Q)
x_ = x(Q{i});
y_ = y(Q{i});
coefficients = polyfit(y_, x_, 3); % Gets coefficients of the formula.
% Fit a curve to 500 points in the range that x has.
fittedX = linspace(min(y_), max(y_), 500);
% Now get the y values.
fittedY = polyval(coefficients, fittedX);
plot(fittedX, fittedY, 'b-', 'linewidth', 4);
% Overlay the original points in red.
plot(y_, x_, 'r.', 'LineWidth', 2, 'MarkerSize', 1)
formula = poly2sym([coefficients(1),coefficients(2),coefficients(3)]);
% formulaD = vpa(formula)
df=diff(formula);
lengthOfCurve(i) = double(int((sqrt(1+df^2)),min(y_),max(y_)));
end
结果:
您可以使用估算每个区域(即弧)的周长,然后将其除以2,得到弧长的良好近似值。以下是您将如何做到这一点(需要): 下面是这张图: 作为一种健全性检查,我们可以使用一个简单的测试图像来查看它给我们提供的近似值有多好:
testImage = zeros(100); % 100-by-100 image
testImage(5:95, 5) = 1; % Add a vertical line, 91 pixels long
testImage(5, 10:90) = 1; % Add a horizontal line, 81 pixels long
testImage(2020:101:6060) = 1; % Add a diagonal line 41-by-41 pixels
testImage = logical(imdilate(testImage, strel('disk', 1))); % Thicken lines slightly
在该图像上运行上述代码,我们得到以下结果:
正如你所看到的,水平线和垂直线的长度与我们期望的接近,对角线比
sqrt(2)*41稍大一点,这是因为扩张步骤稍微延长了它的长度。我需要得到这张图中所有曲线的函数,因为我得到了长度,我没有使用Hough变换好的,我错了。Hough变换只帮助查找线性边。我有一些想法,但有一个大问题。在第二幅图像中,曲线的厚度不是1像素。这是我们必须处理的还是曲线通常为1像素厚?有时厚度会有所不同,但一般来说,它将在像素的最小范围内。我读到了关于hough变换的文章,我非常清楚,细节是如果我能得到曲线方程,如果我得到方程式,我会用直线读到,但我有曲线给了你同样的东西,除了阅读参考书目,我还要检查你的更新,看看是否有办法用霍夫变换来做,如果你可以得到我的代码,当Hough已经给你大部分的时候,我的代码是多余的。我的主要问题是,我不应该使用任何GUI或工具箱,如果我设法获得一些进展,我将把它发布在这里与你分享我的知识,我正在检查你的工作,谢谢:)
testImage = zeros(100); % 100-by-100 image
testImage(5:95, 5) = 1; % Add a vertical line, 91 pixels long
testImage(5, 10:90) = 1; % Add a horizontal line, 81 pixels long
testImage(2020:101:6060) = 1; % Add a diagonal line 41-by-41 pixels
testImage = logical(imdilate(testImage, strel('disk', 1))); % Thicken lines slightly