图像焦点计算

18

我正在尝试为一些测试自动化工作开发图像对焦算法。我选择使用 AForge.net,因为它似乎是一个不错的成熟的 .net 友好系统。

不幸的是,我找不到有关从头开始构建自动对焦算法的信息,所以我尽力了:

获取图像。应用 Sobel 边缘检测滤镜,生成灰度边缘轮廓。生成直方图并保存标准差。将相机向主体移动一步,并拍摄另一张照片。如果标准偏差小于上一个,则表示我们正在变得更加聚焦。否则,我们已经超过了拍摄照片的最佳距离。

还有更好的方法吗?

更新:顺便说一下,这个方法存在严重漏洞。当我超过最佳焦点时,“图像聚焦”值仍然在增长。在距离/焦点值方面,您期望看到一个类似抛物线的函数,但实际上会得到更接近对数函数的东西。

更新2:好吧,我回到这个问题上来了,我们现在正在探索的方法是,给定几个已知的边缘(好吧,我确切地知道图片中的物体是什么),我进行手动像素强度比较。当结果图形变得更加陡峭时,我就会更加聚焦。一旦核心算法从 matlab 被移植到 c# 中,我将发布代码(是的,matlab..:S)。

更新3:最终更新,回到这个问题上来了。最终代码如下:

步骤1:从图像列表中获取图像(我通过聚焦点拍摄了一百张照片)

步骤2:找出我正在关注的对象的一个边缘(在我的情况下,它是一个始终在同一位置的矩形对象,因此我裁剪了一个高而窄的矩形边缘)

步骤3:为该裁剪图像获得 HorizontalIntensityStatistics(Aforge.net 类)

步骤4:获得直方图(在我的情况下是灰度图)

步骤5:找到直方图值的导数

步骤6:斜率最大时,即为最聚焦点。


我认为你至少走在了正确的道路上。如果我没记错,数码相机中的自动对焦也是类似的。 - Hannes Ovrén
我昨晚意识到当我实际使用一台具有自动对焦功能的相机时。工作中的那台相机本质上是一个愚蠢的针孔。当自动对焦被启用时,通常可以听到嗡嗡声。这是相机在不同距离上取样并猜测最佳距离。 - Oren Mazor
7个回答

10

您可以查看NASA好奇号火星探测器中使用的技术。

该技术在这篇文章中有描述。

文章可作为PDF文件获取。

引用文章内容:

7.2.2 自动对焦

预计自动对焦将是MAHLI在火星上对焦的主要方法。自动对焦命令指示相机移动到指定的起始电机计数位置并收集一幅图像,移动指定数量的步骤并再次收集图像,并不断重复直到达到指定的总图像数,每个图像之间由指定的电机计数增量分隔。每个图像都采用JPEG压缩(Joint Photographic Experts Group;参见CCITT(1993)),应用相同的压缩质量因子。每个压缩的图像文件大小是场景细节的度量,而场景细节又是对焦的函数(对焦良好的图像比模糊的、不对焦的场景视图显示更多的细节)。如图23所示,相机确定了JPEG文件大小与电机计数之间的关系,并对三个相邻的最大文件大小拟合一个抛物线。抛物线的顶点提供了最佳对焦电机计数位置的估计。在确定了这一点之后,MAHLI将镜头对焦组移动到最佳电机位置并获取一幅图像;此图像将被存储,用于确定自动对焦位置的早期图像不会被保存。

自动对焦可以在整个

整个 MAHLI 视场都可以进行自动对焦,也可以对应包含待研究物体的场景子帧进行自动对焦。根据主体性质和 MAHLI 机械臂定位不确定性的了解程度,用户可能会选择获取中心自动对焦子帧,或者如果位置知识足以确定子帧应该位于何处,则可以选择非中心自动对焦子帧。强烈建议使用子帧执行自动对焦,因为这通常会使主体的聚焦效果更好,而不是将自动对焦应用于整个 CCD;此外,使用子帧进行自动对焦产生的电机计数位置通常会更准确地确定像素尺度下的工作距离。

以下是图23:

NASA Curiosity 火星探测器中的自动对焦

这个想法也在这个回答中提出:https://dev59.com/OnI95IYBdhLWcg3w1BlN#2173259


5
可能对您的需求来说有些简单,但我使用了一个简单的算法,它查看相邻像素之间的差异,并且获得了良好的结果。相隔2个像素的像素差的总和似乎是图像对比度的合理度量。我找不到70年代Brenner的原始论文,但在http://www2.die.upm.es/im/papers/Autofocus.pdf中提到了它。
另一个问题是当图像极度模糊时,很少有对焦信息,因此很难判断哪个方向是“向前移动”的或避免局部最大值。

你提到的最后一点是我在上周五遇到的问题,当时我的相机距离芯片太远了。后来我想到,为了获得最佳对焦效果,我需要始终保持相同的高度,因此我需要从略微模糊的图像转换为清晰的图像。顺便说一下,那篇文章非常棒。特别是因为拍摄微生物的过程与拍摄芯片非常相似,而这正是我正在做的事情。 - Oren Mazor
@Stew BRENNER,John F.等。细胞学研究的自动显微镜初步评估。《组织化学与细胞化学杂志》,1976年,24.1:100-111。http://jhc.sagepub.com/content/24/1/100.full.pdf - Alessandro Jacopson

4
我没有亲自构建过,但我的第一个想法是对图像的一部分进行2D DFT。当失焦时,高频率将自动消失。
对于懒人原型,您可以尝试使用JPEG(高质量)压缩图像的区域,并查看输出流的大小。大文件意味着有很多细节,这又意味着图像是清晰的。请注意,相机不应太嘈杂,并且您当然不能在不同场景之间比较文件大小。

原型的想法太棒了!不错。 - joonas.fi

3

这可能会有所帮助。这是相机自动对焦系统实际工作的方式-被动自动对焦

对比度测量

通过镜头在传感器范围内测量对比度,实现了对比度测量。传感器相邻像素之间的强度差异随着图像正确对焦而自然增加。因此,光学系统可以调整直到检测到最大对比度。在这种方法中,自动对焦根本不涉及实际距离测量,并且通常比相位检测系统慢,特别是在昏暗的情况下操作。但由于它不使用单独的传感器,因此对比度检测自动对焦可以更加灵活(因为它是软件实现的),并且可能更准确。这是视频摄像机和消费级数码相机中常用的方法,它们缺乏快门和反射镜。一些数码单反相机(包括Olympus E-420、Panasonic L10、Nikon D90、Nikon D5000、Nikon D300三脚架模式、Canon EOS 5D Mark II、Canon EOS 50D)在其实时取景模式下使用此方法进行对焦。一种新的可换镜头系统Micro Four Thirds专门使用对比度测量自动对焦,并据说提供与相位检测系统相当的性能。


像素之间的强度差非常接近于Sobel操作所给出的值。 - kenny

1

尽管Sobel是一个不错的选择,但我可能会选择在几个小的代表性区域中对x和y方向上的投影进行边缘幅度计算。另一个基于OpenCV的.NET友好选择是 @http://www.emgu.com/wiki/index.php/Main_Page


我没有意识到OpenCV是.NET。我想我错误地认为它是C++,然后就没有继续研究了(为自己辩护,这项研究是由别人开始的)。 - Oren Mazor
这是C/C++代码,但链接提供的是DLL的C#包装器。 - kenny

0

另一种聚焦度量的方法可能是:

获取多张图像并对它们进行平均(降噪)。 然后对平均图像进行FFT,并使用高频到低频能量比。 这个比值越高,聚焦度就越好。Matlab演示可用(不包括平均阶段)在工具箱的演示中 :)


0

我在想标准差是否是最好的选择:如果图像变得更加清晰,Sobel滤波器图像将在边缘处包含更亮的像素,但同时也会有更少的亮像素,因为边缘变得更薄。也许你可以尝试使用Sobel图像中排名前1%的最高像素值的平均值?


按照同样的逻辑,我选择使用标准差。图像越清晰,对比度越高,直方图中的变化就越少。如果我获取一些最高像素值(即获取最亮的点),那么这只会告诉我在这张图片上有多少个亮点相对于所有其他点。也就是说,图表会发生滑动: 聚焦拍摄:平均值=23,标准差=15 稍微失焦:平均值=27,标准差=16 非常失焦:平均值=40,标准差=20 - Oren Mazor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接