- macOS Sierra 10.12.6
- Python 3.7.1
必要でなければ仮想環境を作成せずに直接 pip から opencv をインストールして問題ない。 今回は自分の環境に複数のバージョンのPythonが混在している為、仮想環境を用いて動作確認を行った。
~/s/g/i/opencv_sample pipenv install --python 3.7.1
Creating a virtualenv for this project…
Pipfile: /Users/iorionda/src/github.com/iorionda/opencv_sample/Pipfile
Using /Users/iorionda/.pyenv/versions/3.7.1/bin/python (3.7.1) to create virtualenv…
⠏ Creating virtual environment...Using base prefix '/Users/iorionda/.pyenv/versions/3.7.1'
New python executable in /Users/iorionda/.local/share/virtualenvs/opencv_sample-M5HMqQ7v/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /Users/iorionda/.pyenv/versions/3.7.1/bin/python
✔ Successfully created virtual environment!
Virtualenv location: /Users/iorionda/.local/share/virtualenvs/opencv_sample-M5HMqQ7v
Creating a Pipfile for this project…
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (a65489)!
Installing dependencies from Pipfile.lock (a65489)…
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
~/s/g/i/opencv_sample pipenv shell
Launching subshell in virtual environment…
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
~/s/g/i/opencv_sample source /Users/iorionda/.local/share/virtualenvs/opencv_sample-M5HMqQ7v/bin/activate.fish
(opencv_sample) opencv_sample-M5HMqQ7v ~/s/g/i/opencv_sample python -V
Python 3.7.1
(opencv_sample) opencv_sample-M5HMqQ7v ~/s/g/i/opencv_sample pipenv install opencv-python
Installing opencv-python…
Adding opencv-python to Pipfile's [packages]…
✔ Installation Succeeded
Pipfile.lock (4f8333) out of date, updating to (a65489)…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✔ Success!
Updated Pipfile.lock (4f8333)!
Installing dependencies from Pipfile.lock (4f8333)…
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 2/2 — 00:00:01
$pipenv run python
Python 3.7.1 (default, Dec 26 2018, 22:14:57)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'4.0.0'
>>>
>>> import cv2
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> img = cv2.imread(<image_file_path>)
>>> edges = cv2.Canny(img, 150, 200)
>>> cv2.imwrite('/Users/iorionda/Desktop/P8270171_edges.jpg', edges)
ヒステリシス閾値化の小さい方の閾値を調整すると検出できるエッジが増えたり減ったりする。
import cv2
capture = cv2.VideoCapture(0) # カメラの場号を指定する、カメラが1台しか接続されていない場合は"0"を指定する。
while True: # カメラから連続的に画像を取得するために無限ループさせる
ret, frame = capture.read() # 1コマ分のキャプチャ画像を読み込む、取得した画像データはframeに代入される
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break;
capture.release()
cv2.destroyAllWindows()
import cv2
capture = cv2.VideoCapture(0)
before = None
# エリアの最大値と最小値は任意の値に変更して
MAX_AREA_LIMIT = 50000
MIN_AREA_LIMIT = 1000
while capture.isOpened():
# OpenCVでWebカメラの画像を取り込む
ret, frame = capture.read()
# frameのサイズを変更
# スクリーンショットを撮りたい関係で1/4サイズに縮小
frame = cv2.resize(frame, (int(frame.shape[1]/2), int(frame.shape[0]/2)))
# 加工なし画像を表示する
cv2.imshow('frame', frame)
# 取り込んだフレームに対して差分をとって動いているところが明るい画像を作る
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.bitwise_not(gray, gray)
if before is None:
before = gray.copy().astype('float')
continue
# 現フレームと前フレームの加重平均を使うと良いらしい
cv2.accumulateWeighted(gray, before, 0.2)
mdframe = cv2.absdiff(gray, cv2.convertScaleAbs(before))
# 動いているところが明るい画像を表示する
cv2.imshow('MotionDetected Frame', mdframe)
# 動いているエリアの面積を計算してちょうどいい検出結果を抽出する
# 閾値を指定して2値化する
_, thresh = cv2.threshold(mdframe, 3, 255, cv2.THRESH_BINARY)
# 輪郭データに変換しくれるfindContours
contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
max_area = 0
target = contours[0]
for cnt in contours:
#輪郭の面積を求めてくれるcontourArea
area = cv2.contourArea(cnt)
if max_area < area and area < MAX_AREA_LIMIT and area > MIN_AREA_LIMIT:
max_area = area;
target = cnt
# 動いているエリアのうちそこそこの大きさのものがあればそれを矩形で表示する
if max_area <= MIN_AREA_LIMIT:
areaframe = frame
# 動体検知できていないことを表示しているだけ
cv2.putText(areaframe, 'Not Detected', (0,50), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255,0), 3, cv2.LINE_AA)
else:
# 矩形検出
x, y, width, height = cv2.boundingRect(target)
areaframe = cv2.rectangle(frame, (x, y),(x + width, y + height), (0,255,0), 2)
cv2.imshow('MotionDetected Area Frame', areaframe)
# q が押されたら終了させる、ラズパイだと何で終了させたらいいのかは自分で調べて
if cv2.waitKey(1) & 0xFF == ord('q'):
break;
# キャプチャをリリースして、ウィンドウをすべて閉じる
capture.release()
cv2.destroyAllWindows()
OpenCVの場合はCamShiftが実装されているので、それを利用してトラッキングを行うことができる。
Meanshift and Camshift Mean Shiftの理論
でも、サンプルの説明をまだ書いてる途中なので待ってて。2019/03/19追記する予定。