Arducam imx519のオートフォーカスをopencvで実現してみる
前回記事でimx519のマニュアルフォーカス制御を紹介しました。今回はマニュアルフォーカスとopencvを使ってソフトウェアによるオートフォーカスを実現してみたいと思います。
Picamera2から直接オートフォーカスやる方法が見つかるまでの暫定案です。他にもっと良い方法を知っている方がいれば教えてください><
やり方
当記事を最初からご覧いただいている方は、opencv関連のライブラリが追加で必要なので下記をインストールして下さい。(import cv2でエラーが出る場合)
sudo apt install -y libopenexr25
sudo apt install -y libavcodec-extra58
sudo apt install -y libavformat58
sudo apt install -y libswscale5
そしたら、以下のようなスクリプトを作成します。
(Focuser.py,v4l2_utils.pyと同じディレクトリに作成)
#2022年3月15日にpicamera2の大幅な変更があったので一部修正しました
#from picamera2 import *
from picamera2.picamera2 import *
#from null_preview import *
from time import sleep
from Focuser import Focuser
import cv2
def autofocus(f_s=0,f_e=41):
focus=0
max_val=0.0
last_val=0.0
cnt=0
for i in range(f_s,f_e):
focuser.set(Focuser.OPT_FOCUS, i*100)
sleep(0.1)
array = picam2.capture_array()
image_g = cv2.cvtColor(array, cv2.COLOR_BGRA2GRAY)
img_sobel = cv2.Sobel(image_g,cv2.CV_16U,1,1)
val=cv2.mean(img_sobel)[0]
if val > max_val:
focus=i*100
max_val = val
if val < last_val:
cnt+=1
else:
cnt=0
if cnt > 6:
focuser.set(Focuser.OPT_FOCUS, focus)
sleep(0.1)
#print(focus)
break
last_val = val
#print(val)
return focus
picam2 = Picamera2()
picam2.start_preview()
#preview = NullPreview(picam2)
preview_config = picam2.preview_configuration()
capture_config = picam2.still_configuration()
picam2.configure(preview_config)
picam2.start()
focuser = Focuser('/dev/v4l-subdev1')
sleep(2)
autofocus()
picam2.switch_mode_and_capture_file(capture_config, "test.jpg")
仕組みとしてはopencvの輪郭検出画像の輝度値平均から、フォーカスが合っているかいるかボケているかを判断してフォーカス値を決めています。
フォーカス範囲がある程度絞れている場合は、autofocusの引数f_s,f_eを使うと、より高速にオートフォーカスできます。
忙しい人向け
git clone https://github.com/ArcanaMfg/Arducam.git
python Arducam/AutoFocusTest/AutofocusTest.py
以上、imx519のオートフォーカス制御の紹介でした。