首先,你可以注意到如果你在一个(三维)欧几里得(代数)空间中,你要做的就是找到平面和格子之间的交点。
你拥有的是矩阵(M),其大小定义了格子。
然后,因为三个非共线点定义了一个唯一的平面(在三维空间中),你有一个唯一的平面,但你必须想出一个更好的描述平面的方法来找到它与格子的交点。
注意:在任何其他操作之前,你需要将你的点重新定义为适当的列向量。
coor_a = [100 ; 100 ; 124];
coor_b = [256 ; 156 ; 0];
coor_c = [156 ; 256 ; 0];
现在,首先,我们可以通过使用你提供的三个平面点中的两个点对来定义一个任意的二维平面向量基。
u = (corr_b - corr_a);
v = (corr_c - corr_b);
现在,
u
和
v
定义了平面流形空间的基向量。因此,从概念上讲,您正在尝试找到由
u
和
v
的线性组合“到达”的晶格点。这是因为平面实际上是一个基本的线性流形,也可以被视为一个函数:
P = f(u, v) = au + bv
请注意,此处的P
是平面上的任意一点。
现在,您已经知道M是一个矩阵晶格,并具有以下定义域集合(集合符号):
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` 大小为 `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
,即平面上格点的点,因此我们的
r
值是在平面上的
A
矩阵列。
因此,现在我们可以使用
n
作为行向量(列向量的转置)进行向量化计算,在MATLAB中非常快地获取每个格点到平面的距离,并利用
矩阵乘法的优势。
L = ( ( (n.') * A ) - d );
因为我们使用矩阵乘法,
L
变成了一个
1 x (m • n • p)
的数组,其中每个条目是
n
和
A
的列的点积。任何接近或等于
0
的值 - 取决于您想要使用的阈值 - 都是在平面上的格点。
您可以通过使用 find
方法并生成逻辑 NOT
(~
) 来从 l
中获取 A
的索引,将所有零变成 1
,将所有非零值变成 0
,其中 find
返回给定矩阵或向量的所有非零值的索引:
i = find( ~L )
有许多其他方法可以做到这一点,但我认为这种方法利用了代数和内置的MATLAB函数。如果你小心的话,实际上可以将所有先前的命令都放在一行MATLAB代码中完成。这将很难阅读,所以最好将它们保留为单独的行。
此外,这可以轻松设置为一个函数,使您输入3个点值和给定的晶格或晶格定义矩阵,然后您可以返回平面上的所有晶格点或返回向量L的距离,以便您可以选择“接近”0的程度是可接受的,具体取决于您手头的问题。
最后,为了明确起见,如果您想创建一个包含平面上所有点的1通道图像,则可以从以下位置获取点数组:
ImPoints = A(:,i)
一旦您这样做了,您可以使用基本的
for
循环从
M
中提取每个点,并将
M
的值放入一些新的图像数组
I
中,您需要预先用零构造它。
请注意,
ImPoints
的列是
M
的行-列-通道索引,这意味着您需要执行类似以下操作:
for j = [ 1 : 1 : NumPoints ]
NewImIndex = SomeFunc( ImPoints, j );
I( NewImIndex ) = M( ImPoints(:,j) );
end;
您需要预定义I
并想出您偏爱的方法,让SomeFunc
将像素/数据从M
放入您的新图像I
中。
image-processing
标签改成了geometry
,这与图像处理没有任何关系。 - rayryengM
是医学图像(CT扫描切片)或高光谱图像(124个唯一波长的带),那么这很可能是一个图像处理问题。而且问题明确要求如何创建切片的图像,尽管在MATLAB中,图像只是一个矩阵。因此,这是一个图像处理和几何问题,尽管它可以被视为纯几何问题。只是随便提一下。 - user3834473