2016-01-10 37 views
0

我正尝试创建自己的voronoi图。我有一个任意的形状,它们的x和y坐标存储在不同的向量中。在这个形状内部有一些感兴趣的点(具有已知的坐标),它们属于两个不同的组,并且作为voronoi图的种子。例如,整个图表的范围从x = -10到x = 90,y = -20到y = 60。边界形状不是矩形的,而是落在上面的轴范围内。沿着轴以RGB色彩翻译2D图像

我到目前为止所做的工作是创建一个3D矩阵(100 X 80 X 3),C,全部为1,以便默认颜色为白色。然后,我从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 

这是结果 Failed Voronoi Diagram

的形状是右侧有些正确的,但不是为别人。我知道这是因为我的世界坐标从负值开始,但像素坐标从1开始。

因此,我在迷失方面如何解决此问题。

谢谢!

+0

[请提供最小,完整的,并且可验证示例](http://stackoverflow.com/help/mcve) – flawr

+0

@flawr嘿我所提供的请求的例子。谢谢! – Kenneth

回答

0

有一点要注意的是,你必须convert between image and plot coordinates。情节坐标是(x,y)其中x在右边,y上升。矩阵坐标为(i,j),其中i下降,j向右。一个简单的方法是使用vec_X,vec_Y,如下所示。

更新的Matlab版本的另一个解决方案是 - 如您所说 - 使用imref2d,但不幸的是我没有使用该命令的经验。

plot

%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 
+0

谢谢你!这帮助我解决了我的问题。与使用imref2d相比,您解决问题的方式更简单,更容易遵循。干杯! – Kenneth