如何锁定自动对焦
How to lock autofocus
有没有办法使用任何 "standard" 库(例如 OpenCV、EmGU、DirectShow 等)来防止自动对焦?
我想让自动对焦找到最佳焦点,然后在视频拍摄过程中,防止自动对焦自动对焦。
我知道我可以手动设置值,但这违背了使用自动对焦的目的,我还没有找到一种方法来获得自动对焦确定的最佳对焦值。
您可以在校准阶段检测图像何时聚焦(当您找到最佳焦点时)并保存该配置(焦距)。然后将焦点设置为保存的值并在捕获阶段之前禁用自动对焦。要找到最佳焦距,您可以从最近的(微距)焦距开始,然后逐渐将其提高到最大,测量图像的聚焦程度。
这个SO question has an answer that describes how to measure if the image is focused or not. You can use OpenCV Laplacian() (Emgu.CV)实现那个。
The key is that in-focus image has much more strong gradients and sharp features. So what I suggest is to apply a Gaussian Laplace filter and then look at the distribution of pixel values of the result. The in-focus one has much more high values (because the image has more sharp gradients).
this article 中介绍了另一种确定最佳对焦的有趣方法。该技术用于 NASA 好奇号火星探测器。这个想法是对帧进行 JPEG 压缩,并使用 jpeg 的大小作为焦点的度量。
The autofocus command instructs the camera to move to a specified starting motor count position and collect an image, move a specified number of steps and collect another image, and keep doing so until reaching a commanded total number of images, each separated by a specified motor count increment. Each of these images is JPEG compressed (Joint Photographic Experts Group; see CCITT (1993)) with the same compression quality factor applied. The file size of each compressed image is a measure of scene detail, which is in turn a function of focus (an in-focus image shows more detail than a blurry, out of focus view of the same scene).
OpenCV imencode() (Emgu.CV) 可用于将图像压缩为 JPEG。
如果您想对焦于某个特定的稳定物体或区域,并且您能够计算/识别其固定位置,则应仅处理该区域以确定最佳对焦。在第一种方法中,您可以将 Laplacian
应用于裁剪的矩形区域,或者如果您知道对象的形状,甚至可以使用非矩形蒙版进行结果 "focus value" 计算。第二种方法也是如此 - 仅压缩您想要聚焦的感兴趣区域。如果您希望它处理的不是矩形区域并且知道该区域的形状,请首先将所有未覆盖您聚焦区域的像素设置为相同颜色。这将使算法不考虑您不需要关注的区域。
对于 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 开始,我通常 运行 v4l2-ctl
只需使用 subprocess.check_output()
。我记得看到 Windows 个 UVC 库,但从未使用过它们。
用于控制焦点的本机 Windows API 是 IAMCameraControl
与 CameraControl_Focus
属性 的接口。它可以通过 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 的设计方式可能是 auto-focus,然后读取自动确定的设置,然后切换到手动并使用此设置锁定焦点(一切都通过 IAMCameraControl
界面)。
然而,恐怕许多相机基本上仅依靠 built-in auto-focus 功能就无法实现这种足够准确的功能。首先,您无法读取正在进行自动或手动重新对焦的状态,然后在自动模式下读取当前设置可能 return 错误值(例如,最后一次在手动对焦时使用)。尽管有一个标准定义的方法来处理焦点,但它仍然没有被积极使用,并且可能工作得不够好。也许您对特定型号感兴趣,并且相机可以很好地实现这一点。
关于通过图像分析进行焦点识别,您已经在相邻答案中找到了指针。
有没有办法使用任何 "standard" 库(例如 OpenCV、EmGU、DirectShow 等)来防止自动对焦?
我想让自动对焦找到最佳焦点,然后在视频拍摄过程中,防止自动对焦自动对焦。
我知道我可以手动设置值,但这违背了使用自动对焦的目的,我还没有找到一种方法来获得自动对焦确定的最佳对焦值。
您可以在校准阶段检测图像何时聚焦(当您找到最佳焦点时)并保存该配置(焦距)。然后将焦点设置为保存的值并在捕获阶段之前禁用自动对焦。要找到最佳焦距,您可以从最近的(微距)焦距开始,然后逐渐将其提高到最大,测量图像的聚焦程度。
这个SO question has an answer that describes how to measure if the image is focused or not. You can use OpenCV Laplacian() (Emgu.CV)实现那个。
The key is that in-focus image has much more strong gradients and sharp features. So what I suggest is to apply a Gaussian Laplace filter and then look at the distribution of pixel values of the result. The in-focus one has much more high values (because the image has more sharp gradients).
this article 中介绍了另一种确定最佳对焦的有趣方法。该技术用于 NASA 好奇号火星探测器。这个想法是对帧进行 JPEG 压缩,并使用 jpeg 的大小作为焦点的度量。
The autofocus command instructs the camera to move to a specified starting motor count position and collect an image, move a specified number of steps and collect another image, and keep doing so until reaching a commanded total number of images, each separated by a specified motor count increment. Each of these images is JPEG compressed (Joint Photographic Experts Group; see CCITT (1993)) with the same compression quality factor applied. The file size of each compressed image is a measure of scene detail, which is in turn a function of focus (an in-focus image shows more detail than a blurry, out of focus view of the same scene).
OpenCV imencode() (Emgu.CV) 可用于将图像压缩为 JPEG。
如果您想对焦于某个特定的稳定物体或区域,并且您能够计算/识别其固定位置,则应仅处理该区域以确定最佳对焦。在第一种方法中,您可以将 Laplacian
应用于裁剪的矩形区域,或者如果您知道对象的形状,甚至可以使用非矩形蒙版进行结果 "focus value" 计算。第二种方法也是如此 - 仅压缩您想要聚焦的感兴趣区域。如果您希望它处理的不是矩形区域并且知道该区域的形状,请首先将所有未覆盖您聚焦区域的像素设置为相同颜色。这将使算法不考虑您不需要关注的区域。
对于 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 开始,我通常 运行 v4l2-ctl
只需使用 subprocess.check_output()
。我记得看到 Windows 个 UVC 库,但从未使用过它们。
用于控制焦点的本机 Windows API 是 IAMCameraControl
与 CameraControl_Focus
属性 的接口。它可以通过 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 的设计方式可能是 auto-focus,然后读取自动确定的设置,然后切换到手动并使用此设置锁定焦点(一切都通过 IAMCameraControl
界面)。
然而,恐怕许多相机基本上仅依靠 built-in auto-focus 功能就无法实现这种足够准确的功能。首先,您无法读取正在进行自动或手动重新对焦的状态,然后在自动模式下读取当前设置可能 return 错误值(例如,最后一次在手动对焦时使用)。尽管有一个标准定义的方法来处理焦点,但它仍然没有被积极使用,并且可能工作得不够好。也许您对特定型号感兴趣,并且相机可以很好地实现这一点。
关于通过图像分析进行焦点识别,您已经在相邻答案中找到了指针。