我正在尝试创建自己的voronoi图。我有一个由x和y坐标定义的任意形状,存储在不同的向量中。在这个形状内部是一些感兴趣的点(具有已知的坐标),它们属于两个不同的组并且充当voronoi图的种子。作为示例,整个图的范围从x = -10到x = 90并且y = -20到y = 60。边界形状不是矩形,而是在上面的轴范围内。
到目前为止,我所做的是创建一个3D矩阵(100 X 80 X 3),C,所有的矩阵,以便默认颜色为白色。然后我从i = 1:100,j = 1:80循环,测试单个像素,看它们是否使用inpolygon落在形状内。如果他们这样做,我会找出哪个点最近的像素,并根据最近的点是属于组1还是2来为其指定颜色。
到目前为止一切都很好。然后我使用imagesc显示具有自定义轴范围的图像。问题是voronoi图具有一般形状,但由于像素坐标与实际世界坐标不同,因此在位置方面不合适。
我尝试使用imref2d映射它,但我不知道它是如何工作的,或者在使用imref2d后如何显示图像。请帮帮我。
我也对其他方法持开放态度!
谢谢!
编辑: 根据要求,让我给出一个更详细的例子和解释我的问题。
让我们假设一个简单的钻石形状边界,其中包含以下向量和4个点,其中包含以下坐标向量:
%Boundary vectors
Boundary_X = [-5 40 85 40 -5];
Boundary_Y = [20 50 20 -10 20];
%Point vectors
Group_One_X = [20 30];
Group_One_Y = [10 40];
Group_Two_X = [50 70];
Group_Two_Y = [5 20];
接下来,我绘制了所有这些,不同的组具有不同的颜色。
%Plot boundary and points
hold on
plot(Boundary_X,Boundary_Y)
scatter(Group_One_X,Group_One_Y,10,'MarkerFaceColor','Black',...
'MarkerEdgeColor','Black')
scatter(Group_Two_X,Group_Two_Y,10,'MarkerFaceColor','Red',...
'MarkerEdgeColor','Red')
hold off
axis([-10, 90, -20, 60])
这是结果: Boundary with points
接下来,我逐个像素地测试整个图形区域,并将它们染成青色或黄色,具体取决于它们是否更接近第1组或第2组。
%Create pixel vector with default white colour
C=ones(100,80,3);
Colour_One = [0 1 1];
Colour_Two = [1 1 0];
%Loop through whole diagram
for i=1:100
for j=1:80
x=i;
y=j
if inpolygon(x,y,Boundary_X,Boundary_Y)
%Code for testing which point is pixel closest to
%If closest to group 1, assign group 1 colour, else group 2
%colour
end
end
end
%Display image
hold on
imagesc(C)
hold off
右侧的形状有些正确,但其他形状则不正确。我理解这是因为我的世界坐标从负值开始,但像素坐标从1开始。
因此,我如何解决这个问题。
谢谢!
答案 0 :(得分:0)
有一点需要注意的是,你必须convert between image and plot coordinates。绘图坐标为(x,y)
,其中x
向右,y
上升。矩阵坐标为(i,j)
,其中i
向下,j
向右。一种简单的方法是使用vec_X,vec_Y
,如下所示。
较新的Matlab版本的另一个解决方案是 - 如你所说 - 使用imref2d
但不幸的是我没有使用该命令的经验。
%Boundary vectors
Boundary_X = [-5 40 85 40 -5];
Boundary_Y = [20 50 20 -10 20];
%Point vectors
Group_One_X = [20 30];
Group_One_Y = [10 40];
Group_Two_X = [50 70];
Group_Two_Y = [5 20];
%Coordinate system
min_X = -10;
max_X = 90;
min_Y = -20;
max_Y = 60;
axis([min_X, max_X, min_Y, max_Y])
%Create pixel vector with default white colour
rows_N = 100;
columns_N = 80;
C=ones(rows_N,columns_N,3);
%These vectors say where each of the pixels is in the plot coordinate
%system
vec_X = linspace(min_X,max_X,columns_N);
vec_Y = linspace(min_Y,max_Y,rows_N);
Colour_One = [0 1 1];
Colour_Two = [1 1 0];
%Loop through whole diagram
for i=1:100
for j=1:80
if inpolygon(vec_X(j),vec_Y(i),Boundary_X,Boundary_Y)
%calculate distance to each point
Distances_One = zeros(size(Group_One_X));
Distances_Two = zeros(size(Group_Two_X));
for k=1:numel(Group_One_X);
Distances_One(k) = norm([Group_One_X(k),Group_One_Y(k)]-[vec_X(j),vec_Y(i)]);%assuming euclidean norm, but can be adjusted to whatever norm you need
end
for k=1:numel(Group_Two_X);
Distances_Two(k) = norm([Group_Two_X(k),Group_Two_Y(k)]-[vec_X(j),vec_Y(i)]);%assuming euclidean norm, but can be adjusted to whatever norm you need
end
if min(Distances_One) < min(Distances_Two);
C(i,j,:) = Colour_One;
else
C(i,j,:) = Colour_Two;
end
end
end
end
%Display image
imagesc(vec_X,vec_Y,C) %lets you draw the image according to vec_X and vec_Y
%Plot boundary and points
hold on
plot(Boundary_X,Boundary_Y)
scatter(Group_One_X,Group_One_Y,10,'MarkerFaceColor','Black',...
'MarkerEdgeColor','Black')
scatter(Group_Two_X,Group_Two_Y,10,'MarkerFaceColor','Red',...
'MarkerEdgeColor','Red')
hold off