【问题标题】:In a digital photo, how can I detect if a mountain is obscured by clouds?在数码照片中,如何检测一座山是否被云层遮挡?
【发布时间】:2011-02-01 11:17:03
【问题描述】:

问题

我在日本收藏了a mountain 的数码照片。然而,这座山经常被云或雾遮住。

我可以使用哪些技术来检测图像中的山是否可见?我目前正在将 Perl 与 Imager 模块一起使用,但对替代方案持开放态度。

所有图片都是从完全相同的位置拍摄的 - 这些是一些样本。

Sample Images http://www.freeimagehosting.net/uploads/7304a6e191.jpg

我的幼稚解决方案

我首先采集了几个山锥的水平像素样本,并将亮度值与天空中的其他样本进行比较。这对于区分好图像 1 和坏图像 2 非常有效。

然而秋天下雪了,山比天还亮,如图3,我简单的亮度测试开始失败了。

图 4 是边缘情况的示例。我会将其归类为好图像,因为有些山清晰可见。

更新 1

感谢您的建议 - 我很高兴你们都大大高估了我的能力。

根据答案,我已经开始尝试ImageMagick edge-detect 转换,它为我提供了一个更简单的图像来分析。

convert sample.jpg -edge 1 edge.jpg

Edge detected samples http://www.freeimagehosting.net/uploads/caa9018d84.jpg

我想我应该使用某种遮罩来去除树木和大部分云层。

获得蒙版图像后,将相似度与“好”图像进行比较的最佳方法是什么?我猜“compare”命令适合这份工作?如何从中获得数字“相似度”值?

更新 2

我想我可能会通过卷积到达某个地方。

我通过对一张好的图像执行边缘检测来制作我的“内核”图像(下图顶部)。然后,我将山脉轮廓周围的所有“噪音”都涂黑,然后对其进行裁剪。

然后我使用了以下代码:

use Image::Magick;

# Edge detect the test image
my $test_image = Image::Magick->new;
$test_image->Read($ARGV[0]);
$test_image->Quantize(colorspace=>'gray');
$test_image->Edge(radius => 1);

# Load the kernel
my $kernel_image = Image::Magick->new;
$kernel_image->Read('kernel-crop.jpg');

# Convolve and show the result
$kernel_image->Convolve(coefficients => [$test_image->GetPixels()]);
$kernel_image->Display();

我对各种示例图像运行了此程序,得到的结果如下(每个示例下方显示了卷积图像):

(抱歉 - 与上次不同的示例图片!)

alt text http://www.freeimagehosting.net/uploads/f9a5a34980.jpg

现在我正在尝试量化图像的“粗糙”程度。我尝试获取图像的平均亮度:

$kernel_image->Scale('1x1');
die $kernel_image->GetPixel(x=>1,y=>1)[0];

但这给出并没有给出有意义的值(0.0165、0.0175 和 0.0174)。还有更好的方法吗?

【问题讨论】:

  • +1 个很好的问题
  • 你低估了自己的能力。正如 Marcelo 所建议的那样,Update 1 中的“比较”链接有许多非常好的方法可以通过卷积生成一定程度的相似性度量。我希望你在我打字的时候摆弄那些。

标签: perl image-processing imagemagick object-detection


【解决方案1】:

我认为你的工作水平太低了。快速通过边缘检测过滤器将图像集非常明显地划分为 (1, 3) 和 (2, 4)。特别是如果这些图像来自固定的相机视点,则在算法上找到与 (1) 中的原型形状相匹配的匹配相对容易。即使是 (4) 的情况,也可以为您提供一个部分匹配的域,您可以启发式地确定那里是否有足够的山需要考虑。

【讨论】:

  • 谢谢 - 我已经开始玩边缘检测并更新了问题。如何量化那里有多少山仍然有点卡住。
【解决方案2】:

一些具体的建议,建立在你已有的基础上:

  1. 拍摄您最好的图像(类似于图像 1),通过边缘检测运行它,在任何图形编辑器中打开结果(MS Paint 可以)并清理除山顶边界(“中国帽子”线)之外的所有内容。这是你的卷积核。您可以从上方和下方裁剪(而不是调整大小!),以便在下一步中节省一些时间。
  2. 使用 PerlMagick 中的 Convolve 函数(您似乎已经习惯了 Perl 和 ImageMagick)将内核与一些图像进行卷积。在生成的图像上,您应该看到与内核的“正确”位置相对应的尖锐尖峰(与图像中的山重合)。
  3. 当山更清晰可见时,此尖峰的相对高度(相对于周围噪音的水平)会更大。通过拍摄几张具有代表性的图像,您可能能够确定一个阈值,将好图像与坏图像区分开来。
  4. 无论你做什么,都会有误报和漏报。做好准备。

【讨论】:

  • 感谢您的分步指南。这对我现在的水平非常有帮助。但是我有点不确定第 2 步是如何工作的——如何将“内核”图像传递给 Convolve 函数——它似乎只需要一个系数矩阵?
  • @Gavin:内核 == 矩阵。我试图在网上为你找到一些合适的卷积解释,但找不到任何东西——也许你应该自己试试。
  • 经过多次黑客攻击,我使用 $test_image->GetPixels() 作为系数 - 这有效吗?我又更新了帖子。
  • 它似乎工作,干得好。这并不重要,但你应该反过来做卷积,比如test_image->Convolve(coefficients => [$kernel_image->GetPixels()]);。另外,您确定Scale('1x1') 可以为您提供平均亮度吗?无论如何,90% 之类的指标应该比平均值更好。
【解决方案3】:

答案取决于问题的具体程度。如果它是来自同一 POV 的同一座山,则针对已知的良好图像运行和边缘检测,并将其用作对来自语料库的边缘检测图像进行卷积的基线。如果只是您感兴趣的山的边缘,请手动从基线中移除其他特征。

【讨论】:

  • 谢谢。幸运的是,问题非常具体 - POV 已修复。边缘检测似乎是正确的起点。我不太确定这个令人费解的部分。
  • (抱歉延迟响应;不同的时区。)两个图像的卷积会出现表明某种相似性的尖峰。如果您只想知道是否有足够多的山可见,请计算仅包含山边缘的图​​像与您正在测试的图像之间的卷积。图像中心附近的强烈尖峰将说明一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多