如果我有一堆图像并且尺寸正在跟随,
size(M) = [256 256 124];
我有3个点,它们的坐标是,
coor_a = [100,100,124];
coor_b = [256,156,0];
coor_c = [156,256,0];
如何从由3个点定义的平面相交的M创建点的图像?
答案 0 :(得分:3)
首先,你可以注意到,如果你在(三维)欧几里德(代数)空间中,那么你要做的就是找到一个平面和一个格子之间的交点。
你所拥有的是你的矩阵(M),其大小定义了格子。
然后,因为3个非共线点定义了一个独特的平面(在3维空间中),所以你有一个独特的平面,但你必须想出一个更好的平面描述来找到它与晶格。
注意:在其他任何事情之前,您需要将您的点重新定义为正确的列向量:
coor_a = [100 ; 100 ; 124];
coor_b = [256 ; 156 ; 0];
coor_c = [156 ; 256 ; 0];
现在,首先,我们可以通过使用您提供的3个平面点中的两对点,为3-D平面的2-D表面定义任意一对矢量基数:
u = (corr_b - corr_a);
v = (corr_c - corr_b);
现在,u
和v
定义了平面的流形空间的基矢量。所以,从概念上讲,你要做的就是找到你得到的格子点。来自u
和v
的线性组合。这是因为一个平面实际上是一个基本的线性流形,这意味着它也可以被认为是一个函数:
P = f(u, v) = au + bv
其中P
是飞机上的任何一点。
现在,因为您知道M是具有以下域集的矩阵点阵(Set Notation):
e1 = [0, 255]
e2 = [0, 255]
e3 = [0, 123]
你实际上可以将格子中的所有点都作为(MATLAB代码):
X, Y, Z = meshgrid( 0:1:255, 0:1:255, 0:1:123 );
获得meshgrid
索引后,您可以将矩阵展平为带有冒号索引的向量,然后您可以创建一个A
的新矩阵3 x (m • n • p)
,我们已经拥有M
{ {1}}大小为m x n x p
:
A = [ X(:); Y(:); Z(:) ];
因为您的矩阵M
不大,所以这不会造成内存问题。
我们现在可以回顾P
并将P
定义为矢量符号中的线性方程式(MATLAB表示法):
P = ( (a * u) + (b * v) );
我们想要的是i
的所有值,其中以下是真实的:
A(i) = ( (a * u) + (b * v) );
但这是MATLAB,所以我们希望利用线性代数运算并避免迭代进行矢量化。
我们正在构建的内容被称为" Hesse Normal Form"平面的代数方程:
http://en.wikipedia.org/wiki/Hesse_normal_form
我们可以利用这样的事实:使用基向量我们可以找到平面的法向量:
n = cross( (corr_b - corr_a), (corr_c - corr_b) );
现在缺少的是到飞机d
的距离,可以找到原始点矢量均值的范数:
d = norm( mean( [ corr_a ; corr_b ; corr_c ] ), 2 );
从Hesse表单中,这给了我们n
和d
,所有缺失的是r
,这是平面上格子中的点,所以我们{{1 }}值是位于平面上的r
列。
现在我们可以在MATLAB中以矢量化形式进行以下计算,通过使用A
作为行向量来获得格子中每个点与平面的距离(列向量的转置)并利用矩阵乘法:
n
由于我们使用矩阵乘法,L = ( ( (n.') * A ) - d );
变为L
数组,其中每个条目都是1 x (m • n • p)
的点积和n
的列。 A
处或附近的任何值 - 取决于您要使用的阈值 - 是平面中晶格中的点。
您可以使用0
方法从A
获取l
的索引,并生成逻辑find
(NOT
)以转换所有零到~
和1
的所有非零值,其中0
返回给定矩阵或向量的所有非零值的所有索引:
find
还有很多其他方法可以做到这一点,但我认为这种方法利用了代数和内置的MATLAB函数。如果您小心,您可以实际获取所有以前的命令,并在一行MATLAB代码中完成所有操作。阅读起来很可怕,所以最好将它们全部留作单独的行。
此外,这可以很容易地设置为一个函数,以便您输入3个点值和给定的晶格或晶格定义矩阵,然后您可以返回平面上的所有晶格点或返回表单中的距离向量i = find( ~L );
,以便您可以准确地选择"关闭"根据您手头的问题,L
可以接受实际在平面上。
最后,为了明确,如果你想创建一个平面上所有点的单通道图像,你可以从以下位置获得点数组:
0
执行此操作后,您可以使用基本的ImPoints = A(:,i);
循环从M
中提取每个点,并将for
的值放在某个新的图像数组M
中,即你会想要用零预构建。
请注意,I
的列是ImPoints
的行 - 列 - 通道索引,这意味着您需要执行以下操作:
M
您必须预先定义for j = [ 1 : 1 : NumPoints ]
NewImIndex = SomeFunc( ImPoints, j );
I( NewImIndex ) = M( ImPoints(:,j) );
end;
,并提出首选方法,I
将SomeFunc
的像素/数据放入新图片M
。< / p>
答案 1 :(得分:1)
我适合飞机,然后找到最近的点。
%This is the inputs you provided
M = floor(256*rand(256, 256, 124));
a = [100, 100, 124];
b = [256, 156, 0];
c = [156, 256, 0];
% change from a set of triplets to x, y and z vectors
points = [a', b', c'];
x = points(1,:)';
y = points(2,:)';
z = points(3,:)';
%Use Matlab's plane fit function
[ft, ~] = fit( [x, y], z, 'poly11' );
%Get the size of the input matrix
[XExt, YExt, ZExt] = size(M);
%These will be the inputs in the plane
X = 0:XExt-1;
Y = 0:YExt-1;
[X, Y] = meshgrid(X, Y);
%Find the points closest to the plane
Z = round(ft(X, Y));
%Get the x, y, z points of the points on the plane which are also in the extent of M
x = X((Z > 0) & (Z < ZExt)) + 1;
y = Y((Z > 0) & (Z < ZExt)) + 1;
z = Z((Z > 0) & (Z < ZExt));
%Preallocate for the points on the plane
MPrime = zeros(size(z));
%Get the points, need the loop because otherwise Matlab throws an error
for i = 1:length(z)
MPrime(i) = M(x(i), y(i), z(i));
end
%Final output is a N x 3 vector with the row, column, value
NewImage = [x, y, MPrime];
我希望这会有所帮助。