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

Finding items in an image which have the same intensity

如何找到具有 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 但它花了很长时间,所以我就停止了! 基本上如何为如上所述的二维数组执行此操作?

查看 https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.signal.correlate2d.html

2D 相关基本上"slides" 两个图像相互交叉,并将重叠的点积相加。

更多阅读:http://www.cs.umd.edu/~djacobs/CMSC426/Convolution.pdf

https://en.wikipedia.org/wiki/Two-dimensional_correlation_analysis

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

为此,您首先要取两个过滤结果的 相反 ,这样本来会变成 0 的均匀区域现在变成 1 和 vice-versa。您对这两个一起执行 logical AND 操作,然后确保对于每个像素,所有值在时间上都是 true。这意味着对于此图像中的空间位置,所有值都具有与您预期相同的均匀性。

在 MATLAB 中,假设您有图像处理工具箱,使用 imfilter to filter the images, then use all in MATLAB to look temporally after the two filtering results, and then use regionprops 来查找您要查找的区域的坐标。所以做这样的事情:

%# 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 矩阵,每一行告诉 upper-left 边界框原点的坐标以及边界框的宽度和高度。一行中的第一个和第二个元素是列和行坐标,而第三个和第四个元素是边界框的宽度和高度。

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

>> regions

regions =

  3×3 logical array

   0   0   0
   0   1   1
   0   1   1

>> coords

coords =

     2     2     2     2

这告诉我们,我们已经将 "uniformity" 的区域定位到右下角,而边界框的 top-left 角的坐标是第 2 行第 2 列,宽度为和高度分别为 2 和 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

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

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

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

F =

   1
   4
   6
   2
   5
   5
   3
   5
   5

应该重塑为 2D

结果 =

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不同。如果您使用 unique(E,'rows','last'); MATLAB 和 Octave 的结果将是相同的。