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

Algorithm 如何在图像中找到最密集的区域?,algorithm,matlab,image-processing,Algorithm,Matlab,Image Processing,考虑像这样的黑白图像 我想做的是找到白点最密集的区域。在这种情况下,有20-21个这样的密集区域(即,点簇构成密集区域) 有谁能给我一些关于如何实现这一目标的暗示吗 也许是一种天真的方法: 定义一个n*n的平方,它是测量密度的区域的最大大小。对于图像中的每一点,你认为点是正方形的中心,并围绕黑色(B)和白色(W)点的数量进行计数。使用差值b-w,您可以确定哪个正方形最白 必须以模糊方式确定最密集的区域。如果一个区域有600个白点,另一个区域有599个,那么对于人眼来说,它们的密度是相同的。60

考虑像这样的黑白图像

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


有谁能给我一些关于如何实现这一目标的暗示吗

也许是一种天真的方法:

定义一个n*n的平方,它是测量密度的区域的最大大小。对于图像中的每一点,你认为点是正方形的中心,并围绕黑色(B)和白色(W)点的数量进行计数。使用差值b-w,您可以确定哪个正方形最白

必须以模糊方式确定最密集的区域。如果一个区域有600个白点,另一个区域有599个,那么对于人眼来说,它们的密度是相同的。600密度为100%,599密度为99%,非密度为1%。用ε表示

n可以预定义或基于某些函数(即图像大小的百分比)

您也可以使用圆/椭圆代替正方形/矩形。选择最适合您需要的滑动窗口(简单但缓慢) 您可以创建一个滑动窗口(例如10x10像素大小),在图像上进行迭代,并为每个位置计算10x10字段中的白色像素数,并存储计数最高的位置

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

换句话说,您可以使用一个(这里是长方体过滤器)来处理图像,然后使用极值

滑动窗口(快速) 首先,计算a,这可以在一次过程中非常有效地完成:

  • 创建与原始图像大小相同的二维阵列
    sat
  • 迭代每个索引,并为每个索引计算
    x
    y

    sat[x, y] = img[x, y] + sat[x-1, y] + sat[x, y-1] - sat[x-1, y-1]
    
    例如,给定一个图像,其中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
    
  • 现在使用滑动窗口迭代求和面积表的索引,并使用滑动窗口的角点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
    
    算计

    density(x', y') = sat(A) + sat(C) - sat(B) - sat(D)
    
    在上面的例子中,哪个是

    density(1, 0) = 0 + 6 - 1 - 2 = 3
    

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

    如果您有图像处理工具箱,请使用高斯滤波器将其模糊,然后找到峰值/极值

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

    如果您可以访问,则可以利用其中包含的大量滤波和形态学操作。以下是解决问题的一种方法,即使用函数和:

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

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


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

    在家庭作业的背景下,截至此快照的所有答案都非常合理。:)为什么需要关闭过滤器步骤?它只是关闭了黑洞。如果你只对最大值感兴趣,你为什么要这么做?@nikie:正如你从左下角的图中所看到的,接近的一步填满了黑洞和较小的最大值。它基本上在最大的最大值周围形成了一系列平坦、均匀的“高原”。如果你看过滤图像的中心,你可以看到一个较小的最大值,它被关闭操作平滑了。@gnovice:你说的“填充”是什么意思?它不能使最大面积变小。它可能会将一个局部最大值与附近的明亮区域联系起来(所以它不再是一个最大值),这就是你的意思吗?(图太小了。)那么你可以通过放大高斯滤波图像,并在放大图像和高斯滤波图像中选择亮度相等的像素来达到同样的效果,对吗?(也就是说,像素至少与某个邻域中最亮的像素一样亮)。@nikie:解决这个问题的方法可能有很多。我选择IMCLOSE是因为我只是在寻找不同的方法来“展平”最大最大值之间的区域。IMCLOSE使用先膨胀后侵蚀的方法,因此它将最大的最大值扩展到较小的最大值,然后将其缩小。您的解决方案(放大加上与过滤图像的比较)当然是可行的,但您可能必须使用更大的结构元素来确保所有非最大值像素都被放大,在这种情况下,一个“真实”最大值可能会无意中放大到另一个。
    % 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');