c# - 图像上的点密度
问题描述
我有两张表面上有多个点的图像
如何估计图像上这些点的密度,然后将它们与另一个具有不同点浓度的图像进行比较?我想知道在什么图像中点的密度更大。
我试图用 Emgu CV 做到这一点,但没有找到任何方法。
解决方案
有多种方法可以解决这个问题。
下面我使用 MATLAB 和DIPimage来演示这些方法。我不知道 C#,但 OpenCV(以及 EmguCV)有足够的方法来实现 #1 和 #2,尽管可能不像使用 DIPlib 那样容易。
所有演示都使用像素作为单位,如果您记录了适当的像素大小,您应该使用它来导出物理单位的距离和密度。
1.检测点和计数
精确地检测这些点并非易事,但要估计密度,我们不需要非常精确,一些失误就可以了。拉普拉斯高斯滤波器是理想的,输出中局部最大值的数量大约对应于图像中的点数。
img = readim('https://i.stack.imgur.com/TNj3p.jpg');
img = img{1}; % just one channel, all three are identical
% Approach 1: detect and count
dots = laplace(img, 3); % find the right filter size, depending on the noise in the image
dots = maxima(dots, 2);
overlay(img, dots) % display
density = max(label(dots)) / numel(img) % dots/pixel, use physical dimensions if known.
估计的密度为每像素 0.0065 个点。
2.傅里叶分析
这可能是最稳健的方法。我们将汉明窗函数应用于图像以避免边缘效应(任何窗函数都可以做得很好),计算离散傅里叶变换(使用 FFT),并取其大小。这将显示一个整齐的环,其大小由点的密度决定。接下来,我们计算每个半径(到原点的距离)的平均值,忽略前几个 bin(这些由窗口函数控制),并找到峰值。
F = abs(ft(window(img)));
F = radialmean(F);
F(0:3) = 0; % remove frequencies dominated by windowing function
plot(linspace(0, imsize(F)/2, imsize(F)), F) % display
[~,ii] = max(F);
distance = imsize(F) / ii / 2 % in pixels, use physical dimensions if known.
估计距离为 5.78 像素。
3.(半)变异函数
变异函数是一种用于分析空间依赖性的统计工具。我们可以用它来确定点之间的平均距离。
semi = semivariogram(img);
x = semi(:,1);
y = semi(:,2);
plot(x,y) % display
ii = find(maxima(y),1); % the first local maximum is the one we want
distance = x(ii) % in pixels, use physical dimensions if known.
半变异函数在进入固定趋势(基台)之前有一个小峰值。在这种情况下,峰值位于 7 个像素处。我认为如果我们在寻找峰值之前对半变异函数应用一个小的高斯平滑,结果可能会更加稳健。
推荐阅读
- c# - ViewModel 中 MVC asp.net 中的自定义验证
- c# - 可能将数据库连接到服务器
- laravel - 登录后 Laravel 一直在注销我
- netlogo - 使用特殊?变量 Netlogo 什么是替代方案?
- excel - 如何从每日报告中的先前条目中提取数据?
- angular - Angular Promise .then() 返回值
- c++ - 仅当模板参数为真时 C++ 创建变量
- r - gsub("[[:space:]]+", " ", x) 中的错误:'Calloc' 无法分配内存(226427 个字节)
- php - 确定我的数据库中存储了哪些时间参考
- node.js - 如何在客户端接收服务器传递的数据