以前にapt-getを使ってopenCVをインストールしていましたが、これでインストールされるのはpython2系だそうです。
python2系のインストールコマンド
sudo apt-get install python-opencv
python3でカメラを使うにはpip3を使うそうです。
sudo pip3 install opencv-python
しかし、ソース上の
import cv2
これだけでエラーが出ました。
エラー内容
ImportError: libcblas.so.3: cannot open shared object file: No such file or directory
ググるとこちらの記事がヒットしました。
こちらの記事の通り不足しているライブラリをインストールします。
sudo apt-get install libatlas-base-dev
上記の記事は他にもいろいろライブラリを入れていますが僕の環境の場合はこれだけでpython3でopenCVが使えるようになりました。
さて、問題はカメラの方です。
ls -la /dev/v4l/by-pathとlsusbコマンドでデバイスの確認
カメラ無接続
カメラ1台接続
カメラ2台接続
デバイスが1つ増えるごとにvideoの番号が2つ増えています。
理屈はよく解りませんが、左右のカメラをopenCVで取得するには増えた番号の先頭である0と2をインデックス番号として
cap_L = cv2.VideoCapture(0)
cap_R = cv2.VideoCapture(2)
とすれば良いだけのようです。
しかし、これ起動ごとに左右入れ替わることは無いのだろうか?
と思って再起動すると・・・
えええ???
2台目が認識されていません!!
テストで2台の画像を取得していたコードもエラー出現!
[ WARN:0] global /tmp/pip-wheel-qd18ncao/opencv-python/opencv/modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video2): can't open camera by index
Traceback (most recent call last):
File "camera.py", line 60, in <module>
caps()
File "camera.py", line 46, in caps
cv2.imwrite(path_R, frame_R) # ファイル保存
cv2.error: OpenCV(4.5.1) /tmp/pip-wheel-qd18ncao/opencv-python/opencv/modules/imgcodecs/src/loadsave.cpp:753: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'
画像が無いので保存出来ませんよというエラーです。
ははーん、どうやらUSBの接続に問題があるようです。
そこで、こちらの記事を参考にソフトウェア的にUSBの電源を一度OFFにしてONにすることでUSB接続の情報をリセットが出来るかも?と試してみました。
スクリプトも書きました。
### usb_rebind.py ###
#!/usr/bin/python
#coding:utf-8import subprocess
import timedef off():
subprocess.call('sudo sh -c "echo -n \"1-1\" > /sys/bus/usb/drivers/usb/unbind"',shell=True )def on():
subprocess.call('sudo sh -c "echo -n \"1-1\" > /sys/bus/usb/drivers/usb/bind"',shell=True )if __name__=='__main__': # if script
off()
time.sleep(3)
on()
結果、ダメでした orz...。
試しにUSBハブに2台繋いで同時に接続してみても認識しません。
別々で繋ぐと認識出来ます。おそらくカメラの相性ですね。
・・・困りました。(ーー;ムムム。。。
ということで、物理的に切断&接続するという暴挙に出ます。
USBケーブルのここを切り、手持ちのFETでGNDに落とします。(推奨しません)
回路
FETはNchパワーMOSFET 2SK4017(Q) (60V5A)を使用しました。
この回路の状態で試しにマウスを接続して起動させると、なんと信号線をGNDとしてマウスが普通に使えてしまいました orzやっぱりか。。。
しかし、純粋にUSBカットは出来ないようですが、カメラを繋いでON-OFF-ONと繰り返すと電圧差の加減なのかカメラのOFF→ONは出来ました。(これもカメラの相性があるかもしれません。)
スクリプトには
time.sleep(3)
on()
time.sleep(1)
off()
time.sleep(1)
on()
print('USB-3 RESET')
while True:
time.sleep(60)
と書いてサービスに登録、ラズパイ起動3秒後にon-off-onとさせます。
GPIOの制御は基本のLチカですので割愛します。
これでやっとカメラ2台を認識するようになりました。
信号線にGNDが流れてしまうのでラズパイの回路には優しくないと思うので推奨はしませんが、今回はこんな方法で認識しましたという報告でした。
以上です。
<参考>