查找图像中具有相同强度的项目

时间:2017-02-06 19:12:20

标签: python matlab image-processing matrix computer-vision

如何找到图像中具有3维的所有点(或区域),其中前两个维显示分辨率,第三个显示密度?我可以使用Matlab或Python。我想知道是否有一个本机函数来找到那些计算量最小的点。 更新: 想象一下,我有以下几点:

A= [1,2,3; 4,6,6; 7,6,6]
A =

     1     2     3
     4     6     6
     7     6     6

>> B=[7,8,9; 10,11,11; 1, 11,11]

B =

     7     8     9
    10    11    11
     1    11    11

>> C=[0,1,2; 3, 7, 7; 5,7,7]

C =

     0     1     2
     3     7     7
     5     7     7

如何找到下方,其中A的所有值等于B的所有值和C的所有值?如果这太多了我怎样才能找到A中的下方,其中A中的所有值都相等? *显示的值是图像的强度。

更新:尝试提供的答案并收到此错误:

>> c=conv2(M,T, 'full');
Warning: CONV2 on values of class UINT8 is obsolete.
         Use CONV2(DOUBLE(A),DOUBLE(B)) or CONV2(SINGLE(A),SINGLE(B)) instead. 
> In uint8/conv2 (line 10) 
Undefined function 'conv2' for input arguments of type 'double' and attributes 'full 3d real'.

Error in uint8/conv2 (line 17)
y = conv2(varargin{:});

*还尝试了convn,它花了很长时间,所以我就停止了! 基本上如何为2D阵列执行此操作?如上所述?

3 个答案:

答案 0 :(得分:2)

您可以使用一对水平和垂直1D滤镜,使水平滤镜的内核为[1 -1],而垂直滤镜的内核为[1; -1]。这样做的结果是它分别对每个维度中的每个元素采用水平和垂直成对距离。然后,您可以使用这两个内核执行图像过滤或卷积,确保复制边框。为了能够找到统一区域,通过检查两个结果中的哪些区域在它们之间映射到0,这将为您提供区域,这些区域在所有通道上独立均匀。

要执行此操作,您首先要使用两个过滤结果的相反,以便将变为0的均匀区域现在为1,反之亦然。您同时对这两个像素执行logical AND操作,然后确保对于每个像素在时间上,所有值都是true。这意味着对于此图像中的空间位置,所有值都会达到您期望的相同均匀度。

在MATLAB中,假设你有图像处理工具箱,使用imfilter过滤图像,然后在MATLAB中使用all在两个过滤结果后暂时查看,然后使用{{3}找到你寻找的区域的坐标。所以做这样的事情:

%# Reproducing your data
A = [1,2,3; 4,6,6; 7,6,6];
B = [7,8,9; 10,11,11; 1, 11,11];
C = [0,1,2; 3, 7, 7; 5,7,7];

%# Create a 3D matrix to allow for efficient filtering
D = cat(3, A, B, C);

%# Filter using the kernels
ker = [1 -1];
ker2 = ker.'; %#
out = imfilter(D, ker, 'replicate');
out2 = imfilter(D, ker2, 'replicate');

%# Find uniform regions
regions = all(~out & ~out2, 3);

%# Determine the locations of the uniform areas
R = regionprops(regions, 'BoundingBox');

%# Round to ensure pixel accuracy and reshape into a matrix
coords = round(reshape([R.BoundingBox], 4, [])).';

coords将是一个N x 4矩阵,每行记录边界框原点的左上角坐标以及边界框的宽度和高度。行中的第一个和第二个元素是列和行坐标,而第三个和第四个元素是边界框的宽度和高度。

我们检测到的区域可以在regions变量中找到。这两个都表明:

>> regions

regions =

  3×3 logical array

   0   0   0
   0   1   1
   0   1   1

>> coords

coords =

     2     2     2     2

这告诉我们,我们已将“uniform”的区域本地化为右下角,而边界框的左上角的坐标是第2行,第2列的宽度和高度为2和2分别

答案 1 :(得分:2)

可能的解决方案:

A = [1,2,3; 4,6,6; 7,6,6];
B = [7,8,9; 10,11,11; 1, 11,11];
C = [0,1,2; 3, 7, 7; 5,7,7];
%create a 3D array
D = cat(3,A,B,C)
%reshape the 3D array to 2D 
%its columns represent the third dimension
%and its rows represent resolution
E = reshape(D,[],size(D,3));
%third output of the unique function applied row-wise  to the data
%represents the label of each pixel a [m*n, 1] vector created
[~,~,F] = unique(E,'rows');
%reshape the vector to a [m, n] matrix of labels
result = reshape(F, size(D,1), size(D,2));

您可以将3D矩阵重塑为2D矩阵(E),其列代表第三维,其行代表分辨率。

然后使用unique功能,您可以标记图像。

我们有一个3D矩阵:

A =
     1     2     3
     4     6     6
     7     6     6
B =
     7     8     9
    10    11    11
     1    11    11
C =
     0     1     2
     3     7     7
     5     7     7

当我们将3D矩阵重塑为2D矩阵E时,我们得到:

E =

    1    7    0
    4   10    3
    7    1    5
    2    8    1
    6   11    7
    6   11    7
    3    9    2
    6   11    7
    6   11    7

所以我们需要根据它们的值对行进行分类。

唯一函数能够提取唯一行并将相同的标签分配给彼此相等的行。

此处varible F捕获作为每行标签的唯一函数的第三个输出。

F =

   1
   4
   6
   2
   5
   5
   3
   5
   5

应该重塑为2D

result =

1   2   3
4   5   5
6   5   5

所以每个地区都有不同的标签。

如果要分割不同的区域(基于它们的值和空间位置),您需要在循环中标记图像

numcolors = max(F);
N = 0;
segment = zeros(size(result));
for c = 1 : numcolors
    [label,n] = bwlabel(result==c);
    segment = segment +label + logical(label)*N;
    N = N + n;
end

所以在这里你需要标记具有不同标签的相同值的断开连接的区域。由于MATLAB没有灰度分割功能,您可以多次使用bwlabel函数进行分割,并将上一次迭代的结果添加到当前迭代的结果中。 segment变量包含分段图片。

*注意:从GNU Octave获得的结果是它的标签与MATLAB不同。如果使用MATLAB的unique(E,'rows','last');结果,Octave将是相同的。

答案 2 :(得分:0)