【发布时间】:2011-01-01 08:52:10
【问题描述】:
【问题讨论】:
-
在家庭作业的背景下,截至此快照的所有答案似乎都是完全合理的。 :)
标签: algorithm matlab image-processing
【问题讨论】:
标签: algorithm matlab image-processing
也许是一种天真的方法:
您定义一个 n*n 的正方形,它是您测量密度的区域的最大尺寸。对于图像中的每个点,您将该点视为正方形的中心,并围绕黑色 (b) 和白色 (w) 点的数量进行计数。使用 b-w 的差异,您可以确定哪个正方形最白。
必须以模糊的方式确定最密集的区域。如果一个区域有 600 个白点,另一个有 599 个,那么对于人眼来说,它们的密度相同。 600 是 100% 密集,而 599 是 99% 密集和 1% 非密集。为此使用 epsilon。
n 可以预定义或基于某些函数(即图像大小的百分比)。
您也可以使用圆形/椭圆形而不是方形/矩形。选择最适合您的需求
【讨论】:
您可以创建一个迭代图像的滑动窗口(例如 10x10 像素大小),并为每个位置计算此 10x10 字段中白色像素的数量,并存储计数最高的位置。
整个过程O(n*m),其中n是图像的像素数,m是滑动窗口的大小。
换句话说,你convolve 用mean filter 的图像(这里是框过滤器),然后使用极值。
首先,计算一个summed area table,可以非常高效地一次性完成:
img大小相同的二维数组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),所以速度与滑动窗口的大小无关。
【讨论】:
如果您有图像处理工具箱,请使用高斯滤镜对其进行模糊处理,然后找到峰值/极值。
改变高斯滤波器的大小以获得您想要的“密集”区域的数量。
【讨论】:
如果您有权访问Image Processing Toolbox,则可以利用其中包含的许多过滤和形态学操作。这是解决问题的一种方法,使用函数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');
这是上面代码创建的图像:
为了让事情看起来不错,我一直尝试为高斯滤波器(使用 fspecial 创建)和结构元素(使用 strel 创建)的参数尝试几种不同的组合。然而,这一点尝试和错误产生了非常好的结果。
注意:从imregionalmax 返回的图像并不总是只有单个像素设置为 1(表示最大值)。输出图像通常包含像素簇,因为输入图像中的相邻像素可以具有相等的值,因此都被视为最大值。在上面的代码中,我还用imdilate 扩大了这些点,只是为了让它们更容易在图像中看到,这使得以最大值为中心的更大的像素簇。如果您想将像素簇减少为单个像素,则应移除膨胀步骤并以其他方式修改图像(在结果中添加噪声或对其进行过滤,然后找到新的最大值等)。
【讨论】: