如何在图像中找到最密集的区域?

Tas*_*eer 13 algorithm matlab image-processing

考虑像这样的黑白图像

替代文字

我想要做的是找到白点最密集的区域.在这种情况下,存在20-21个这样的密集区域(即,点簇成为密集区域).

任何人都可以给我任何关于如何实现这一点的提示吗?

gno*_*ice 18

如果您可以访问图像处理工具箱,则可以利用它包含的许多过滤和形态操作.这里是你可以接近你的问题的一种方法,使用的功能imfilter,imclose以及imregionalmax:

% Load and plot the image data:
imageData = imread('lattice_pic.jpg');  % Load the lattice image
subplot(221);
imshow(imageData);
title('Original image');

% Gaussian-filter the image:
gaussFilter = fspecial('gaussian', [31 31], 9);  % Create the filter
filteredData = imfilter(imageData, gaussFilter);
subplot(222);
imshow(filteredData);
title('Gaussian-filtered image');

% Perform a morphological close operation:
closeElement = strel('disk', 31);  % Create a disk-shaped structuring element
closedData = imclose(filteredData, closeElement);
subplot(223);
imshow(closedData);
title('Closed image');

% Find the regions where local maxima occur:
maxImage = imregionalmax(closedData);
maxImage = imdilate(maxImage, strel('disk', 5));  % Dilate the points to see
                                                  % them better on the plot
subplot(224);
imshow(maxImage);
title('Maxima locations');
Run Code Online (Sandbox Code Playgroud)

这是上面代码创建的图像:

在此输入图像描述

为了让事情看起来不错,我只是为高斯滤波器(使用创建fspecial)和结构元素(使用创建)的参数尝试了几种不同的组合strel.然而,这一点点的试验和错误给出了一个非常好的结果.

注意:从返回的图像imregionalmax并不总是只有单个像素设置为1(表示最大值).输出图像通常包含像素簇,因为输入图像中的相邻像素可以具有相等的值,因此都被计为最大值.在上面的代码中,我也扩大了这些点,imdilate只是为了让它们更容易在图像中看到,这使得更大的像素集群以最大值为中心.如果要将像素簇缩小为单个像素,则应删除扩张步骤并以其他方式修改图像(向结果添加噪声或对其进行过滤,然后查找新的最大值等).


mar*_*nus 7

滑动窗(简单但缓慢)

您可以创建一个滑动窗口(例如10x10像素大小),迭代图像,对于每个位置,您可以计算此10x10字段中的白色像素数,并存储具有最高计数的位置.

整个过程是O(n*m),其中n是图像的像素数,m是滑动窗口的大小.

换句话说,您使用均值过滤器(此处为框过滤器)对图像进行卷积,然后使用极值.

滑动窗(快速)

首先,计算一个求和面积表,可以在一次通过中非常有效地完成:

  1. 创建一个sat与原始图像大小相同的2D数组img.
  2. 迭代每个索引,并计算每个索引xy

    sat[x, y] = img[x, y] + sat[x-1, y] + sat[x, y-1] - sat[x-1, y-1]
    
    Run Code Online (Sandbox Code Playgroud)

    例如,给定一个图像,其中0为暗,1为白色,这是结果:

       img            sat
    0 0 0 1 0 0   0 0 0 1 1 1 
    0 0 0 1 0 0   0 0 0 2 2 2
    0 1 1 1 0 0   0 1 2 5 5 5
    0 1 0 0 0 0   0 2 3 6 6 6
    0 0 0 0 0 0   0 2 3 6 6 6
    
    Run Code Online (Sandbox Code Playgroud)
  3. 现在用滑动窗口迭代求和区域表的索引,并使用滑动窗口的角A,B,C,D计算其中的白色像素数:

       img            sat          window
    0 0 0 1 0 0   0 0 0 1 1 1   0 A-----B 1 
    0 0 0 1 0 0   0 0 0 2 2 2   0 | 0 2 | 2
    0 1 1 1 0 0   0 1 2 5 5 5   0 | 2 5 | 5
    0 1 0 0 0 0   0 2 3 6 6 6   0 | 3 6 | 6
    0 0 0 0 0 0   0 2 3 6 6 6   0 D-----C 6
    
    Run Code Online (Sandbox Code Playgroud)

    计算

    density(x', y') = sat(A) + sat(C) - sat(B) - sat(D)
    
    Run Code Online (Sandbox Code Playgroud)

    在上面的例子中是哪个

    density(1, 0) = 0 + 6 - 1 - 2 = 3
    
    Run Code Online (Sandbox Code Playgroud)

这个过程需要一个临时图像,但它只是O(n),因此速度与滑动窗口的大小无关.


小智 6

如果你有图像处理工具箱,用高斯滤波器模糊它,然后找到峰值/极值.

改变高斯滤波器的大小以获得所需的"密集"区域的数量.