見出し画像

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のオートフォーカス制御の紹介でした。



いいなと思ったら応援しよう!