沿着轴平移RGB颜色的2D图像

时间:2016-01-10 11:23:42

标签: matlab

我正在尝试创建自己的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

这是结果 Failed Voronoi Diagram

右侧的形状有些正确,但其他形状则不正确。我理解这是因为我的世界坐标从负值开始,但像素坐标从1开始。

因此,我如何解决这个问题。

谢谢!

1 个答案:

答案 0 :(得分: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