金子邦彦研究室人工知能OpenCV 4 の Python プログラムカメラのステレオマッチング(OpenCV,Python を使用)

カメラのステレオマッチング(OpenCV,Python を使用)

前準備

Python 64 ビット版のインストール,pip と setuptools の更新(Windows 上)

Windows での Python 3.10 のインストール,pip と setuptools の更新: 別ページ »で説明している.

Python の公式ページ: https://www.python.org/

Python 開発環境のインストール

opencv-python パッケージのインストール

  1. Windows では,コマンドプロン プトを管理者として実行する.
  2. opencv-python パッケージのインストール

    Windows では「python」,Ubuntu では「sudo python3 -m pip」

    python -m pip install -U opencv-python opencv-contrib-python
    

    [image]

カメラ画像の表示

パソコン接続できるビデオカメラ 2台を準備し,パソコンに接続しておく.

  1. Python プログラムの実行

    Python プログラムの実行: 別ページ »で説明

    Python のまとめ: 別ページ »にまとめ

  2. 次を実行

    OpenCV による動画表示を行う.

    import cv2
    import numpy as np
    
    v0 = cv2.VideoCapture(0)
    v1 = cv2.VideoCapture(1)
    while( ( v0.isOpened() ) and ( v1.isOpened() ) ):
        r0, bgr0 = v0.read()
        if ( r0 == False ):
            break
        r1, bgr1 = v1.read()
        if ( r1 == False ):
            break
        cv2.imshow("0", bgr0)
        cv2.imshow("1", bgr1)
        # Press Q to exit
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    v0.release()
    v1.release()
    cv2.destroyAllWindows()
    

    ※ 止めたいとき,右上の「x」をクリックしない.画面の中をクリックしてから,「q」のキーを押して閉じる

OpenCV の POC (PhaseCorrelate) を用いて、ステレオ画像の位置合わせ

ステレオ画像のうち1枚を、平行移動による位置合わせ

import cv2
import numpy as np

v0 = cv2.VideoCapture(0)
v1 = cv2.VideoCapture(1)
while( ( v0.isOpened() ) and ( v1.isOpened() ) ):
    r0, bgr0 = v0.read()
    if ( r0 == False ):
        break
    r1, bgr1 = v1.read()
    if ( r1 == False ):
        break
    mono0 = cv2.cvtColor(bgr0, cv2.COLOR_BGR2GRAY)
    mono1 = cv2.cvtColor(bgr1, cv2.COLOR_BGR2GRAY)
    f0 = np.array( mono0, dtype='float32')
    f1 = np.array( mono1, dtype='float32')
    dxdy, response = cv2.phaseCorrelate(f0, f1) 
    print(dxdy[0], dxdy[1]) 
    bgr0after = cv2.warpAffine(bgr0, np.float32([[1, 0, dxdy[0]], [0, 1, dxdy[1]]]), (f0.shape[1], f0.shape[0]))
    cv2.imshow("bgr0", bgr0)
    cv2.imshow("bgr1", bgr1)
    cv2.imshow("bgr0after", bgr0after)
    # Press Q to exit
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
v0.release()
v1.release()
cv2.destroyAllWindows()

ステレオマッチングによる距離画像の生成

OpenCV による動画表示を行う.

import cv2
import numpy as np

v0 = cv2.VideoCapture(0)
v1 = cv2.VideoCapture(1)
while( ( v0.isOpened() ) and ( v1.isOpened() ) ):
    r0, bgr0 = v0.read()
    if ( r0 == False ):
        break
    r1, bgr1 = v1.read()
    if ( r1 == False ):
        break
    mono0 = cv2.cvtColor(bgr0, cv2.COLOR_BGR2GRAY)
    mono1 = cv2.cvtColor(bgr1, cv2.COLOR_BGR2GRAY)
    f0 = np.array( mono0, dtype='float32')
    f1 = np.array( mono1, dtype='float32')
    dxdy, response = cv2.phaseCorrelate(f0, f1) 
    print(dxdy[0], dxdy[1]) 
    bgr0after = cv2.warpAffine(bgr0, np.float32([[1, 0, dxdy[0]], [0, 1, dxdy[1]]]), (bgr0.shape[1], bgr0.shape[0]))

    window_size = 3
    min_disp = 16
    num_disp = 112-min_disp
    stereo = cv2.StereoSGBM_create(minDisparity = min_disp,
        numDisparities = num_disp,
        blockSize = 8,
        P1 = 8*3*window_size**2,
        P2 = 32*3*window_size**2,
        disp12MaxDiff = 1,
        uniquenessRatio = 10,
        speckleWindowSize = 200,
        speckleRange = 1
    )
    disparity = stereo.compute(bgr0after, bgr1).astype(np.float32) / 16.0
    cv2.imshow("bgr0", bgr0)
    cv2.imshow("bgr1", bgr1)
    cv2.imshow("bgr0after", bgr0after)
    cv2.imshow('disparity', (disparity-min_disp)/num_disp)
    # Press Q to exit
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

v0.release()
v1.release()
cv2.destroyAllWindows()

[image]

※ 止めたいとき,右上の「x」をクリックしない.画面の中をクリックしてから,「q」のキーを押して閉じる