Raspberry Pi 4のカメラのマニュアルフォーカスをテストしてみると…注意点がありました(Python、picamera2)

 以前picamera2でカメラのオートフォーカスを試してみました:

Picamera2.set_controlsメソッドでAfModeをAutoもしくはContinuousに設定すると自動的にきゅいきゅいピントを合わせてくれます。

マニュアルフォーカス

 一方で時にマニュアルでピントを調整したい時もあります。例えば同じ距離にあるのが分かっている対象物(工場のラインを流れる物、監視カメラ)などは何かのはずみで勝手にピントがずれるとかえって困るんですね。オートフォーカスはたまにピントがずれたまま違う世界に旅立ってしまう事もありますのでw

 picamera2でオートフォーカスモードをマニュアルに設定するには、Picamera2.set_contorlsにキーをAfMode、値をControls.AfModeEnum.Manualにセットします。簡単なサンプルはこちらです:

#オートフォーカスモードをマニュアルに設定

from picamera2 import Picamera2, Preview
from libcamera import controls
import time

pc2 = Picamera2()

pc2.start_preview( True )

# start後じゃないとset_controlsは動作しない
pc2.start()

# オートフォーカスモードをManualに設定
pc2.set_controls( {"AfMode" : controls.AfModeEnum.Manual} )

# 焦点距離を8cm(0.08m)に設定
#  1/距離で与える
pc2.set_controls( {"LensPosition" : 1.0 / 0.08 } )

time.sleep( 10 )

 マニュアルなのでピントを合わせる何らかの調整値を追加で与える必要があります。それがLensPositionで、同じくset_controlsメソッドに指定します。

 picamera2のリファレンスによると、与える値は距離(m)の逆数との事。これは専門用語で「ディオプトリ(dioptre)」と言うそうです。老眼鏡の度数表示は実はこれです。なのでお店の数値の逆数を取ればどのくらいの距離でピントが合うレンズかおおよそ分かります。

 おっと閑話休題。上の例では焦点距離を8cm(0.08m)としています。これで実際に撮影してみると、

おお、8cmでピントしっかり合っています。これ電池を10cmの位置に話すとピンボケするので僕の取り付けたカメラ(ArduCam製64MP Hawk-eye)は近距離は中々の精度が出ているようです。ただし大いなる注意があります。

焦点距離はあくまで「概算値」で設定どおりにはほぼならない事に注意

 上のコードを作って気を良くした僕は、次に焦点距離を20cm(0.2m)に設定して試してみました。すると、

あれ~?ピンボケも甚だしい…。近距離側にピントが無いので、かなり遠方に焦点が合ってしまっています。実際20cmのピントが合ったのは、LensPositionに1.0/0.12、つまり12cmと指定した時でした。

同じ様に測定距離と設定距離とを色々試した所、対象物までの距離と設定値とは正直「全然対応していない」のがわかりました。えーー!ですww

picamera2のリファレンスのLensPositionを説明している所に次の一文があります:

「In general, users should expect the distance calibrations to be approximate as it will depend on the accuracy of the tuning and the degree of variation between the user’s module and the module for which the calibration was performed.」
(一般にこの機能が概算値である事を想定して下さい。ご使用のカメラモジュールの精度やそのモジュールの調整によって決まります。)

The Picamera2 Library: 5.2.3. Setting the Lens Position Manually
https://datasheets.raspberrypi.com/camera/picamera2-manual.pdf

つまりそういう事のようです(-_-;;。ですから、例えば「焦点距離を指定の距離に合わせる」という機能を作る場合は取り付けているそのカメラが持つ特性に合わせてその値を文字通りマニュアルで調整しないといけないのです。

Picamera2のマニュアルフォーカスとの付き合い方

 僕がテストした範囲ですが、Picamera2のマニュアルフォーカスに与える値は取り付けているカメラモジュールに完全に依存した設定値になりそうです。

 例えば僕のラズパイに取り付けたArduCam製の64MP Hawk-eyeカメラの場合、カメラの性能限界である8cm近辺のピントであれば1.0/0.08でジャストでしたが、以後は、

こんな感じで対象物の距離が20cmにもなればもう設定距離と対応がつかなくなってしまいました。そして設定距離を0.3以上にするとカメラのフォーカス自体が限界距離辺りになり、それ以上の値ではフォーカス機構が動かないという結果になりました。

 以上の事から、Picamera2のマニュアルフォーカスは次のような扱い方になるかと思います:

  1. LensPositionにカメラのスペック表にある最も近い焦点距離(m)に対応した逆数を与える(Near=1.0/0.08など)。おそらくこれは動くはず。

  2. 少しずつ対象物の距離を離していき、それに対応した設定距離をメモる(上の表のようなものが出来るはず)

  3. カメラのフォーカス機能が反応しなくなる限界遠距離設定値をテストする。僕のカメラの場合は0.3m(Far=1.0/0.3)

  4. Near~Farの間でピントが合う位置を調整するようなアプリケーションを作る。可能であれば値を関数で近似するようにして、指定距離に該当する設定距離を求める、とかする。

 4番について、対象距離に対する設定距離を細かくプロットしていくと、おおよその関係性が見えてきます。そのプロットを再現できるような適当な関数(多分対数関数になります)を当てはめてあげれば、任意の対象距離に対する設定距離を割り出せます。僕のカメラで実際粗くプロットしたグラフがこちら:

横軸が対象物までの距離(焦点距離)、縦軸がLensPositionに設定したピントが合っていそうな値です。これにフィットする関数を求めてあげれば潰しが利きそうです。

 次回はこの辺りを少し加味しつつ、マニュアルフォーカスの駆動範囲内でピントを動的に調整できるような簡易なGUIアプリを作ってみたいと思います。GUIで機器を動かすというインタラクティブが出来ると、ラズパイは俄然楽しくなるのです!

ではまた(^-^)/

<次回>

この記事が気に入ったらサポートをしてみませんか?