2023-简单点-picamera2中的取消auto focus,进行手动焦距设定
Auto Focus
- 什么是auto focus?简介
- picamera2支持的 Auto Focus state
- Auto
- Manual手动模式下的重要参数 lens position
- 未完待续。。
- Af Wondows参数
什么是auto focus?简介
一个像素有两个 前置并列透镜阵列,左右可以纠正相位差
参考
picamera2支持的 Auto Focus state
简而言之,就三种模式:
1.Manual
2.Auto
3.Continuous
自动对焦(AF)状态机有3种模式:
可以通过读取每张图像返回的“AfState”元数据来监控其在每种模式下的活动。
三种模式是:
- mannual手动:镜头永远不会自动移动,但“镜头位置”控制可以用来“手动”移动镜头。
这个控制的单位是屈光度(1 /米,单位),所以零可以用来表示“无穷大”。
“镜头位置”也可以在图像元数据中进行监控,并将指示镜头何时到达请求的位置。 - auto自动:在这种模式下,“后触发”控制可用于启动一个自动对焦循环。可以检查与图像一起接收的“AfState”元数据,以确定它何时完成以及是否成功,尽管我们建议使用辅助函数,使用户不必实现此操作。在这种模式下,镜头也永远不会自动移动,直到它被应用程序“触发”。
- 连续Continuous-自动对焦算法将连续运行,并在必要时自动重新对焦。应用程序可以根据需要在这些模式之间自由切换。
Auto
from picamera2 import Picamera2
from libcamera import controls
picam2 = Picamera2()
picam2.start(show_preview=True)
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
Manual手动模式下的重要参数 lens position
from picamera2 import Picamera2
from libcamera import controls
picam2 = Picamera2()
picam2.start(show_preview=True)
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual, "LensPosition": 0.0})
lens position control( picam2.camera_controls['LensPosition']
)给出三个值,即最小、最大和默认镜头位置。
- 最小值定义了 最远的焦距,
- 最大值指定了 最近的可实现的焦距(通过取其倒数)。
- 第三个值给出了一个“默认”值,这通常是镜头的超焦位置。
透镜位置的最小值通常为0.0(表示无穷大)。
对于最大值,一个值为10.0将表示最近的焦距为1 / 10米,或10厘米。
默认值通常可能在0.5到1.0左右,这意味着超焦距离约为1到2米。
一般来说,用户应该期望距离校准是近似的,因为它将取决于调整的准确性和用户的模块和执行校准的模块之间的变化程度。
特别注意:lensPosition 中设置的屈光度(焦距的倒数)是近似值,根本不能信任这种东西
实际上,对应关系可能是这样的
具体可以参考:这个
这里直接给出gui调焦的代码:
from picamera2 import Picamera2
import time
from libcamera import controls
def getVideo(duration,name="test.mp4"):
picam2 = Picamera2()
#picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual, "LensPosition": 7.53})
video_config = picam2.create_video_configuration(main={"size": (1080, 720)})
picam2.configure(video_config)
picam2.start_and_record_video(name, duration=duration,config=video_config)
def getStill(nums):
picam2 = Picamera2()
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual, "LensPosition": 7.53})
#picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
config = picam2.create_still_configuration()
picam2.configure(config)
picam2.start()
time.sleep(2)
i = 1
while i <= nums:
picam2.capture_file(f"{i}.jpg")
i += 1
def getPreview():
from picamera2 import Picamera2
picam2 = Picamera2()
config = picam2.create_preview_configuration(main={"size":(1080,720)})
picam2.configure(config)
picam2.start(show_preview=True)
picam2.set_controls({"AfMode": controls.AfModeEnum.Manual,
"LensPosition": 7.53,
})
time.sleep(100)
picam2.stop()
def autoAdjust():
from picamera2 import Picamera2
from libcamera import controls
import tkinter
import math
pc2 = Picamera2()
# 焦距调节参数
N = 0.08 # 最近焦点距離(m)
M = 0.25 # 中間焦点距離(m)
F = 1.0 # 最遠焦点距離(m)
IN = 1.0 / N
IM = 1.0 / M
IF = 1.0 / F
# 将滑块的值转换为焦距
def convSliderToFocusLen( t ):
a = ( IM - IF ) / ( 2.0 * IM - IN - IF )
b = a * ( 1.0 - 2.0 * a ) * ( IM - IN )
c = IN + b / a
ID = b / ( t - a ) + c # 1/Dなので注意
return 1.0 / ID
# 将焦距转换为设定距离
def convFocusLenToSetLen( focusLen ) :
Px = 0.2 # 焦点距離Px
Py = 0.12 # 焦点距離Py
Qx = 1.0 # 基准焦距设定距離Qx
Qy = 0.16 # 基准焦距设定距離Qy
bP = ( Py - N ) / ( Px - N )
bQ = ( Qy - N ) / ( Qx - N )
a = ( bQ * Qx - bP * Px ) / ( bQ - bP )
b = ( Px - a ) * ( N - a ) * ( Py - N ) / ( N - Px )
c = N - b / ( N - a )
return b / ( focusLen - a ) + c
# 给相机设定手动对焦距离
def setFocusLen( focusLen ):
# 将焦距转换为设定距离
setLen = convFocusLenToSetLen( focusLen )
# 给照相机设定设定距离
pc2.set_controls( {"LensPosition" : 1.0 / setLen} )
# 焦点距离表示
label["text"] = "{:.4f}m".format( focusLen )
print(f"current parm: {1.0 / setLen}")
# 滑块变更的回调
def onChangeSlider( event ):
focusLen = convSliderToFocusLen( slider.get() )
setFocusLen( focusLen )
# 主窗口
root = tkinter.Tk()
root.title( "Camera manual focus test" )
# 追加焦距调整滑块
sliderLen = 250
sliderWidth = 15
slider = tkinter.Scale(
root,
orient = tkinter.HORIZONTAL, # 水平滑块
from_ = 0.0, to = 1.0, # 0〜1之间
resolution = 0.01, # 0.01步宽
length = sliderLen, # 滑块的长度
width = sliderWidth, # 滑块的宽度
showvalue = 0, # 不显示值
command = onChangeSlider #注册值改变时被调用的函数
initFocusPos = 0.5
slider.set( initFocusPos ); #初始值
slider.place( x = 30, y = 20 )
# 焦距标示标签
label = tkinter.Label( root )
label.place( x = 34 + sliderLen, y = 5 + sliderWidth )
# 相机初始化
# 显示预览,将自动聚焦模式设置为Manual pc2.start_preview( True )
pc2.start()
pc2.set_controls( {"AfMode" : controls.AfModeEnum.Manual} )
# 循环开始
root.mainloop()
if __name__ == "__main__":
#getVideo(5)
#getStill(3)
#getPreview()
autoAdjust()
print(f"current parm: {1.0 / setLen}")
这个会给出设置的lensposition
滑块拖动修改参数,
实时获得结果,看上面print(f"current parm: {1.0 / setLen}")
打印的结果,然后手动设置参数picam2.set_controls({"AfMode": controls.AfModeEnum.Manual, "LensPosition":参数})
未完待续。。
Af Wondows参数
设置用来定焦的图片区域