コンピュータビジョンと OpenCV の概要
現代の技術環境において、コンピュータビジョンは不可欠な要素となっています。スマートフォンの生体認証から自動運転システムの周囲認識、さらには監視カメラの智能分析に至るまで、その応用範囲は多岐にわたります。こうした視覚情報を処理するための標準的なツールとして、OpenCV(Open Source Computer Vision Library)が広く採用されています。多様な画像処理機能と機械学習アルゴリズムを備えたこのライブラリは、C++、Python、Java など複数の言語に対応しており、特に Python バインディングは記述が簡潔であるため、初学者にとって最適な入り口となります。
開発環境の構築
OpenCV を利用して開発を始める前に、適切な環境を整える必要があります。主に以下の手順でセットアップを行います。
1. Python インタープリタの導入
OpenCV の Python モジュールを利用するには、事前に Python 環境が必要です。バージョン 3.6 以降を推奨します。公式ウェブサイトからインストーラーを入手し、システムにインストールしてください。
2. OpenCV ライブラリのインストール
パッケージ管理ツール pip を使用して、簡単にライブラリを導入できます。ターミナルまたはコマンドプロンプトで以下のコマンドを実行します。
pip install opencv-python
さらに、貢献モジュール(contrib modules)に含まれる追加機能を利用したい場合は、以下のパッケージもインストールします。
pip install opencv-contrib-python
3. 統合開発環境(IDE)の選定
効率的なコーディングのために、Visual Studio Code や PyCharm などの IDE を利用することを推奨します。これらのツールは、コード補完やデバッグ機能を備えており、開発生産性を向上させます。
基礎的な画像・動画処理
OpenCV 学習の最初のステップは、基本的な入出力操作と幾何学的変換を理解することです。
画像の読み込みと表示
画像ファイルの読み込み、画面表示、および保存を行う基本コードは以下の通りです。ここでは、カラー空間の変換処理も追加しています。
import cv2
# 画像ファイルの読み込み
img_source = cv2.imread('sample_photo.png')
if img_source is not None:
# BGR から RGB へ変換(表示用)
img_rgb = cv2.cvtColor(img_source, cv2.COLOR_BGR2RGB)
# ウィンドウに表示
cv2.imshow('Preview', img_rgb)
cv2.waitKey(0)
# 結果を保存
cv2.imwrite('processed_output.png', img_source)
cv2.destroyAllWindows()
動画ストリームの処理
静止画だけでなく、動画ファイルや webcam からの入力も処理可能です。フレームごとに処理を行うループ構造が基本となります。
import cv2
# 動画ファイルを開く
cap_source = cv2.VideoCapture('movie_clip.mp4')
while cap_source.isOpened():
ret, frame = cap_source.read()
if not ret:
break
# グレースケール変換
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Stream', gray_frame)
# 'q' キーで終了
if cv2.waitKey(30) & 0xFF == ord('q'):
break
cap_source.release()
cv2.destroyAllWindows()
幾何学的変換
画像のサイズ変更や回転などの操作は、前処理として頻繁に利用されます。
import cv2
img = cv2.imread('sample_photo.png')
h, w = img.shape[:2]
# リサイズ(幅と高さの半分)
img_small = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
# 回転(90 度)
angle_deg = 90
center = (w / 2, h / 2)
scale = 1.0
rot_mat = cv2.getRotationMatrix2D(center, angle_deg, scale)
img_rotated = cv2.warpAffine(img, rot_mat, (w, h))
cv2.imshow('Resized', img_small)
cv2.imshow('Rotated', img_rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()
画像分析と特徴抽出
基礎操作を習得したら、画像から情報を抽出する进阶的な処理に移ります。
エッジ検出
物体の輪郭を抽出する際、Canny アルゴリズムが広く用いられます。ノイズ除去のためにガウシアンブラーを適用するのが一般的です。
import cv2
img_gray = cv2.imread('sample_photo.png', cv2.IMREAD_GRAYSCALE)
# ノイズ低減
blurred = cv2.GaussianBlur(img_gray, (3, 3), 0)
# エッジ検出
threshold_low = 50
threshold_high = 150
edges = cv2.Canny(blurred, threshold_low, threshold_high)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
特徴点検出(ORB)
画像中の興味深い点(キーポイント)を検出し、記述子を計算することで、画像マッチングなどが可能になります。
import cv2
img_gray = cv2.imread('sample_photo.png', cv2.IMREAD_GRAYSCALE)
# ORB 検出器の初期化
feature_detector = cv2.ORB_create(nfeatures=500)
# キーポイントと記述子の計算
keypoints, descriptors = feature_detector.detectAndCompute(img_gray, None)
# 可視化
img_vis = cv2.drawKeypoints(img_gray, keypoints, None, color=(0, 255, 0), flags=0)
cv2.imshow('Features', img_vis)
cv2.waitKey(0)
cv2.destroyAllWindows()
機械学習と深層学習の統合
OpenCV は伝統的な画像処理に加え、機械学習モデルや深層学習ネットワークの実行環境としても機能します。
SVM による分類
サポートベクターマシン(SVM)を用いた简单的な分類タスクの例です。
import cv2
import numpy as np
# 訓練データの生成
train_samples = np.random.rand(20, 2).astype(np.float32) * 100
labels = np.random.randint(0, 2, (20, 1)).astype(np.float32)
# SVM モデルの設定
classifier = cv2.ml.SVM_create()
classifier.setType(cv2.ml.SVM_C_SVC)
classifier.setKernel(cv2.ml.SVM_LINEAR)
classifier.train(train_samples, cv2.ml.ROW_SAMPLE, labels)
# 予測実行
test_samples = np.random.rand(5, 2).astype(np.float32) * 100
prediction = classifier.predict(test_samples)[1]
print("Classification Result:", prediction)
深層学習モデルによる物体検出
事前に訓練された YOLO などのモデルを読み込み、画像内の物体を検出する処理です。
import cv2
import numpy as np
# ネットワークの読み込み
inference_net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')
img = cv2.imread('sample_photo.png')
h, w = img.shape[:2]
# 入力データの整形
input_blob = cv2.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)
inference_net.setInput(input_blob)
# 出力層の取得
layer_names = inference_net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in inference_net.getUnconnectedOutLayers()]
# 推論実行
outputs = inference_net.forward(output_layers)
# 結果の描画
for out in outputs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.6:
cx = int(detection[0] * w)
cy = int(detection[1] * h)
bw = int(detection[2] * w)
bh = int(detection[3] * h)
x = int(cx - bw / 2)
y = int(cy - bh / 2)
cv2.rectangle(img, (x, y), (x + bw, y + bh), (0, 255, 0), 2)
cv2.imshow('Detection', img)
cv2.waitKey(0)
cv2.destroyAllWindows()