在数码照片中,如何检测山脉是否被云遮住了?

发布于 2024-08-26 23:13:22 字数 2326 浏览 11 评论 0原文

问题

我有一组日本一座山的数码照片。然而,这座山经常被云或雾遮蔽。

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

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

示例图片 http://www.freeimagehosting.net/uploads/7304a6e191.jpg

我的简单解决方案

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

然而,在秋天下雪了,山变得比天空更亮,就像图 3 一样,我的简单亮度测试开始失败。

图 4 是边缘情况的示例。我认为这是一张好照片,因为一些山峰清晰可见。

更新1

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

根据答案,我开始尝试 ImageMagick 边缘检测 变换,它给出我有一个更简单的图像来分析。

convert sample.jpg -edge 1 edge.jpg

边缘检测样本 http://www.freeimagehosting.net/uploads/caa9018d84.jpg

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

获得蒙版图像后,比较与“好”图像相似度的最佳方法是什么?我想“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();

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

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

替代文本 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)。还有更好的办法吗?

The problem

I have a collection of digital photos of a mountain in Japan. However the mountain is often obscured by clouds or fog.

What techniques can I use to detect that the mountain is visible in the image? I am currently using Perl with the Imager module, but open to alternatives.

All the images are taken from the exact same position - these are some samples.

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

My naïve solution

I started by taking several horizontal pixel samples of the mountain cone and comparing the brightness values to other samples from the sky. This worked well for differentiating good image 1 and bad image 2.

However in the autumn it snowed and the mountain became brighter than the sky, like image 3, and my simple brightness test started to fail.

Image 4 is an example of an edge case. I would classify this as a good image since some of the mountain is clearly visible.

UPDATE 1

Thank you for the suggestions - I am happy you all vastly over-estimated my competence.

Based on the answers, I have started trying the ImageMagick edge-detect transform, which gives me a much simpler image to analyze.

convert sample.jpg -edge 1 edge.jpg

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

I assume I should use some kind of masking to get rid of the trees and most of the clouds.

Once I have the masked image, what is the best way to compare the similarity to a 'good' image? I guess the "compare" command suited for this job? How do I get a numeric 'similarity' value from this?

UPDATE 2

I think I may be getting somewhere with convolve.

I made my 'kernel' image (top of the image below) by performing edge detect on a good image. I then blacked out all the 'noise' around the outline of the mountain and then cropped it.

I then used the following code:

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();

I ran this for various sample images, and I got results as below (the convolved image is shown below each sample):

(Sorry - different sample images from last time!)

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

Now I am trying to quantify how 'ridgy' an image is. I tried taking the image average brightness:

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

But this gives does not give meaningful values (0.0165, 0.0175 and 0.0174). Any better ways?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

美人迟暮 2024-09-02 23:13:23

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

The answer depends on how specific the problem is. If it's the same mountain from the same POV, run and edge detection against a known good image, and use it as a baseline for convolving against edge-detected images from the corpus. If it's only the edge of the mountain that you're interested in, manually remove other features from the baseline.

无边思念无边月 2024-09-02 23:13:22

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

I think you are working on too low a level. A quick pass through an edge detection filter partitioned the image set very distinctly into (1, 3) and (2, 4). Especially if these images come from a fixed camera viewpoint, finding a match against the prototypical shape in (1) would be relatively easy algorithmically. Even your case of (4) could give you a domain of partial matching which you could heuristically determine if there was enough mountain there to consider.

余厌 2024-09-02 23:13:22

基于您已有的内容,提出一些具体建议:

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

A few specific recommendations, building upon what you've got already:

  1. Take your best image (something like image 1), run it through edge detection, open the result in any graphic editor (MS Paint will do) and clean everything except the mountain top boundary (the "chinese hat" line). This is you convolution kernel. You can crop it (not resize!) from above and below to save some time in the next step.
  2. Use the Convolve function from PerlMagick (you seem already comfortable with Perl and ImageMagick) to convolve the kernel with a few images. On the resulting image you should see a sharp spike corresponding to the "correct" position of the kernel (coinciding with the mountain in the image).
  3. The relative (to the level of surrounding noise) height of this spike will be larger when the mountain is better visible. By taking several representative images you might be able to determine a threshold that will separate good images from the bad ones.
  4. Whatever you do, there will be false positives and false negatives. Be prepared.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文