如何通过白色像素找到两个连接点之间的距离?
How to find distance between two connected points through white pixels?
我想找到曲线的两个端点。
我使用凸包找到 8 boundary-points 然后对于每个点,计算与所有其他点的距离。具有最大距离的点被假定为端点。它适用于大多数形状简单的情况,如下所示:
我正在使用这段代码找到两点:
% Calculate 8-boundary points using Convex Hull
% (points consists of all white pixels for the curve)
out=convhull(points);
extremes=points(out,:);
% Finding two farthest points among above boundary points
arr_size = size(extremes);
max_distance = 0;
endpoints = [extremes(1,:); extremes(2,:)];
for i=1:arr_size(1)
p1 = extremes(i,:);
for j=i+1:arr_size(1)
p2 = extremes(j,:);
dist = sqrt((p2(1)-p1(1))^2 + (p2(2)-p1(2))^2);
if dist>max_distance
max_distance = dist;
endpoints = [p1; p2];
end
end
end
disp(endpoints);
在大多数情况下它都有效,但是当它应用于 U-typed 形状时就会出现问题。
我想找出两点之间的白色像素数。我跟着这个
但它在只有直线而不是曲线的情况下有帮助。任何帮助表示赞赏!
编辑 1:
我已经根据@Rotem 的回答更新了我的代码,它解决了我的问题。
更新代码:
for i=1:arr_size(1)
p1 = extremes(i,:);
distanceMap = calculate_distance_map(arr, p1);
for j=i+1:arr_size(1)
p2 = extremes(j,:);
dist = distanceMap(p2(2), p2(1));
if dist>max_distance
max_distance = dist;
endpoints = [p1; p2];
end
end
end
但是这需要花费很多时间。关于如何减少计算时间有什么建议吗?
我找到了一个受 dynamic programming 算法启发的解决方案。
解释在评论中:
function n_points = BlueDotsDist()
I = imread('BlueDots.png');
%Fix the image uploaded to the site - each dot will be a pixel.
I = imresize(imclose(I, ones(3)), 1/6, 'nearest');
%Convert each color channel to a bynary image:
R = imbinarize(I(:,:,1));G = imbinarize(I(:,:,2));B = imbinarize(I(:,:,3));
%figure;imshow(cat(3, double(R), double(G), double(B)));impixelinfo
%Find blue dost:
[blue_y, blue_x] = find((B == 1) & (R == 0));
%Compute distance map from first blue point
P = CalcDistMap(R, blue_y(1), blue_x(1));
%Compute distance map from second blue point
Q = CalcDistMap(R, blue_y(2), blue_x(2));
%Get 3x3 pixels around second blue point.
A = P(blue_y(2)-1:blue_y(2)+1, blue_x(2)-1:blue_x(2)+1);
dist_p = min(A(:)); %Minimum value is the shortest distance from first point (but not the number of white points).
T = max(P, Q); %Each element of T is maximum distance from both points.
T(T > dist_p) = 10000; %Remove points that are more far than dist_p.
%Return number of white points between blue points.
n_points = sum(T(:) < 10000);
function P = CalcDistMap(R, blue_y, blue_x)
%Each white pixel in R gets the distance from the blue dot in coordinate (blue_x, blue_y).
%Initialize array with values of 10000 (high value - marks infinite distance).
P = zeros(size(R)) + 10000; %P - distance from blue dot
P(blue_y, blue_x) = 0; %Distance from itself.
prvPsum = 0;
while (sum(P(:) < 10000) ~= prvPsum)
prvPsum = sum(P(:) < 10000); %Sum of "marked" dots.
for y = 2:size(R, 1)-1
for x = 2:size(R, 2)-1
p = P(y, x);
if (p < 10000) %If P(y,x) is "marked"
A = P(y-1:y+1, x-1:x+1); %3x3 neighbors.
A = min(A, p+1); %Distance is the minimum of current distance, and distance from p pixel + 1.
A(R(y-1:y+1, x-1:x+1) == 0) = 10000; %Ignore black pixels.
A(P(y-1:y+1, x-1:x+1) == 0) = 0; %Restore 0 in blue point.
P(y-1:y+1, x-1:x+1) = A; %Update distance map.
end
end
end
end
距离图说明(10000 替换为零):
P(与第一个蓝点的距离):
Q(与第二个蓝点的距离):
最大(P,Q):
T:
我想找到曲线的两个端点。
我使用凸包找到 8 boundary-points 然后对于每个点,计算与所有其他点的距离。具有最大距离的点被假定为端点。它适用于大多数形状简单的情况,如下所示:
我正在使用这段代码找到两点:
% Calculate 8-boundary points using Convex Hull
% (points consists of all white pixels for the curve)
out=convhull(points);
extremes=points(out,:);
% Finding two farthest points among above boundary points
arr_size = size(extremes);
max_distance = 0;
endpoints = [extremes(1,:); extremes(2,:)];
for i=1:arr_size(1)
p1 = extremes(i,:);
for j=i+1:arr_size(1)
p2 = extremes(j,:);
dist = sqrt((p2(1)-p1(1))^2 + (p2(2)-p1(2))^2);
if dist>max_distance
max_distance = dist;
endpoints = [p1; p2];
end
end
end
disp(endpoints);
在大多数情况下它都有效,但是当它应用于 U-typed 形状时就会出现问题。
我想找出两点之间的白色像素数。我跟着这个
编辑 1:
我已经根据@Rotem 的回答更新了我的代码,它解决了我的问题。
更新代码:
for i=1:arr_size(1)
p1 = extremes(i,:);
distanceMap = calculate_distance_map(arr, p1);
for j=i+1:arr_size(1)
p2 = extremes(j,:);
dist = distanceMap(p2(2), p2(1));
if dist>max_distance
max_distance = dist;
endpoints = [p1; p2];
end
end
end
但是这需要花费很多时间。关于如何减少计算时间有什么建议吗?
我找到了一个受 dynamic programming 算法启发的解决方案。
解释在评论中:
function n_points = BlueDotsDist()
I = imread('BlueDots.png');
%Fix the image uploaded to the site - each dot will be a pixel.
I = imresize(imclose(I, ones(3)), 1/6, 'nearest');
%Convert each color channel to a bynary image:
R = imbinarize(I(:,:,1));G = imbinarize(I(:,:,2));B = imbinarize(I(:,:,3));
%figure;imshow(cat(3, double(R), double(G), double(B)));impixelinfo
%Find blue dost:
[blue_y, blue_x] = find((B == 1) & (R == 0));
%Compute distance map from first blue point
P = CalcDistMap(R, blue_y(1), blue_x(1));
%Compute distance map from second blue point
Q = CalcDistMap(R, blue_y(2), blue_x(2));
%Get 3x3 pixels around second blue point.
A = P(blue_y(2)-1:blue_y(2)+1, blue_x(2)-1:blue_x(2)+1);
dist_p = min(A(:)); %Minimum value is the shortest distance from first point (but not the number of white points).
T = max(P, Q); %Each element of T is maximum distance from both points.
T(T > dist_p) = 10000; %Remove points that are more far than dist_p.
%Return number of white points between blue points.
n_points = sum(T(:) < 10000);
function P = CalcDistMap(R, blue_y, blue_x)
%Each white pixel in R gets the distance from the blue dot in coordinate (blue_x, blue_y).
%Initialize array with values of 10000 (high value - marks infinite distance).
P = zeros(size(R)) + 10000; %P - distance from blue dot
P(blue_y, blue_x) = 0; %Distance from itself.
prvPsum = 0;
while (sum(P(:) < 10000) ~= prvPsum)
prvPsum = sum(P(:) < 10000); %Sum of "marked" dots.
for y = 2:size(R, 1)-1
for x = 2:size(R, 2)-1
p = P(y, x);
if (p < 10000) %If P(y,x) is "marked"
A = P(y-1:y+1, x-1:x+1); %3x3 neighbors.
A = min(A, p+1); %Distance is the minimum of current distance, and distance from p pixel + 1.
A(R(y-1:y+1, x-1:x+1) == 0) = 10000; %Ignore black pixels.
A(P(y-1:y+1, x-1:x+1) == 0) = 0; %Restore 0 in blue point.
P(y-1:y+1, x-1:x+1) = A; %Update distance map.
end
end
end
end
距离图说明(10000 替换为零):
P(与第一个蓝点的距离):
Q(与第二个蓝点的距离):
最大(P,Q):
T: