如何锁定自动对焦

Posted

技术标签:

【中文标题】如何锁定自动对焦【英文标题】:How to lock autofocus 【发布时间】:2019-09-19 06:19:27 【问题描述】:

有没有办法使用任何“标准”库(例如 OpenCV、EmGU、DirectShow 等)来防止自动对焦?

我希望自动对焦找到最佳对焦,然后在视频拍摄期间,防止自动对焦自动对焦。

我知道我可以手动设置该值,但这违背了使用自动对焦的目的,而且我还没有找到一种方法来获得由自动对焦确定的最佳对焦值。

【问题讨论】:

可以使用相机的自动对焦来找到最佳对焦然后锁定。你仍然对这种方法感兴趣吗? (我看到你接受了奥利奥特的回答。)你使用 USB 网络摄像头吗? 这就是整个问题。如何锁定最佳焦点。无法找到通过自动对焦获得的最佳手动对焦值。 我的网络摄像头似乎有办法。稍后发布。 @UlrichStern 在某些情况下,相机本机自动对焦可能不适合。我不知道 RickInWestPalmBeach 是否属于这种情况。我更新了我的答案并涵盖了我们想要聚焦的对象很小/具有复杂形状/不居中位置(这将使本机自动对焦最有可能失败)的情况。 @Oliort,我认为我们的两个解决方案都很好。我通常不喜欢重新实现已经存在的功能(特别是如果它看起来运行良好),但我同意基于 UVC 的解决方案也有缺点(便携性等)。 【参考方案1】:

对于与UVC 兼容的 USB 网络摄像头(大多数都兼容),有合理的机会可以使用摄像头的自动对焦然后将其锁定。要确定相机是否允许通过 UVC 进行此操作,在 Linux 上可以使用 v4l2-ctl,它位于包 v4l-utils 中。 v4l2-ctl -l 列出所有可用控件,v4l2-ctl -c 设置控件的值,v4l2-ctl -C 获取值。

例如,以下命令对 Ubuntu 16.04 机器上的 Microsoft LifeCam Cinema 起到了作用,该机器运行了一个简单的 Python OpenCV 程序来显示当前帧:

> v4l2-ctl -d 0 -c focus_auto=1
> v4l2-ctl -d 0 -C focus_absolute
focus_absolute: 12

将对象移近相机后,焦点发生了变化,我得到了 focus_absolute 的不同值:(因此 UVC 可以访问自动对焦选择的值。)

> v4l2-ctl -d 0 -C focus_absolute
focus_absolute: 17

然后我改为手动对焦,这锁定了自动对焦选择的值:

> v4l2-ctl -d 0 -c focus_auto=0
> v4l2-ctl -d 0 -C focus_absolute
focus_absolute: 17

因此,对于 LifeCam Cinema,代码唯一需要做的就是将 focus_auto 控件最初更改为自动 (1),然后在锁定焦点后更改为手动。

在 Python 中,我通常只需使用 subprocess.check_output() 即可运行 v4l2-ctl。我记得看到过用于 UVC 的 Windows 库,但从未使用过它们。

【讨论】:

罗技 Brio 也得到了确认。您也可以使用-c focus_absolute= 设置关闭自动对焦后的对焦级别(-c focus_auto=0)。可惜视角无法控制。 列出了来自同一项目的其他可帮助您诊断问题的实用程序here,例如v4l2-compliance 似乎有一个等效的 API 使用库 libv4l,您可以将其安装为 linux 包。 pypi.org/project/PyV4L2Camera 等项目使用它并根据 linux 风格给出包名称。该库的文档在其头文件中内联:libv4l2.h,您可以在根据您的 linux 风格安装软件包后获得该文件,但是它是实用程序提供的较低级别的接口,因此最好遵循命令行实用程序的代码我猜是为了针对那个库进行开发。【参考方案2】:

您可以在校准阶段检测图像何时聚焦(当您找到最佳焦点时)并保存该配置(焦距)。然后将焦点设置为保存的值并在捕获阶段之前禁用自动对焦。要找到最佳焦距,您可以从最接近(宏观)的焦距开始,然后逐渐将其提高到最大,测量图像的聚焦程度。

这个SO question 有一个答案,描述了如何测量图像是否聚焦。您可以使用OpenCV Laplacian() (Emgu.CV) 来实现。

关键是对焦图像具有更强烈的渐变和清晰的特征。所以我的建议是应用高斯拉普拉斯滤波器,然后查看结果的像素值分布。对焦时的值更高(因为图像具有更锐利的渐变)。

this article 中描述了另一种确定最佳焦点的有趣方法。该技术用于美国宇航局好奇号火星探测器。这个想法是对帧进行 JPEG 压缩并使用 jpeg 的大小作为焦点的度量。

自动对焦命令指示相机移动到指定的起始电机计数位置并收集图像,移动指定的步数并收集另一张图像,并继续这样做直到达到命令的图像总数,每个图像由指定的电机计数增量。这些图像中的每一个都是 JPEG 压缩的(联合图像专家组;参见 CCITT (1993)),并应用了相同的压缩质量因子。每个压缩图像的文件大小是衡量场景细节的指标,而这又是焦点的函数(焦点对准的图像比同一场景的模糊、失焦视图显示更多细节)。

OpenCV imencode() (Emgu.CV) 可用于将图像压缩为 JPEG。

如果您想专注于某个特定的稳定对象或区域并且您能够计算/识别其固定位置,您应该只处理该区域以确定最佳焦点。在第一种方法中,您可以将Laplacian 应用于裁剪的矩形区域,如果您知道对象的形状,甚至可以不使用矩形蒙版进行结果“焦点值”计算。第二种方法也是如此 - 仅压缩您想要关注的感兴趣区域。如果您希望它处理非矩形区域并知道该区域的形状,请首先将所有不覆盖您关注的区域的像素设置为相同的颜色。这将使算法不考虑您不需要关注的区域。

【讨论】:

【参考方案3】:

用于控制焦点的本机 Windows API 是带有 CameraControl_Focus 属性的 IAMCameraControl 接口。它可以通过 DirectShow 获得,并且很可能(我没有检查,但我希望它按原样存在)也可以通过 Media Foundation 获得。问题第一段中提到的库在这些 API 之上工作。

例如,罗技高清网络摄像头 C615 摄像头(随机抓取了第一个带有对焦功能的摄像头)就在对焦方面提供了这样的功能:

CameraControl_Focus:51,标志CameraControl_Flags_Auto | CameraControl_Flags_Manual,0..255,第 17 步,默认 51,上限标志 CameraControl_Flags_Auto | CameraControl_Flags_Manual

这表明范围为0..255,增量为17,即相机具有16个设置范围内的自动对焦和手动对焦。 API 的设计方式是可以潜在地自动对焦,然后读取自动确定的设置,然后切换到手动,此设置锁定焦点(一切都通过IAMCameraControl 接口)。

然而,恐怕很多相机并没有足够准确地实现这一点,基本上只是依靠内置的自动对焦功能。首先,您无法读取正在进行自动或手动重新对焦的状态,然后在自动模式下读取当前设置可能会返回错误值(例如在手动对焦期间最后一次使用)。即使有一种标准定义的方式来处理焦点,它仍然没有被积极使用,并且可能效果不够好。也许您对特定模型感兴趣,而相机很好地实现了这一点。

关于通过图像分析识别焦点,您已经在相邻答案中找到了指针。

【讨论】:

以上是关于如何锁定自动对焦的主要内容,如果未能解决你的问题,请参考以下文章

oracle帐户老是自动被锁定

使用 xcode 安装应用程序时如何允许 iPhone 自动锁定?

如何在 MPMoviePlayer 播放期间启用 iPhone 自动锁定?

Win10 如何设置自动锁定屏幕

如何使用VBscript防止XP机器的自动锁定功能

如何在应用程序处于前台模式时禁用 iPhone/iPad 自动锁定?