Image 将非零图像像素转换为行-列坐标,并将输出保存到工作空间

Image 将非零图像像素转换为行-列坐标,并将输出保存到工作空间,image,matlab,image-processing,Image,Matlab,Image Processing,我很难将图像像素转换为坐标,并使它们出现在我的MATLAB工作区中。例如,我有如下像素值的图像(它是大小为4x4的二进制图像): 获取像素后,我想读取每个值,如果它们不等于零(即1),我想读取该值的坐标,并将它们保存到我的MATLAB工作区中。例如,这是我想到的想法: [x,y] = size(image) for i=1:x for j=1:y if (image(i,j)~=0) .... 然而,我被卡住了。有没有人能就如何读取非零值的坐标并将其保存到我的

我很难将图像像素转换为坐标,并使它们出现在我的MATLAB工作区中。例如,我有如下像素值的图像(它是大小为4x4的二进制图像):

获取像素后,我想读取每个值,如果它们不等于零(即1),我想读取该值的坐标,并将它们保存到我的MATLAB工作区中。例如,这是我想到的想法:

[x,y] = size(image)
for i=1:x
   for j=1:y
       if (image(i,j)~=0)
       ....
然而,我被卡住了。有没有人能就如何读取非零值的坐标并将其保存到我的工作区给出建议

具体来说,我在工作区中的预期结果是:

2 2

2 3

3 2

3 3

使用循环可能不是实现要求的最有效的方法。相反,使用<代码>查找确定向量或矩阵中非零的位置。在您的情况下,您所要做的就是:

[row,col] = find(image);
将包含二进制图像中非零元素的行和列位置。因此,以你的例子:

b = [0 0 0 0;
     0 1 1 0;
     0 1 1 0;
     0 0 0 0];
我们得到:

>> disp([row, col]);

 2     2
 3     2
 2     3
 3     3
但是,您将看到位置与您期望的顺序不符。这是因为位置按主列顺序显示,这意味着首先遍历列。在您的示例中,您将按行主顺序显示它们。如果要保持此顺序,请按行坐标对结果进行排序:

>> sortrows([row, col])

ans =

     2     2
     2     3
     3     2
     3     3

然而,如果你真的。。。我是说真的。。。要使用
进行循环,您需要做的是保留两个单独的数组,它们最初为空,然后循环每个像素并确定其是否为非零。如果是,则将
x
y
位置添加到这两个单独的数组中

因此,您可以这样做:

row = []; col = [];
[x,y] = size(image);
for i=1:x
   for j=1:y
       if (image(i,j)~=0)
           row = [row; i]; %// Concatenate row and column location if non-zero
           col = [col; j];
       end
   end
end

这应该会给您提供与
find

相同的结果,使用循环可能不是执行您要求的最有效的方法。相反,使用<代码>查找
确定向量或矩阵中非零的位置。在您的情况下,您所要做的就是:

[row,col] = find(image);
将包含二进制图像中非零元素的行和列位置。因此,以你的例子:

b = [0 0 0 0;
     0 1 1 0;
     0 1 1 0;
     0 0 0 0];
我们得到:

>> disp([row, col]);

 2     2
 3     2
 2     3
 3     3
但是,您将看到位置与您期望的顺序不符。这是因为位置按主列顺序显示,这意味着首先遍历列。在您的示例中,您将按行主顺序显示它们。如果要保持此顺序,请按行坐标对结果进行排序:

>> sortrows([row, col])

ans =

     2     2
     2     3
     3     2
     3     3

然而,如果你真的。。。我是说真的。。。要使用
进行循环,您需要做的是保留两个单独的数组,它们最初为空,然后循环每个像素并确定其是否为非零。如果是,则将
x
y
位置添加到这两个单独的数组中

因此,您可以这样做:

row = []; col = [];
[x,y] = size(image);
for i=1:x
   for j=1:y
       if (image(i,j)~=0)
           row = [row; i]; %// Concatenate row and column location if non-zero
           col = [col; j];
       end
   end
end
这将提供与查找相同的结果,您可以使用meshgrid()收集这些坐标。该函数生成两个输出,第一个是x坐标,第二个是y坐标。你会这样说:

[xcoord ycoord] = meshgrid( 1:x_size, 1:y_size);

zeros_coordsx = xcoord( image == 0);
zeros_coordsy = ycoord( image == 0);
这比嵌套循环快得多,并使您保持在matlab的自然向量操作空间内。。。这两个输出是同步的,这意味着

image( zeros_coordsy(1), zeros_coordsx(1)) 
是图像上的零之一

您可以使用meshgrid()收集这些坐标。该函数生成两个输出,第一个是x坐标,第二个是y坐标。你会这样说:

[xcoord ycoord] = meshgrid( 1:x_size, 1:y_size);

zeros_coordsx = xcoord( image == 0);
zeros_coordsy = ycoord( image == 0);
这比嵌套循环快得多,并使您保持在matlab的自然向量操作空间内。。。这两个输出是同步的,这意味着

image( zeros_coordsy(1), zeros_coordsx(1)) 

是图像上的零之一

您可能应该将其更改为
image~=0
,因为OP正在查找所有非零坐标。此外,获得坐标的
网格
,然后索引到坐标的每个维度是否比使用
查找
更快?此外,就内存复杂性而言,这似乎有点不必要。您实际上占用了
2N
更多的双倍内存来执行您的请求,其中
N
是图像的总大小。没有理由比find更快。当我需要根据坐标计算一些值时,我经常使用这种方法,比如纹理生成。旧习惯,没什么更深刻的:)。您的评论是100%正确的,find()做得很好。但值得注意的是,meshgrid()方法适用于更多维度,尽管在讨论中它并不重要。:)啊哈,用
meshgrid
就够了。但是,如果要将
find
扩展到多个维度,只需获取列的主要线性索引,然后调用
ind2sub
调用。。。但是,是的,这不是重点:)。不过,我确实喜欢另一种方法,而且对于纹理生成之类的事情来说,这肯定是正确的方法。我给你一个+1。你可能应该把它改成
image~=0
,因为OP正在寻找所有非零坐标。此外,获得坐标的
网格
,然后索引到坐标的每个维度是否比使用
查找
更快?此外,就内存复杂性而言,这似乎有点不必要。您实际上占用了
2N
更多的双倍内存来执行您的请求,其中
N
是图像的总大小。没有理由比find更快。当我需要根据坐标计算一些值时,我经常使用这种方法,比如纹理生成。旧习惯,没什么更深刻的:)。您的评论是100%正确的,find()的作用仅限于此