114 Views
November 28, 24
スライド概要
医学生。AIや業務・学習効率化に興味あり。
OpenCV 画像処理 フィルタ処理 ガウシアンフィルタ コンピュータビジョン エッジ検出 メディアンフィルタ Canny 画像変換 Sobel 物体検出 Haar Cascades 物体追跡 YOLO MeanShift 動画解析 Machine Learning 顔認識 SVM KNN ニューラルネットワーク 背景差分 動体検出 カメラキャリブレーション 光学フロー 内部パラメータ推定 外部パラメータ推定 CamShift OpenCV 定義や意味 OpenCV(Open Source Computer Vision Library)は、コンピュータビジョンと機械学習のためのライブラリ。も ともとはIntelによって開発され、現在はオープンソースとして広く利用されている。主にリアルタイムの画像処 理や解析を目的としており、C++、Python、Javaなどの多言語でサポートされている。 OpenCVは画像処理に関連する多くの機能を提供しており、画像フィルタリング、特徴量検出、エッジ検出、物体 認識、顔認識、カメラキャリブレーションなど、様々なアルゴリズムを含む。 画像処理の基本的な操作は、画像を行列として扱う。例えば、グレースケール画像は2次元の行列として表現さ れ、カラー画像は3次元の行列として扱う。 嚙み砕いた説明 OpenCVは、カメラで撮影した画像やビデオを利用して、コンピュータに「見る」ことを教えるためのツール。例 えば、写真の中から顔を見つけたり、車のナンバープレートを読み取ったりするのに使われる。 具体的には、画像を読み込んでその中の特定のパターンを見つけたり、画像の中の色を変えたり、エッジ(輪 郭)を強調したりすることができる。これにより、画像に関する多くの面白いアプリケーションを作成できる。 実際の応用例 OpenCVはゲーム開発において、拡張現実(AR)やモーションキャプチャ、顔認識を使用したユーザーインター フェースに応用される。 以下のコードスニペットでは、OpenCVを使用して画像から顔を検出する方法を示す。
import cv2 # 顔検出用のカスケード分類器の読み込み face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # 画像の読み込み img = cv2.imread('image.jpg') # グレースケールへの変換 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 顔検出 faces = face_cascade.detectMultiScale(gray, 1.1, 4) # 検出した顔に対して矩形を描画 for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) # 画像の表示 cv2.imshow('img', img) cv2.waitKey() cv2.destroyAllWindows() このコードは、指定した画像ファイル内の顔を検出し、見つけた顔の周りに青い矩形を描画する。顔検出はHaar カスケード分類器を用いて行われる。 画像処理 定義や意味 画像処理とは、デジタル画像を操作する技術や方法を指す。これには画像の変換、フィルタリング、エッジ検 出、ノイズ除去、色補正、形状認識などが含まれる。画像処理は、コンピュータビジョンや機械学習の分野にお いて重要な役割を果たす。 画像処理の基本的な操作には、画像のピクセル値を変更することが含まれる。例えば、画像の輝度を調整する場 合、各ピクセルのRGB値に一定の値を加えるか乗算する。 画像フィルタリングの例として、ガウシアンフィルタを用いた平滑化がある。ガウシアンフィルタは、以下のガ ウス関数を使用して画像の各ピクセルに重み付け平均を適用する: G(x, y) = 1 − x2 +2y2 e 2σ 2πσ 2 ここで、σ はフィルタの標準偏差であり、フィルタの広がりを制御する。 嚙み砕いた説明 画像処理は、写真やビデオのような視覚的なメディアをコンピュータで扱うための技術。例えば、写真の色を鮮 やかにする、ぼやけた画像をシャープにする、あるいは画像から特定の物体を見つけ出すといった操作がある。 例えば、画像を明るくする操作は、画像の各ピクセルの色をより明るい色に変更することを意味する。これは、 画像の全体の見た目を変える簡単な方法の一つ。
実際の応用例 画像処理は、写真編集ソフトウェア(例:Photoshop)、監視カメラの映像解析、医療画像診断、顔認識システム など、さまざまな分野で応用されている。 OpenCV(Open Source Computer Vision Library)は、画像処理とコンピュータビジョンを実行するためのライブ ラリで、多くの関数が提供されている。 以下は、OpenCVを用いて画像をグレースケールに変換する簡単な例: import cv2 # 画像を読み込む image = cv2.imread('input.jpg') # 画像をグレースケールに変換 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # グレースケール画像を保存 cv2.imwrite('output_gray.jpg', gray_image) # グレースケール画像を表示 cv2.imshow('Grayscale Image', gray_image) cv2.waitKey(0) cv2.destroyAllWindows() このコードスニペットは、OpenCVを用いてカラー画像をグレースケール画像に変換する手順を示す。 cv2.imread で画像 を読み込み、 cv2.cvtColor を使用して色空間をBGRからグレースケールに変換する。変換後の画像は、 cv2.imwrite で保 存し、 cv2.imshow で表示する。 コンピュータビジョン 定義や意味 コンピュータビジョンは、コンピュータがデジタル画像やビデオから高次の情報を取得する技術 画像処理、パターン認識、機械学習、データ分析などの技術を組み合わせて、視覚的なデータを理解・解釈する 具体的には、物体検出、画像分類、顔認識、動作解析などのタスクを含む 数式による具体例として、画像を2次元信号と見なし、空間領域における座標 (x, y) での強度値を I(x, y) と定 義する I : R2 → R 嚙み砕いた説明 コンピュータビジョンは、人間の目で行う視覚的な情報の解釈をコンピュータで行う技術 例えば、写真の中に写っている動物が犬か猫かを自動的に判別する カメラで撮影した映像から人を追跡し、動きを分析することも可能 実際の応用例 コンピュータビジョンは、自動運転車の車両検知、監視カメラでの不審者検出、医療画像診断などに応用される
OpenCV(Open Source Computer Vision Library)は、コンピュータビジョンのためのオープンソースライブラリ で、画像処理のための多くの機能を提供する 以下はOpenCVを用いて画像を読み込み、グレースケールに変換して表示するコードスニペット import cv2 # 画像を読み込む image = cv2.imread('path_to_image.jpg') # 画像をグレースケールに変換 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 変換した画像を表示 cv2.imshow('Grayscale Image', gray_image) cv2.waitKey(0) cv2.destroyAllWindows() このコードは、指定したパスの画像を読み込み、グレースケールに変換した後にウィンドウで表示する。 cv2.imread 関 数で画像を読み込み、 cv2.cvtColor 関数でカラー画像をグレースケールに変換することで、視覚情報の単純化を行う。 Machine Learning 定義や意味 機械学習(Machine Learning)は、コンピュータがデータを使用してパターンを学び、予測や意思決定をするこ とを可能にする一連のアルゴリズムや統計モデルの総称。機械学習は、明示的にプログラムされることなく、デ ータの中から知識を構築することに重点を置く。 機械学習は主に以下の3種類に分類される: 教師あり学習: 入力データとその対応する正解(ラベル)が存在し、その関係を学ぶプロセス。 教師なし学習: 入力データだけが与えられ、そこからデータの構造やパターンを学ぶプロセス。 強化学習: エージェントが環境と相互作用し、報酬をもとに最適な行動を学ぶプロセス。 機械学習のモデルは、関数 f : X → Y を近似することが目的。ここで、X は入力データのセット、Y は出力デ ータのセット。 嚙み砕いた説明 機械学習は、人間が行う学習方法をコンピュータに模倣させる技術。例えば、写真を見て「これは犬だ」と判断 するのに、何千枚もの犬の写真を見せて「犬」の特徴を学習させる。 教師あり学習では、すでに正解がわかっている問題をたくさん解かせて、間違えたところを修正しながら学ぶ。 教師なし学習では、答えを教えずにデータの中で何が重要かを自分で見つけさせる。強化学習では、ゲームのよ うに報酬を与えて、最善の選択を学ばせる。 実際の応用例 OpenCVを用いた画像認識における機械学習の応用例。OpenCVは画像処理ライブラリであり、機械学習と組み合 わせることで顔認識や物体検出などのタスクを実行できる。
import cv2
import numpy as np
# トレーニングデータとラベルの準備
# ここでは仮のデータを使用
X_train = np.array([[0, 0], [1, 1], [1, 0], [0, 1]])
y_train = np.array([0, 1, 0, 1])
# 例: 特徴量
# 例: ラベル
# k近傍法(k-Nearest Neighbors, k-NN)を用いた分類器の訓練
knn = cv2.ml.KNearest_create()
knn.train(X_train.astype(np.float32), cv2.ml.ROW_SAMPLE, y_train)
# 新しいデータポイントの分類
sample = np.array([[0.5, 0.5]])
ret, results, neighbours, dist = knn.findNearest(sample.astype(np.float32), k=3)
print(f"Predicted label: {results[0][0]}")
上記のコードでは、OpenCVのk-NN分類器を用いて簡単な2次元特徴量のデータを分類する例を示す。ここでは、
サンプルデータに対してどのクラスに属するかを予測する。
動画解析
定義や意味
動画解析とは、動画データを処理し、そこから有用な情報を抽出する技術の総称
動画は時間的に連続した画像の集合であり、その解析には空間情報だけでなく、時間的情報の解析も必要となる
具体的には、物体検出、追跡、動作認識、シーン解析などのタスクが含まれる
数式で表すと、動画は各フレームをI(x, y, t)として表現し、ここでx, y は空間座標、tは時間を示す
嚙み砕いた説明
動画解析は、映画や監視カメラの映像を人間が理解できる形で解釈する技術
例えば、自動運転車がカメラで撮影した道路の映像から、信号機や歩行者を認識するのに使われる
動画の各フレームを画像として取り出し、それぞれを解析することで、動いている物体の追跡や行動の認識が可
能となる
実際の応用例
動画解析は監視システム、医療画像診断、スポーツのパフォーマンス分析などで応用される
ここではPythonとOpenCVを用いた動画解析の基本的な例を示す
import cv2 # 動画ファイルの読み込み cap = cv2.VideoCapture('video.mp4') # 動画が開けない場合のエラーチェック if not cap.isOpened(): print("Error: Could not open video.") exit() # フレームを一枚ずつ読み込んで処理 while True: # フレームを取得 ret, frame = cap.read() # フレームが正しく読み込めなかった場合、ループを抜ける if not ret: break # フレームをグレースケールに変換 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # ここでフレームに対する解析処理を実施(例:物体検出など) # フレームを表示 cv2.imshow('Frame', gray) # 'q'を押すとプログラムを終了 if cv2.waitKey(1) & 0xFF == ord('q'): break # リソースの解放 cap.release() cv2.destroyAllWindows() 上記コードでは、動画ファイルをフレームごとに読み込み、各フレームをグレースケールに変換して表示 ここに物体検出や動作認識などの解析アルゴリズムを追加することで、様々な動画解析タスクを実現可能 カメラキャリブレーション 定義や意味 カメラキャリブレーションとは、カメラの内部パラメータ(焦点距離、光学中心、レンズの歪みなど)を推定す るプロセス。これにより、カメラで撮影された画像を正確にモデル化することが可能。 キャリブレーションの数式は、一般に次のように表現される。画像座標 (x, y) は実世界の座標 (X, Y , Z) と内 部パラメータを用いて関連付けられる。 $$ s
\begin{bmatrix} x\ y\ 1 \end \mathbf{K} \begin{bmatrix} R&t \end{bmatrix} \begin{bmatrix} X\ Y\ Z\ 1 \end{bmatrix} $$ ここで、K はカメラの内部パラメータ行列であり、R は回転行列、t は平行移動ベクトルである。 嚙み砕いた説明 カメラキャリブレーションは、画像がどのように歪んでいるかを把握し、それを補正する手法。簡単に言えば、 カメラの「目の癖」を知ること。 実際の3D空間の点が、カメラの画像上でどの位置に映るかを計算するために、カメラの内側の特性を知る必要が ある。これがキャリブレーションの目的。 例えば、チェスボードの画像を使ってキャリブレーションを行うことが多い。この画像を使って、カメラがどの ように見ているかを逆算する。 実際の応用例 カメラキャリブレーションはコンピュータビジョンや3D再構築、AR(拡張現実)などで広く使用されている。 OpenCVを使ってカメラキャリブレーションを行う例として、チェスボードパターンを使った実装を以下に示す。
import cv2 import numpy as np # チェスボードのサイズ chessboard_size = (9, 6) # チェスボードの3Dポイント objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32) objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) objpoints = [] # 3Dポイント imgpoints = [] # 2Dポイント # ビデオキャプチャを開く cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None) if ret: objpoints.append(objp) imgpoints.append(corners) cv2.drawChessboardCorners(frame, chessboard_size, corners, ret) cv2.imshow("Calibration", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() # キャリブレーションを行う ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) # 結果の表示 print("カメラ行列:\n", mtx) print("歪み係数:\n", dist) 上記のコードは、ライブカメラフィードを使用してチェスボードパターンを検出し、その情報を使用してカメラ のキャリブレーションを行う。キャリブレーションが成功すると、カメラの内部行列と歪み係数が出力される。 フィルタ処理 定義や意味 フィルタ処理とは、画像処理の一環として画像データに対して特定の演算や処理を施すことで、画像のノイズ除 去、エッジ検出、ぼかし効果などを実現する技術
フィルタ処理は、主に空間フィルタリングと周波数フィルタリングの2つに分類される。空間フィルタリングで は、画像の特定のピクセルに隣接するピクセルの値を用いて新しい値を計算する 数式で表現すると、フィルタ処理の基本式は次のように表される。画像の各ピクセルの値I(x, y)に対してフィル タカーネルK(i, j)を適用する: k k I (x, y) = ∑ ∑ K(i, j) ⋅ I(x + i, y + j) ′ i=−k j=−k ここで、I ′ (x, y)はフィルタ適用後の画像、k はカーネルのサイズに依存する 嚙み砕いた説明 フィルタ処理は、画像の見え方を変えたり、特定の特徴を強調したりするために使う 例えば、画像がぼやけている場合やノイズが多い場合に、フィルタ処理でこれを改善することができる 一般的なフィルタにはぼかしフィルタやシャープ化フィルタがあり、ぼかしフィルタは画像を滑らかにし、シャ ープ化フィルタはエッジを強調する フィルタのサイズや形状によって、画像に与える効果が変わる 実際の応用例 ゲーム開発では、フィルタ処理を用いてリアルタイムで画像やビジュアルエフェクトを処理することがある 例えば、OpenCVライブラリを使用すると、簡単にフィルタ処理を適用できる 以下にOpenCVを用いた簡単なぼかしフィルタの例を示す import cv2 import numpy as np # 画像を読み込む image = cv2.imread('example.jpg') # カーネルサイズを5x5に設定 (カーネルはぼかしの強さを決定) kernel_size = (5, 5) # GaussianBlurを用いてぼかしフィルタを適用 blurred_image = cv2.GaussianBlur(image, kernel_size, 0) # 結果を表示 cv2.imshow('Original Image', image) cv2.imshow('Blurred Image', blurred_image) cv2.waitKey(0) cv2.destroyAllWindows() 上記のコードでは、 cv2.GaussianBlur 関数を使用して、画像に5x5のガウスぼかしを適用している kernel_size を大きくすると、ぼかしの効果が強くなる
エッジ検出 定義や意味 エッジ検出は、画像中の急激な輝度変化を検出するための技術。エッジは、画像の構造的特徴や物体の輪郭を表 すことが多い。 数学的には、画像を二次元のスカラーフィールドと見なし、その勾配を求めることでエッジを検出する手法。エ ッジは画像の輝度関数 I(x, y) の勾配 ∇I の大きさがしきい値を超える点として定義される。 勾配の大きさは次の式で計算される。 ∥∇I(x, y)∥ = ( 2 ∂I ∂I ) +( ) ∂x ∂y 2 嚙み砕いた説明 エッジ検出は、画像の中で「急激に色が変わる場所」を探すこと。例えば、白い背景に黒い線があるとき、その 黒い線の周りがエッジとして検出される。 これは、画像を構成するピクセルの色の変化を調べて、急激に変わる部分を見つけ出すことで実現される。 実際の応用例 エッジ検出はコンピュータビジョンや画像処理の多くの分野で重要な役割を果たす。例えば、物体認識、画像セ グメンテーション、顔検出などがある。 OpenCVを使用したエッジ検出の実装例として、Cannyエッジ検出器を用いた例を示す。 import cv2 import numpy as np # 画像を読み込む image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE) # Cannyエッジ検出を適用 edges = cv2.Canny(image, 100, 200) # 結果を表示 cv2.imshow('Original Image', image) cv2.imshow('Canny Edges', edges) cv2.waitKey(0) cv2.destroyAllWindows() このコードスニペットでは、 cv2.Canny 関数を使ってエッジ検出を行っている。第二引数と第三引数はそれぞれ最 小と最大のしきい値を設定し、エッジと見なす輝度の変化を決めている。 画像変換 定義や意味 画像変換は、画像データのピクセル情報を操作して、新たな画像を生成する技術の総称
画像の変換には、幾何学的変換(回転、平行移動、スケーリング)、空間変換(アフィン変換、射影変換)など が含まれる 数学的には、画像を行列として定義し、その行列に対して変換行列を適用することにより変換を行う たとえば、2D座標 (x, y) の点を θ 角度だけ回転させる場合の変換行列 R は以下の通り: R=[ cos θ sin θ − sin θ ] cos θ 新しい座標 (x′ , y ′ ) は、次のように計算される: $$ \begin{bmatrix} x' \ y' \end R \cdot \begin{bmatrix} x\ y \end{bmatrix} $$ 嚙み砕いた説明 画像変換とは、画像の形を変えたり、位置を動かしたりする操作のこと 例えば、画像を縮小したり、回転させたりするのは画像変換の一種 画像をデジタルデータと考え、そのデジタルデータを数式やアルゴリズムで加工する技術 実際の応用例 画像変換は、デジタル画像処理やコンピュータビジョン、特にゲーム開発において、キャラクターの動きやシー ンの切り替えなどで使用される OpenCVは、画像変換を行うための強力なライブラリであり、様々な変換操作を簡単に実装できる 以下に、OpenCVを使って画像を回転させるコードスニペットを示す:
import cv2 import numpy as np # 画像を読み込む image = cv2.imread('input.jpg') # 画像の中心を計算 (h, w) = image.shape[:2] center = (w // 2, h // 2) # 回転行列を取得 angle = 45 # 回転角度 scale = 1.0 # スケール rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale) # 画像を回転 rotated_image = cv2.warpAffine(image, rotation_matrix, (w, h)) # 結果を表示 cv2.imshow('Rotated Image', rotated_image) cv2.waitKey(0) cv2.destroyAllWindows() このコードは、画像を45度回転させる処理を行う。 getRotationMatrix2D 関数で回転行列を作成し、それを warpAffine 関数で画像に適用する。 物体検出 定義や意味 物体検出は、画像や映像内に存在する物体を識別し、その位置を特定する技術を指す。 画像の中から特定の物体(例えば、車、人、動物など)を見つけ出し、その物体の種類と位置を矩形で示す。 物体検出は、物体の位置を示すバウンディングボックスを生成する。これにより、物体の座標を取得できる。 数式による具体例として、物体検出モデルの基本的な出力はバウンディングボックスの座標と分類スコアで表される: バウンディングボックス:(x, y, w, h) ここで、x, y は矩形の左上の座標、w, hは幅と高さを表す。 スコア:s 物体が特定のクラスに属する確率を示す。 嚙み砕いた説明 物体検出とは、画像の中で「これは車」「これは猫」といった形で、物の種類を見分ける技術。 例えば、カメラで撮った一枚の写真から、人や犬、車などを見つけて、それぞれの場所を四角で囲む。 物体検出を通して、どのあたりにどんなものがあるのかを視覚的に理解することが可能になる。 実際の応用例 自動運転車において、道路上の他の車両や歩行者を検出するために使用される。 監視カメラシステムで、不審者や特定の物体を検出して警報を出すといった用途。
スマートフォンのカメラアプリで、顔認識やQRコードの読み取りに使われる。 以下にPythonとOpenCVを用いた物体検出の基本的な例を示す。ここでは、Haar Cascade Classifierを用いて顔を検出す る。 import cv2 # カスケード分類器の読み込み face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # 画像の読み込み image = cv2.imread('path/to/image.jpg') gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 物体検出(顔検出) faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30)) # 検出された物体に対して矩形を描画 for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2) # 画像を表示 cv2.imshow('Detected Faces', image) cv2.waitKey(0) cv2.destroyAllWindows() このコードでは、 cv2.CascadeClassifier を使って、顔検出用のモデルを読み込み、指定された画像内で顔を検出する。 検出された顔は矩形で囲まれ、最後に画像が表示される。 物体追跡 定義や意味 物体追跡とは、映像や一連の画像において特定の物体を時間的に追跡する技術のことを指す。これには、物体の 位置、形状、動きの変化を特定し続けるプロセスが含まれる。 物体追跡のアルゴリズムは、物体の初期位置を特定し、その後のフレームでの位置を予測、検出、更新する。通 常、背景差分、テンプレートマッチング、特徴点追跡などの手法が用いられる。 ^ t+1 と表し、更新式は以下の 数式で表現すると、物体の位置を Xt とした場合、次のフレームでの予測位置を X ように書かれることがある。 ^ t+1 = Xt + Vt Δt X ここで、Vt は物体の速度、Δt は時間の差分を表す。 嚙み砕いた説明 物体追跡は、ビデオやカメラ映像の中の特定の物体を見つけ出して、フレームが進むたびにその物体がどこにあ るかを追い続ける技術。例えば、監視カメラで人を追跡したり、スポーツ映像でボールの動きを追ったりする。 これを実現するためには、まず最初に追いたい物体を見つけ、それが次のフレームでどこに動くかを予測する。 そして、実際にその位置で物体を検出し、予測と実際の位置を調整する。
実際の応用例 物体追跡は、監視システム、スポーツ解析、拡張現実、ゲームでのキャラクターAIなどで広く応用されている。 OpenCVを使用した物体追跡の基本的なコード例を以下に示す。このコードは、カメラ映像から特定の物体を追跡 する。 import cv2 # カメラ映像の取得 cap = cv2.VideoCapture(0) # トラッカのインスタンスを作成 tracker = cv2.TrackerKCF_create() # 最初のフレームを読み込み、物体の初期位置を選択 ret, frame = cap.read() bbox = cv2.selectROI(frame, False) # トラッカを初期化 ok = tracker.init(frame, bbox) while True: # フレームを取得 ret, frame = cap.read() if not ret: break # 物体を追跡 ok, bbox = tracker.update(frame) # 結果を描画 if ok: # 追跡成功: 境界ボックスを描画 p1 = (int(bbox[0]), int(bbox[1])) p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3])) cv2.rectangle(frame, p1, p2, (255,0,0), 2, 1) else: # 追跡失敗 cv2.putText(frame, "Tracking failure detected", (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,0,255), 2) # フレーム表示 cv2.imshow("Tracking", frame) # ESCキーが押されたらループを終了 if cv2.waitKey(1) & 0xFF == 27: break # リソースの解放 cap.release() cv2.destroyAllWindows() このコードスニペットでは、OpenCVのKCFトラッカを使用してリアルタイムでカメラ映像から物体を追跡する。 物体を選択すると、その物体がフレーム間で追跡され、追跡が成功すればその位置に矩形が描画される。
顔認識 定義や意味 顔認識は、画像やビデオから人間の顔を特定し、識別する技術 これは主に顔検出、顔特徴抽出、顔特徴マッチングの3つのステップから成る 顔認識は、特定の画像内の顔を識別し、それを既知の顔データベースと比較することで、個人を特定する 一般的に以下のような数式で表現される。顔の識別は特徴ベクトル f を用いて行われる: Face Recognition: arg min ∥f − fi ∥ i ここで、f は入力画像から抽出された顔の特徴ベクトル、fi はデータベース内の顔特徴ベクトル 嚙み砕いた説明 顔認識は、カメラなどで撮影した画像やビデオの中から人の顔を見つけ出し、その顔が誰であるかを確認する技 術 例えば、スマートフォンの顔認証機能はこの技術を用いており、ユーザーの顔をカメラでスキャンし、それが登 録された顔と一致するかを確認している 顔の特徴をデジタル情報に変換し、それらを比較することで、どの顔がどの人物に属するかを判断する 実際の応用例 スマートフォンやノートパソコンの顔認証機能 セキュリティシステムや監視カメラでの個人識別 ソーシャルメディアでの写真タグ付け機能 以下に、OpenCVを用いた顔検出のコードスニペットを示す。この例では、カスケード分類器を用いて画像から顔を検出 する。
import cv2 # カスケード分類器の読み込み face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # 画像の読み込み img = cv2.imread('example.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 顔の検出 faces = face_cascade.detectMultiScale(gray, 1.1, 4) # 検出した顔に矩形を描画 for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2) # 画像の表示 cv2.imshow('img', img) cv2.waitKey() cv2.destroyAllWindows() このコードは、OpenCVのカスケード分類器を用いて画像から顔を検出し、検出した顔の周囲に矩形を描画する detectMultiScale 関数は、画像中の異なるサイズの物体を検出し、すべての顔のリストを返す 検出された顔は、 cv2.rectangle 関数を用いて元の画像上に描画される SVM(サポートベクターマシン) 定義や意味 サポートベクターマシン(Support Vector Machine, SVM)は、線形分類問題を解くための教師あり学習アルゴリ ズムの一つ 主に機械学習において分類問題に使用され、データポイントを異なるクラスに分ける最適な超平面を見つける SVMは、マージン(異なるクラスに属するデータポイント間の距離)を最大化する超平面を選択することで、汎 化能力を高める 数式で表すと、超平面は次のように定義される: f (x) = w ⋅ x + b = 0 ここで、wは重みベクトル、xは特徴ベクトル、bはバイアス項 嚙み砕いた説明 SVMは、データを分類するための「線」を見つけることを目指すアルゴリズム 例えば、2D平面上に赤と青の点があるとき、SVMはこれらの点をできるだけ綺麗に分ける直線を見つける この直線は、点と点の間の「余裕」を最大にするように選ばれる SVMは、線形に分離できない場合でも、カーネル関数を用いることで非線形に分離することが可能
実際の応用例 SVMは画像分類や顔認識、テキスト分類など、様々な問題に応用される OpenCVでは、SVMを用いて画像を分類することが可能 以下にPythonとOpenCVを使用した簡単なSVMのコード例を示す import cv2 import numpy as np # データセットの生成 # 特徴量 trainData = np.array([[1, 2], [2, 3], [3, 3], [4, 5], [5, 5]], dtype=np.float32) # ラベル(0または1) responses = np.array([0, 0, 1, 1, 1], dtype=np.int32) # SVMの初期化 svm = cv2.ml.SVM_create() svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6)) # SVMのトレーニング svm.train(trainData, cv2.ml.ROW_SAMPLE, responses) # 新しいデータポイントを分類 testData = np.array([[2, 2], [5, 4]], dtype=np.float32) _, results = svm.predict(testData) print("Predictions:", results) # 結果の出力 # Predictions: [[0.] # [1.]] このコードでは、SVMを用いて2D のデータポイントを分類する トレーニングデータとして(1, 2)、(2, 3)がクラス0に、(3, 3)、(4, 5)、(5, 5)がクラス1に属する 新しいデータポイント(2, 2)と(5, 4)のクラスを予測し、結果を出力する KNN(k-Nearest Neighbors) 定義や意味 KNN(k-Nearest Neighbors)は、非パラメトリックな分類アルゴリズムの一つであり、教師あり学習に分類され る データポイントの分類を行う際に、未知のデータポイントが属するクラスを推定するために、そのデータポイン トに最も近いk 個のデータポイント(近傍)のクラスを参照する 距離計算には通常、ユークリッド距離を用いるが、他の距離指標(例:マンハッタン距離、コサイン類似度)も 使用可能である 具体的な距離計算は次のように表現される。pとq が二つのデータポイントであり、dが次元数である場合、ユーク リッド距離D(p, q)は以下のように定義される
d D(p, q) = ∑(pi − qi )2 i=1 KNNアルゴリズムは、次の手順で実行される i. 分類したいデータポイントを選択する ii. 全ての訓練データとの距離を計算する iii. 近い方からk 個のデータポイントを選ぶ iv. 選んだk 個のデータポイントの中で最も多いクラスに分類する 嚙み砕いた説明 KNNは「近くにいるものは似ている」という直感に基づくアルゴリズム データの特徴から、すでに分類されたデータの中でどれが一番似ているかを探し、その周辺の複数のデータが属 するクラスを見て、新しいデータのクラスを決める 例えば、赤いリンゴを知らないとしても、赤くて丸い果物の近くにあるなら、それはリンゴと分類する 実際の応用例 KNNは顔認識や手書き文字認識など、様々な分類問題で利用される OpenCVでは画像の分類やパターン認識にKNNを活用することができる 以下は、OpenCVを用いてKNNで手書き数字を分類する例 import cv2 import numpy as np # 手書き数字データをロード train_data = np.random.randint(0, 100, (25, 2)).astype(np.float32) responses = np.random.randint(0, 2, (25, 1)).astype(np.float32) # KNNモデルを作成し、訓練データを設定 knn = cv2.ml.KNearest_create() knn.train(train_data, cv2.ml.ROW_SAMPLE, responses) # 新しいデータポイントを分類 newcomer = np.random.randint(0, 100, (1, 2)).astype(np.float32) ret, results, neighbours, dist = knn.findNearest(newcomer, k=3) print("Result: ", results) print("Neighbours: ", neighbours) print("Distances: ", dist) このコードでは、ランダムに生成したデータを用いてKNNを訓練し、新しいデータポイントを3つの近傍で分類す る OpenCVの ml.KNearest_create() を使ってKNNモデルを作成し、 train() メソッドで訓練データを設定 findNearest() メソッドで新しいデータポイントを分類し、結果を取得する
ニューラルネットワーク 定義や意味 ニューラルネットワークは、生物の脳の神経回路を模倣した機械学習モデルの一種。基本的には、入力データを 受け取り、複数の層を通じて計算を行い、最終的に出力を生成する。 ニューラルネットワークは、通常、入力層、隠れ層、出力層から構成され、それぞれの層に複数のノード(ニュ ーロン)が存在する。各ノードは重み w とバイアス b を持ち、それらを用いて入力データ x を処理し、活性化関 数を通して出力を生成する。 数式で表すと、各ノードにおける出力は以下のように表される: y = f (∑ wi xi + b) i ここで、f は活性化関数(例えばシグモイド関数やReLU関数)を表す。 嚙み砕いた説明 ニューラルネットワークは、コンピュータがデータからパターンを学ぶための仕組み。生物の脳が情報を処理す る様子を手本にしている。入力を受け取って、それを何度も加工し、最終的に答えを出す。 例えば、手書き数字認識のタスクでは、入力は数字の画像で、出力はその数字がどの数字であるかを示す。ニュ ーラルネットワークは、たくさんの数字の画像を見せることで、その数字が何であるかを学習する。 実際の応用例 ニューラルネットワークは、画像認識や音声認識、自然言語処理など、さまざまな分野で応用されている。特に OpenCVと組み合わせることで、画像処理タスクにおいて強力なツールとなる。 以下は、OpenCVとTensorFlowを使用して、ニューラルネットワークを用いて画像の分類を行う例。
import cv2
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
# 画像を読み込み、前処理を行う
image_path = 'path/to/image.jpg'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.resize(image, (32, 32))
image = image / 255.0
# ネットワークの入力サイズに合わせてリサイズ
# 正規化
# モデルの定義
model = Sequential([
Flatten(input_shape=(32, 32, 3)),
# 入力層
Dense(128, activation='relu'),
# 隠れ層
Dense(10, activation='softmax')
# 出力層
])
# モデルのコンパイル
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 画像をバッチ形式に変換し、モデルを使用して予測
image = image.reshape((1, 32, 32, 3))
prediction = model.predict(image)
# 結果の表示
predicted_class = tf.argmax(prediction, axis=1).numpy()[0]
print(f"Predicted class: {predicted_class}")
このコードスニペットでは、OpenCVを使用して画像を読み込み、前処理を行い、TensorFlowのニューラルネッ
トワークを使用して画像の分類を行っている。入力画像は32x32ピクセルにリサイズされ、ニューラルネットワー
クは単純な全結合層で構成されている。
背景差分
定義や意味
背景差分(Background Subtraction)は、ビデオ監視や動体検出などのアプリケーションで使用される手法であ
る。これは、静止背景から動的なオブジェクトを検出するための技術であり、各フレームから背景を差し引くこ
とによって動く物体を特定する。
背景差分の基本的な手法の1つは、フレームごとに静的な背景モデルを構築し、現在のフレームからこのモデルを
減算すること。数式で表すと、D(x, y, t) = ∣I(x, y, t) − B(x, y)∣となり、ここでD(x, y, t)は差分画像、
I(x, y, t)は現行フレームでの画素値、B(x, y)は背景モデルでの画素値を表す。
嚙み砕いた説明
背景差分は、カメラで撮影した映像の中から動いているもの(例えば人や車)を見つけ出す手法。まず、カメラ
が見ているシーンの背景を学習し、その背景と新しい映像を比較して、背景以外の動いている部分を探す。
例えば、監視カメラで通行人を検出するとき、カメラが見えている背景(例えば建物や木)は変わらないが、人 が通過するとその部分だけが動く。この動いている人を背景差分によって見つける。 実際の応用例 背景差分は、監視システム、交通監視、動作認識、インタラクティブアートなどで広く使われている。 OpenCVを用いた背景差分の実装例を以下に示す。OpenCVの BackgroundSubtractorMOG2 を使用して、動いている 物体を検出する。 import cv2 # ビデオキャプチャの初期化 cap = cv2.VideoCapture('video.mp4') # 背景差分器の作成 backSub = cv2.createBackgroundSubtractorMOG2() while True: # フレームの読み込み ret, frame = cap.read() if not ret: break # 背景差分を適用 fgMask = backSub.apply(frame) # 結果の表示 cv2.imshow('Frame', frame) cv2.imshow('FG Mask', fgMask) # 'q'キーで終了 if cv2.waitKey(30) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() 上記のコードは、動画ファイルからフレームを読み込み、各フレームに対して背景差分を適用し、動くオブジェ クトを検出している。 BackgroundSubtractorMOG2 は、OpenCVの標準ライブラリであるため、簡単に実装が可能。 動体検出 定義や意味 動体検出とは、画像やビデオシーケンスにおいて動いている物体を検出する技術のこと これにより、動いている物体と背景を分離し、物体の追跡や分析を行うことが可能になる 数学的には、時間 t における画像フレーム It (x, y) と時間 t − 1 のフレーム It−1 (x, y) の差分を計算することで 動きを検出する。差分が閾値 τ を超える場合、そのピクセルは動いているとみなされる。 M (x, y) = { 1, 0, if ∣It (x, y) − It−1 (x, y)∣ > τ otherwise
M (x, y) は動体マスクで、1 は動いている部分、0 は静止部分を示す 嚙み砕いた説明 動体検出は、どんなシーンにおいても動いているものを見つけ出すための方法 例えば、ビデオ監視カメラが動く人や車を検出して追跡するために使う 画像の各フレームを比較し、変化がある部分を動体と見なす。人間の目で見ても変化している部分をコンピュー タで検出できるようにする技術 実際の応用例 動体検出は監視カメラシステム、自動運転車、インタラクティブなゲームなどで使用されている OpenCVを使った動体検出の基本的な例を以下に示す import cv2 # ビデオキャプチャを取得 cap = cv2.VideoCapture('video.mp4') # 最初のフレームを取得してグレースケールに変換 ret, frame1 = cap.read() gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) while cap.isOpened(): ret, frame2 = cap.read() if not ret: break # 現在のフレームをグレースケールに変換 gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) # フレーム間の差分を計算 diff = cv2.absdiff(gray1, gray2) # 差分を閾値処理して動きを検出 _, thresh = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY) # 結果を表示 cv2.imshow('Motion Detection', thresh) # 次のフレームのために更新 gray1 = gray2 # 'q' キーを押すとループを終了 if cv2.waitKey(30) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() 上記のコードは、ビデオファイルを読み込んで各フレームの間の動きを検出する フレーム間の差分を計算し、閾値処理を行うことで動いている部分を白く表示する
光学フロー 定義や意味 光学フロー(Optical Flow)は、画像の中で物体の動きを計算する方法の一つ。時間の経過による連続した画像間 での各ピクセルの動きのベクトル場を表す。 数学的には、光学フローは2次元画像平面での速度ベクトル V(x, y) = (u(x, y), v(x, y)) を指し、ここで u(x, y) と v(x, y) はそれぞれ水平方向と垂直方向の速度成分。 光学フローの基本的な仮定は、輝度の保存であり、これは次の式で表される: I(x, y, t) = I(x + u, y + v, t + Δt) ここで I(x, y, t) は時間 t における位置 (x, y) の輝度を表す。 嚙み砕いた説明 光学フローは、映像や画像の連続フレーム間で物体がどのように動いているかを追跡するための技術。 例えば、ビデオゲームでキャラクターが走っている時に、背景がどのように動いて見えるかを計算するのに使え る。 動きの方向と速さをピクセルレベルで捉えるため、カメラで撮影した映像の解析などに応用される。 実際の応用例 光学フローは、モーション検出、物体追跡、動き推定、画像安定化などの分野で使用される。 特にコンピュータビジョンやロボットビジョンの分野で重要な役割を果たす。 以下はOpenCVを用いた光学フローの計算例。
import cv2 import numpy as np # ビデオキャプチャの取得 cap = cv2.VideoCapture('video.mp4') # 最初のフレームを取得し、グレースケールに変換 ret, first_frame = cap.read() prev_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY) # HSVイメージを初期化 hsv = np.zeros_like(first_frame) hsv[..., 1] = 255 while(cap.isOpened()): ret, frame = cap.read() if not ret: break # 現在のフレームをグレースケールに変換 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 光学フローの計算 (Farneback法) flow = cv2.calcOpticalFlowFarneback(prev_gray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0) # フローの大きさと角度を計算 magnitude, angle = cv2.cartToPolar(flow[..., 0], flow[..., 1]) # HSVのHチャンネルに角度情報を設定 hsv[..., 0] = angle * 180 / np.pi / 2 # HSVのVチャンネルにフローの大きさを正規化して設定 hsv[..., 2] = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX) # HSVからBGRに変換 bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # 結果の表示 cv2.imshow('Optical Flow', bgr) # 次のフレームの準備 prev_gray = gray if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() このコードは、指定されたビデオファイル内のフレーム間で光学フローを計算し、その結果を表示する。 cv2.calcOpticalFlowFarneback 関数を使用して、Farnebackアルゴリズムにより光学フローを計算する。
内部パラメータ推定 定義や意味 内部パラメータ推定(カメラキャリブレーション)は、カメラの内部特性を数値的に求めるプロセスである。こ れには焦点距離、光学中心(主点)、歪み係数などのカメラの固有パラメータを含む。 内部パラメータは、カメラ行列 K によって定義される。これは次のように表される: fx K= 0 0 0 fy 0 cx cy 1 ここで、fx と fy はそれぞれ横と縦の焦点距離、cx と cy は光学中心の座標を示す。 嚙み砕いた説明 カメラキャリブレーションは、カメラがどのように世界を「見ている」かを理解するためのステップである。こ の情報がなければ、カメラで撮影した画像を正確に解釈することは難しい。 たとえば、歪んだ写真を見たとき、カメラのレンズが画像の周囲に歪みを生じさせている。内部パラメータを知 ることで、その歪みを補正できる。 実際の応用例 OpenCVを用いてカメラの内部パラメータを推定する方法を示す。実際の応用としては、ロボットビジョン、3D 再構成、画像補正などがある。
import cv2 import numpy as np # チェスボードのサイズ chessboard_size = (9, 6) square_size = 1.0 # 正方形のサイズ # 3D世界座標系の点群を準備 objp = np.zeros((np.prod(chessboard_size), 3), dtype=np.float32) objp[:, :2] = np.indices(chessboard_size).T.reshape(-1, 2) objp *= square_size # 画像からの2D画像座標系の点群を集める objpoints = [] # 3D点 imgpoints = [] # 2D点 # キャリブレーションに用いる画像のリスト images = ['image1.jpg', 'image2.jpg', ...] for fname in images: img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # チェスボードのコーナーを探す ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None) if ret: objpoints.append(objp) imgpoints.append(corners) # 内部パラメータを推定 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) # 結果の表示 print("Camera matrix:\n", mtx) print("Distortion coefficients:\n", dist) このスニペットでは、複数のチェスボード画像を用いてカメラの内部パラメータを推定す る。 cv2.calibrateCamera 関数は、入力された3Dおよび2Dの点群を基にカメラ行列と歪み係数を計算する。 外部パラメータ推定 定義や意味 外部パラメータ推定とは、カメラの位置や向き(姿勢)を推定することを指す。具体的には、カメラ座標系と世 界座標系の間の変換を求めることであり、これは通常、回転行列と並進ベクトルで表現される。 カメラの外部パラメータは、回転行列 R と並進ベクトル t で表され、世界座標系の点 Xw がカメラ座標系の点 Xc に変換される関係は次のように表される。 Xc = R ⋅ Xw + t
嚙み砕いた説明 外部パラメータ推定は、カメラがどこにあってどちらを向いているかを知るための方法。例えば、ある物体をカ メラで撮影したとき、その物体がカメラからどれくらいの距離にあり、どの方向にあるのかを計算する。 これを行うためには、カメラが撮影した画像内の特定の点(特徴点)と、実際の物体の位置(世界座標)が必要 になる。これらの情報を使って、カメラの位置と向きを計算する。 実際の応用例 外部パラメータ推定は、ロボット工学やコンピュータビジョンの分野でよく使われる。例えば、ロボットがカメ ラで周囲を見渡して自分の位置を把握する際に利用される。 OpenCVを用いた外部パラメータ推定の具体例として、PnP(Perspective-n-Point)問題を解決する方法がある。 これは、3D空間の点とそれに対応する2D画像の点を用いてカメラの位置と向きを推定する問題。 import cv2 import numpy as np # 3Dの座標系における点(世界座標系) object_points = np.array([ [0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0] ], dtype=np.float32) # カメラの画像平面上の対応する点(画像座標系) image_points = np.array([ [320, 240], [400, 240], [320, 320], [400, 320] ], dtype=np.float32) # カメラ行列(内部パラメータ) camera_matrix = np.array([ [800, 0, 320], [0, 800, 240], [0, 0, 1] ], dtype=np.float32) # 歪み係数(今回はゼロとしている) dist_coeffs = np.zeros((4, 1)) # 外部パラメータを求める success, rotation_vector, translation_vector = cv2.solvePnP( object_points, image_points, camera_matrix, dist_coeffs ) # 得られた回転ベクトルと並進ベクトル print("Rotation Vector:\n", rotation_vector) print("Translation Vector:\n", translation_vector) 上記のコードは、OpenCVを使ってカメラの外部パラメータを求める例を示している。 solvePnP 関数を用いて、 3Dの物体点と2Dの画像点からカメラの回転ベクトルと並進ベクトルを推定する。これにより、カメラの位置と方
向を知ることができる。 ガウシアンフィルタ 定義や意味 ガウシアンフィルタは、画像処理における平滑化のためのフィルタであり、特にノイズ除去やエッジの検出をス ムーズに行うために用いられる。ガウス分布(正規分布)に基づいてフィルタを構築する。 ガウシアンフィルタは、入力画像に対してガウス関数を畳み込むことによって実現される。ガウス関数は次のよ うに定義される: G(x, y) = 1 x2 + y 2 exp − ( ) 2πσ 2 2σ 2 ここで、σ は標準偏差で、フィルタのぼかしの強さを制御する。 嚙み砕いた説明 ガウシアンフィルタは、画像からノイズを除去しつつ、エッジをなめらかにするためのツール。ガウス関数とい う数学的な式を使って、画像のピクセルを平均化し、急激な色の変化を緩やかにする。 例えば、写真の中の小さなノイズやしわを目立たなくするのに使われる。ぼやけた画像を作り出すフィルタとも 言える。 実際の応用例 ガウシアンフィルタは、デジタル画像処理で広く使われており、特にエッジ検出処理の前処理としてノイズを除 去する際に用いられる。また、3Dグラフィックスやコンピュータビジョンの分野でも、ガウシアンフィルタは一 般的な手法である。 OpenCVを用いたガウシアンフィルタの実装例: import cv2 import numpy as np # 画像の読み込み image = cv2.imread('example.jpg') # ガウシアンフィルタの適用 # ksizeはフィルタのカーネルサイズ、sigmaXはX方向の標準偏差 blurred_image = cv2.GaussianBlur(image, (5, 5), 0) # 結果の表示 cv2.imshow('Original Image', image) cv2.imshow('Gaussian Blurred Image', blurred_image) cv2.waitKey(0) cv2.destroyAllWindows() このコードでは、OpenCVの GaussianBlur 関数を使って画像にガウシアンフィルタを適用している。カーネルサ イズは(5, 5)に設定し、X方向の標準偏差を0にしている(この場合、自動的に適切な値が計算される)。このよう にして、画像を滑らかにすることができる。
メディアンフィルタ 定義や意味 メディアンフィルタは、信号処理や画像処理においてノイズを除去するためのフィルタリング手法の一つ 特に、スパイクノイズ(塩胡椒ノイズ)と呼ばれるランダムに現れる極端な画素値に対して効果的 フィルタリング処理は、指定されたウィンドウサイズ(通常は3x3、5x5などの正方形)内の画素値を昇順に並 べ、その中の中央値(メディアン)をそのウィンドウの中心画素に設定することで実現される 数式的には、ウィンドウ内の画素値を P = {p1 , p2 , … , pn } とした場合、メディアンフィルタによって得られ る値 M は次のように表される: M = median(P ) 嚙み砕いた説明 画像の各ピクセルを取り囲む一定範囲(ウィンドウ)のピクセルを集め、数を小さい順に並べる 並べたピクセルの真ん中に位置する値を、ウィンドウの中心にあるピクセルの新しい値とする これにより、画像のエッジを保ちながら、ノイズを効果的に除去することができる 例えば、ウィンドウが「3, 1, 2, 100, 5」の場合、並べると「1, 2, 3, 5, 100」で、中央値は「3」 実際の応用例 メディアンフィルタはデジタル画像のノイズ除去に広く使用されている 特に、スパイクノイズが多く含まれる監視カメラの画像や、医療画像処理において有効 OpenCVを用いてメディアンフィルタを適用する例を以下に示す import cv2 import numpy as np # 画像を読み込む image = cv2.imread('noisy_image.jpg') # メディアンフィルタを適用(カーネルサイズは5x5) # カーネルサイズは必ず奇数で指定する必要がある filtered_image = cv2.medianBlur(image, 5) # フィルタリング結果を保存または表示 cv2.imwrite('filtered_image.jpg', filtered_image) # cv2.imshow('Filtered Image', filtered_image) # cv2.waitKey(0) # cv2.destroyAllWindows() このコードでは、OpenCVの medianBlur 関数を使用して、ノイズの多い画像にメディアンフィルタを適用してい る カーネルサイズ(フィルタを適用するウィンドウのサイズ)は5x5に設定しているが、ノイズの程度に応じて調整 可能 ノイズを効果的に除去しつつ、エッジを保つことができるため、画像の品質を向上させる手法として使用される
Canny 定義や意味 Cannyエッジ検出は、画像処理の一手法であり、ノイズの多い画像から重要なエッジを抽出するためのアルゴリ ズム 1986年にJohn F. Cannyによって開発された 主に以下のステップで構成される: i. ガウシアンフィルタによる画像の平滑化 ii. 画像のグレースケール変換 iii. Sobelフィルタを用いた画像の勾配強度と方向の計算 iv. 非最大抑制によるエッジの強調 v. ヒステリシスによるエッジの追跡 数式として、勾配は次のように計算される: G2x + G2y 勾配強度: G = 勾配方向: θ = tan−1 ( G ) Gy x ここで、Gx とGy はそれぞれ画像のx軸およびy軸方向の勾配 嚙み砕いた説明 Cannyエッジ検出は、写真や画像の中にある輪郭(エッジ)を見つけ出すための手法 まず、画像をぼかしてノイズを減らし、次にエッジの強さと方向を計算する その後、最も目立つエッジだけを残し、他の弱いエッジを削除する 最後に、エッジを繋げることで途切れた線がないようにする 実際の応用例 Cannyエッジ検出は、画像の物体認識やコンピュータビジョンにおいて重要な手法 例えば、顔認識や障害物検出、自動運転車の画像解析に利用される OpenCVを用いたCannyエッジ検出の実装例を以下に示す import cv2 import numpy as np # 画像を読み込む image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE) # Cannyエッジ検出を適用 edges = cv2.Canny(image, 100, 200) # 結果を表示 cv2.imshow('Edges', edges) cv2.waitKey(0) cv2.destroyAllWindows()
上記のコードでは、 cv2.Canny 関数がCannyエッジ検出を行う 第一引数は入力画像で、第二、第三引数はヒステリシスのための閾値となる Sobel 定義や意味 Sobel(ソーベル)フィルタは、画像処理におけるエッジ検出のための手法の一つ。エッジ検出とは、画像内の急 激な輝度変化を検出することであり、これにより画像の輪郭や形状を抽出することが可能となる。 Sobelフィルタは、画像の水平および垂直方向の微分を計算することでエッジを検出する。これにより、画像の勾 配の大きさと方向を求めることができる。 水平方向のSobelフィルタ(Gx )と垂直方向のSobelフィルタ(Gy )はそれぞれ以下の3x3カーネルで表現され る: −1 0 1 Gx = −2 0 2 −1 0 1 Gy = −1 −2 −1 0 0 0 1 2 1 画像の勾配の大きさはこれらのカーネルを用いて以下のように計算される: G= G2x + G2y 嚙み砕いた説明 Sobelフィルタは、画像の輪郭や縁を見つけるための方法。画像の中で色が急に変わるところを探して、そこがエ ッジ(輪郭)だよ、という風に教えてくれる。 例えば、写真の中で建物や人の境界線をはっきりさせたい時に使われる。Sobelフィルタは画像を水平方向と垂直 方向に分けて、それぞれの方向でどれだけ色が変わっているかを計算する。 これにより、画像のどこにエッジがあるのかを見つけることができる。 実際の応用例 Sobelフィルタはコンピュータビジョンの分野でよく使われる。特に、オブジェクトの認識やトラッキング、画像 の特徴抽出などに利用される。 OpenCVを使ってSobelフィルタを適用するコードスニペットを以下に示す:
import cv2 import numpy as np # 画像を読み込む image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) # Sobelフィルタを適用してx方向の勾配を計算 sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3) # Sobelフィルタを適用してy方向の勾配を計算 sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3) # 勾配の大きさを計算 sobel_magnitude = np.sqrt(sobel_x**2 + sobel_y**2) # 結果を表示 cv2.imshow('Sobel X', sobel_x) cv2.imshow('Sobel Y', sobel_y) cv2.imshow('Sobel Magnitude', sobel_magnitude) cv2.waitKey(0) cv2.destroyAllWindows() このコードでは、まず画像をグレースケールで読み込み、次にSobelフィルタを使って水平方向と垂直方向の勾配 を計算する。最後に、勾配の大きさを計算して表示する。 Haar Cascades 定義や意味 Haar Cascadesは、物体検出に用いられる機械学習ベースの手法であり、特に顔検出で広く利用されている。検 出器はAdaBoostアルゴリズムを用いてトレーニングされた一連の単純な特徴(Haar-like特徴)を使用する。 Haar-like特徴は、特定の領域内のピクセル値の和を計算し、それを隣接する領域の和と比較することによって定 義される。これにより、画像内のエッジやラインを検出する。 数式的には、Haar-like特徴は以下のように表される。 Feature = ∑ White − ∑ Black 嚙み砕いた説明 Haar Cascadesは、画像内の特定のパターン(例えば顔や目など)を見つけるための方法。画像をスキャンし、 特定の特徴(Haar-like特徴)を見つけることで、物体を検出する。 Haar-like特徴とは、画像を白と黒の領域に分けて、その輝度の差を計算することで、物体の形や境界を見つける 手法。例えば、顔では目の部分が暗く、頬の部分が明るいといった特徴を捉える。 実際の応用例 Haar Cascadesは顔検出や目、笑顔、猫の顔などの検出に使用される。 OpenCVでは、Haar Cascadesがプリセットとして提供されており、簡単に使用することができる。 以下にOpenCVを使用した顔検出のコード例を示す。
import cv2
# Haar CascadeのXMLファイルをロード
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 画像を読み込み
img = cv2.imread('path_to_image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 顔検出を実行
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# 検出された顔を囲む
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# 結果を表示
cv2.imshow('Detected Faces', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードでは、画像内の顔を検出し、長方形で囲む。 detectMultiScale 関数がHaar Cascadeを使用して物体を
検出する。
YOLO
定義や意味
YOLO(You Only Look Once)は、物体検出アルゴリズムの一種で、単一のニューラルネットワークを用いて画
像内の物体を高速かつ正確に検出する手法。YOLOは画像をグリッドに分割し、それぞれのセルに対してバウンデ
ィングボックスとその信頼度スコアを予測する。
予測されるバウンディングボックスは、中心座標 (bx , by )、幅 bw 、高さ bh 、およびクラス確率 P (ci ) を含む。
損失関数は以下のように定義される。
S2
S2 B
obj
obj
2
2
Loss = λcoord ∑ ∑ 1ij [(xi − x
^i ) + (yi − y^i ) ] + λcoord ∑ ∑ 1ij [(
i=0 j=0
i=0 j=0
B
wi −
w
^ i )2 + ( h i −
^ i )2 ]
h
$$
\sum_{i=0}{S2} \sum_{j=0}^{B} \mathbb{1}{ij}^{\text{obj}} (C_i - \hat{C}i)^2 + \lambda{\text{noobj}} \sum{i=0}{S2}
\sum_{j=0}^{B} \mathbb{1}{ij}^{\text{noobj}} (C_i - \hat{C}i)^2 + \sum{i=0}{S2} \mathbb{1}{i}^{\text{obj}} \sum_{c \in
\text{classes}} (p_i(c) - \hat{p}_i(c))^2
$$
嚙み砕いた説明
YOLOは、画像を一度だけ見て("You Only Look Once")物体を検出する方法。画像をグリッドに分けて、各グリ
ッドセルが物体を含むかどうかを判断し、その物体の位置と種類を予測する。非常に高速であるため、リアルタ
イムの応用に適している。
例えば、画像内に3つの物体(猫、犬、車)があるとき、YOLOはそれらを検出し、それぞれの位置とクラスを出 力する。これにより、どの位置にどの物体があるのかがわかる。 実際の応用例 YOLOは防犯カメラやドローン映像のリアルタイム物体検出、モバイルアプリでの画像解析、ゲームの視覚的要素 の検出などに使われている。 OpenCVを用いたYOLOの実装例を以下に示す。
import cv2 import numpy as np # YOLOモデルの重みと設定ファイル weights_path = 'yolov3.weights' config_path = 'yolov3.cfg' classes_path = 'coco.names' # クラス名の読み込み with open(classes_path, 'r') as f: classes = [line.strip() for line in f.readlines()] # ネットワークの初期化 net = cv2.dnn.readNet(weights_path, config_path) layer_names = net.getLayerNames() output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] # 画像の読み込み image = cv2.imread('image.jpg') height, width, channels = image.shape # 画像をYOLOに入力するための前処理 blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False) net.setInput(blob) # フォワードパスで物体を検出 outs = net.forward(output_layers) # 検出結果の解析 class_ids = [] confidences = [] boxes = [] for out in outs: for detection in out: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if confidence > 0.5: center_x = int(detection[0] * width) center_y = int(detection[1] * height) w = int(detection[2] * width) h = int(detection[3] * height) x = int(center_x - w / 2) y = int(center_y - h / 2) boxes.append([x, y, w, h]) confidences.append(float(confidence)) class_ids.append(class_id) # Non-maximum Suppression for redundant overlapping boxes indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4) for i in indices: i = i[0] box = boxes[i]
x, y, w, h = box label = str(classes[class_ids[i]]) color = (0, 255, 0) cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) cv2.putText(image, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) # 結果の表示 cv2.imshow('Image', image) cv2.waitKey(0) cv2.destroyAllWindows() このコードスニペットは、OpenCVのDNNモジュールを使用して、YOLOv3モデルを用いて画像内の物体を検出するも の。画像を読み込み、YOLOのネットワークを通して物体を検出し、その結果を画像上に描画する。 MeanShift 定義や意味 MeanShiftは、データの密度推定に基づく非パラメトリックなクラスタリング手法。クラスタリングを行うため に、データの密度勾配を反復的に計算し、データポイントを高密度の方向にシフトさせる。 各データポイントは、カーネル関数を用いて周囲のデータ密度を計算し、その密度の重心(平均)に向かって移 動する。このプロセスを収束するまで繰り返し、最終的にデータポイントが密集する位置にクラスタが形成され る。 数式的には、データ点xi の新しい位置xi+1 は次のように更新される: xi+1 = ∑j K(xj − xi )xj ∑j K(xj − xi ) ここで、K はカーネル関数を表す。 嚙み砕いた説明 MeanShiftは、データの「山」を見つける方法。データポイントを高密度の領域に「シフト」させることで、デー タが集まる場所を明らかにする。 例えば、散らばった点群データがあるとき、MeanShiftはそれぞれの点を密度が高い方向に動かし、最終的に点が 集まる場所(つまりクラスタ)を見つける。 この手法は、事前にクラスタの数を指定する必要がないため、データの性質に応じた自然なクラスタを見つける ことができる。 実際の応用例 MeanShiftは、画像セグメンテーション、物体追跡、特徴空間のクラスタリングなど、多くのコンピュータビジョ ンの問題に応用される。 OpenCVを用いたMeanShiftの実装例を以下に示す。ここでは、ある画像内で特定の色の物体を追跡する例を示 す。
import cv2 import numpy as np # 動画キャプチャの初期化 cap = cv2.VideoCapture('video.mp4') # 初期位置の設定(ROI: Region of Interest) ret, frame = cap.read() x, y, w, h = 300, 200, 100, 50 # 初期の追跡する領域 track_window = (x, y, w, h) # ROIを設定 roi = frame[y:y+h, x:x+w] hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # マスクの作成 mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.))) # ヒストグラムの計算 roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180]) cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # MeanShiftの停止条件 term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) while True: ret, frame = cap.read() if not ret: break hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1) # MeanShiftアルゴリズム適用 ret, track_window = cv2.meanShift(dst, track_window, term_crit) # トラッキング結果の描画 x, y, w, h = track_window img2 = cv2.rectangle(frame, (x, y), (x+w, y+h), 255, 2) cv2.imshow('Tracking', img2) if cv2.waitKey(30) & 0xFF == 27: # Escキーで終了 break cap.release() cv2.destroyAllWindows() このコードは、動画内の特定の色の物体をMeanShiftアルゴリズムを用いて追跡する。最初に指定した領域を基 に、動的に物体の位置を更新し続ける。
CamShift 定義や意味 CamShift(Continuously Adaptive Mean Shift)は、物体追跡アルゴリズムの一つで、Mean Shiftアルゴリズムを基 にして、追跡対象のサイズや形状の変化に適応するように設計された手法 画像内の特定の物体を追跡するために、色相(Hue)などの色空間情報を利用する 基本的な手順としては、まず初期の位置とサイズを指定し、フレームごとに物体の位置を更新する 物体の追跡において、物体の色のヒストグラムをビンで分け、それを基に物体の位置を推定する CamShiftでは、以下の手順で追跡を行う ヒストグラムの計算 逆投影(back projection)の計算 Mean Shiftによるウィンドウの移動 ウィンドウサイズの更新 嚙み砕いた説明 CamShiftは、色を利用して物体を追いかける技術で、動いている物体が徐々に大きくなったり小さくなったりし ても、それに合わせて追跡するサイズを調整する 例えば、カメラで人物の顔を追いかける場合、その人物がカメラに近づいたり遠ざかったりしても、CamShiftを 使えば顔をしっかりと捉え続けることができる 実際の応用例 CamShiftは、ビデオストリームなどで特定の物体を追跡する際に利用され、特にWebカメラを使ったアプリケー ションや監視システムで使用される 以下にOpenCVを用いたPythonでのCamShiftの実装例を示す。
import cv2 import numpy as np # カメラからのビデオキャプチャ cap = cv2.VideoCapture(0) # 初期フレームの取得 ret, frame = cap.read() # 追跡する対象の領域選択 x, y, w, h = 300, 200, 100, 50 track_window = (x, y, w, h) # ROIの設定 roi = frame[y:y+h, x:x+w] hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.))) # ヒストグラムの計算と正規化 roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0,180]) cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 停止条件の設定 term_criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) while True: ret, frame = cap.read() if not ret: break # フレームをHSVに変換 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 逆投影の計算 dst = cv2.calcBackProject([hsv], [0], roi_hist, [0,180], 1) # CamShiftによる物体追跡 ret, track_window = cv2.CamShift(dst, track_window, term_criteria) # 結果の描画 pts = cv2.boxPoints(ret) pts = np.int0(pts) img2 = cv2.polylines(frame, [pts], True, 255, 2) cv2.imshow('CamShift Tracking', img2) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
このコードは、Webカメラからの映像を使用して、指定した領域をCamShiftアルゴリズムで追跡する。追跡されている 物体の境界をリアルタイムで描画する。