[Python] OpenCV(cv2)の使い方を解説
OpenCVは、コンピュータビジョンや画像処理のためのライブラリで、Pythonではcv2
モジュールとして利用されます。
画像の読み込みにはcv2.imread()
を使用し、表示にはcv2.imshow()
を用います。
画像の保存はcv2.imwrite()
で行います。
また、画像のリサイズや回転、フィルタリングなどの操作も簡単に行えます。
OpenCVは、顔認識や物体検出などの高度な機能もサポートしており、機械学習やディープラーニングと組み合わせて利用されることが多いです。
- OpenCVの基本操作(画像の読み込み、表示、保存など)
- 画像処理技術(グレースケール変換、エッジ検出、フィルタリングなど)
- 動画処理の方法(動画の読み込み、フレームの取得、動体検知など)
- 画像の特徴量抽出とマッチング技術
- 様々な応用例(顔検出、物体検出、OCRなど)
OpenCV(cv2)とは
OpenCV(Open Source Computer Vision Library)は、コンピュータビジョンや画像処理のためのオープンソースライブラリです。
C++で開発されており、PythonやJavaなどの言語からも利用可能です。
画像や動画の解析、処理、認識を行うための多くの機能が提供されています。
特に、リアルタイム処理に強みを持ち、さまざまなアプリケーションで広く使用されています。
OpenCVの概要
OpenCVは、以下のような特徴を持っています。
特徴 | 説明 |
---|---|
オープンソース | 無料で使用でき、コミュニティによって開発されている。 |
クロスプラットフォーム | Windows、Linux、macOS、Android、iOSで動作する。 |
多言語サポート | C++、Python、Javaなど、複数のプログラミング言語に対応。 |
リアルタイム処理 | 高速な画像処理が可能で、リアルタイムアプリケーションに適している。 |
OpenCVの歴史
OpenCVは、2000年にIntelによって開発が始まりました。
最初はC++で実装され、2006年にオープンソースとして公開されました。
その後、コミュニティの貢献により、機能が拡張され続け、現在では数千の関数が提供されています。
OpenCVは、学術研究や産業界での利用が進み、特にロボティクスや自動運転車、医療画像処理などの分野で重要な役割を果たしています。
OpenCVの用途
OpenCVは、さまざまな用途に利用されています。
以下はその一部です。
用途 | 説明 |
---|---|
画像処理 | 画像のフィルタリング、変換、解析など。 |
動画解析 | 動画のフレーム処理、動体検知など。 |
顔認識 | 顔の検出や認識、表情分析など。 |
物体追跡 | 動体の追跡や識別。 |
自動運転 | 車両の周囲の認識や障害物検知。 |
OpenCVのインストール方法
OpenCVは、Python環境に簡単にインストールできます。
以下の手順でインストールを行います。
- Pythonがインストールされていることを確認します。
- コマンドラインで以下のコマンドを実行します。
pip install opencv-python
これでOpenCVがインストールされ、cv2
モジュールを使用できるようになります。
インストール後、以下のコードを実行して、正しくインストールされたか確認できます。
import cv2
print(cv2.__version__)
このコードを実行すると、インストールされたOpenCVのバージョンが表示されます。
OpenCVの基本操作
OpenCVを使用すると、画像に対する基本的な操作を簡単に行うことができます。
ここでは、画像の読み込み、表示、保存、サイズ変更、回転、切り抜きについて解説します。
画像の読み込みと表示
画像を読み込むには、cv2.imread()関数
を使用します。
読み込んだ画像を表示するには、cv2.imshow()関数
を使います。
以下はそのサンプルコードです。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# 画像の表示
cv2.imshow('Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、指定した画像がウィンドウに表示されます。
cv2.waitKey(0)
は、キーが押されるまでウィンドウを表示し続けます。
画像の保存
画像を保存するには、cv2.imwrite()関数
を使用します。
以下のサンプルコードでは、読み込んだ画像を新しいファイル名で保存します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# 画像の保存
cv2.imwrite('saved_image.jpg', image)
このコードを実行すると、image.jpg
がsaved_image.jpg
として保存されます。
画像のサイズ変更
画像のサイズを変更するには、cv2.resize()関数
を使用します。
以下のサンプルコードでは、画像を幅300ピクセル、高さ200ピクセルにリサイズします。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# 画像のサイズ変更
resized_image = cv2.resize(image, (300, 200))
# 画像の表示
cv2.imshow('Resized Image', resized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、リサイズされた画像が表示されます。
画像の回転
画像を回転させるには、cv2.getRotationMatrix2D()
とcv2.warpAffine()
を使用します。
以下のサンプルコードでは、画像を45度回転させます。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# 回転行列の作成
height, width = image.shape[:2]
rotation_matrix = cv2.getRotationMatrix2D((width / 2, height / 2), 45, 1)
# 画像の回転
rotated_image = cv2.warpAffine(image, rotation_matrix, (width, height))
# 画像の表示
cv2.imshow('Rotated Image', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、45度回転した画像が表示されます。
画像の切り抜き
画像を切り抜くには、NumPyのスライシングを使用します。
以下のサンプルコードでは、画像の特定の領域を切り抜きます。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# 画像の切り抜き (x, y, width, height)
cropped_image = image[50:200, 100:300]
# 画像の表示
cv2.imshow('Cropped Image', cropped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、指定した領域が切り抜かれた画像が表示されます。
画像処理の基本
OpenCVを使用すると、画像に対するさまざまな処理を簡単に行うことができます。
ここでは、グレースケール変換、画像の二値化、平滑化(ぼかし)、エッジ検出、画像のヒストグラムについて解説します。
グレースケール変換
カラー画像をグレースケール画像に変換するには、cv2.cvtColor()関数
を使用します。
以下のサンプルコードでは、画像をグレースケールに変換します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# グレースケール変換
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 画像の表示
cv2.imshow('Gray Image', gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、グレースケールに変換された画像が表示されます。
画像の二値化
画像を二値化するには、cv2.threshold()関数
を使用します。
以下のサンプルコードでは、グレースケール画像を二値化します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 画像の二値化
_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
# 画像の表示
cv2.imshow('Binary Image', binary_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、二値化された画像が表示されます。
画像の平滑化(ぼかし)
画像を平滑化するには、cv2.GaussianBlur()関数
を使用します。
以下のサンプルコードでは、画像にガウシアンぼかしを適用します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# 画像の平滑化
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
# 画像の表示
cv2.imshow('Blurred Image', blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、ぼかしが適用された画像が表示されます。
カーネルサイズは5×5に設定されています。
エッジ検出
エッジ検出には、Canny法を使用することが一般的です。
cv2.Canny()関数
を使用してエッジを検出します。
以下のサンプルコードでは、Cannyエッジ検出を行います。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# エッジ検出
edges = cv2.Canny(image, 100, 200)
# 画像の表示
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、エッジが強調された画像が表示されます。
閾値は100と200に設定されています。
画像のヒストグラム
画像のヒストグラムを表示するには、cv2.calcHist()関数
を使用します。
以下のサンプルコードでは、グレースケール画像のヒストグラムを計算し、表示します。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# ヒストグラムの計算
histogram = cv2.calcHist([image], [0], None, [256], [0, 256])
# ヒストグラムの表示
plt.plot(histogram)
plt.title('Histogram')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.xlim([0, 256])
plt.show()
このコードを実行すると、画像のピクセル値に対する頻度を示すヒストグラムが表示されます。
ヒストグラムは、画像の明るさやコントラストを分析するのに役立ちます。
画像の変換とフィルタリング
OpenCVを使用すると、画像の変換やフィルタリングを簡単に行うことができます。
ここでは、アフィン変換、パースペクティブ変換、ガウシアンフィルタ、メディアンフィルタ、バイラテラルフィルタについて解説します。
アフィン変換
アフィン変換は、画像の平行移動、回転、スケーリングを行うための変換です。
cv2.getAffineTransform()
とcv2.warpAffine()
を使用して実行します。
以下のサンプルコードでは、アフィン変換を適用します。
import cv2
import numpy as np
# 画像の読み込み
image = cv2.imread('image.jpg')
# アフィン変換のための3点の指定
points1 = np.float32([[50, 50], [200, 50], [50, 200]])
points2 = np.float32([[10, 100], [200, 50], [100, 250]])
# アフィン変換行列の計算
matrix = cv2.getAffineTransform(points1, points2)
# アフィン変換の適用
affine_transformed_image = cv2.warpAffine(image, matrix, (image.shape[1], image.shape[0]))
# 画像の表示
cv2.imshow('Affine Transformed Image', affine_transformed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、指定した3点に基づいてアフィン変換が適用された画像が表示されます。
パースペクティブ変換
パースペクティブ変換は、画像の視点を変更するための変換です。
cv2.getPerspectiveTransform()
とcv2.warpPerspective()
を使用します。
以下のサンプルコードでは、パースペクティブ変換を適用します。
import cv2
import numpy as np
# 画像の読み込み
image = cv2.imread('image.jpg')
# パースペクティブ変換のための4点の指定
points1 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
points2 = np.float32([[50, 50], [250, 30], [30, 250], [300, 300]])
# パースペクティブ変換行列の計算
matrix = cv2.getPerspectiveTransform(points1, points2)
# パースペクティブ変換の適用
perspective_transformed_image = cv2.warpPerspective(image, matrix, (image.shape[1], image.shape[0]))
# 画像の表示
cv2.imshow('Perspective Transformed Image', perspective_transformed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、指定した4点に基づいてパースペクティブ変換が適用された画像が表示されます。
ガウシアンフィルタ
ガウシアンフィルタは、画像のノイズを減少させるために使用される平滑化フィルタです。
cv2.GaussianBlur()
を使用します。
以下のサンプルコードでは、ガウシアンフィルタを適用します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# ガウシアンフィルタの適用
gaussian_blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
# 画像の表示
cv2.imshow('Gaussian Blurred Image', gaussian_blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、ガウシアンフィルタが適用された画像が表示されます。
メディアンフィルタ
メディアンフィルタは、画像のノイズを除去するためのフィルタで、特に塩胡椒ノイズに効果的です。
cv2.medianBlur()
を使用します。
以下のサンプルコードでは、メディアンフィルタを適用します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# メディアンフィルタの適用
median_blurred_image = cv2.medianBlur(image, 5)
# 画像の表示
cv2.imshow('Median Blurred Image', median_blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、メディアンフィルタが適用された画像が表示されます。
バイラテラルフィルタ
バイラテラルフィルタは、エッジを保持しながらノイズを除去するためのフィルタです。
cv2.bilateralFilter()
を使用します。
以下のサンプルコードでは、バイラテラルフィルタを適用します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# バイラテラルフィルタの適用
bilateral_filtered_image = cv2.bilateralFilter(image, 9, 75, 75)
# 画像の表示
cv2.imshow('Bilateral Filtered Image', bilateral_filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、バイラテラルフィルタが適用された画像が表示されます。
フィルタのパラメータは、カーネルサイズ9、空間的および色空間の標準偏差75に設定されています。
形状検出と解析
OpenCVを使用すると、画像内の形状を検出し、解析することができます。
ここでは、輪郭検出、形状の近似、形状の特徴量抽出、ハフ変換による直線検出、ハフ変換による円検出について解説します。
輪郭検出
輪郭検出は、画像内の物体の境界を見つけるための手法です。
cv2.findContours()
を使用して輪郭を検出します。
以下のサンプルコードでは、輪郭を検出し、描画します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 画像の二値化
_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
# 輪郭の検出
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 輪郭の描画
contour_image = cv2.cvtColor(binary_image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)
# 画像の表示
cv2.imshow('Contours', contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、検出された輪郭が緑色で描画された画像が表示されます。
形状の近似
輪郭を近似することで、形状を単純化することができます。
cv2.approxPolyDP()
を使用します。
以下のサンプルコードでは、輪郭を近似し、描画します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 画像の二値化
_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
# 輪郭の検出
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 形状の近似
approx_contours = [cv2.approxPolyDP(cnt, 10, True) for cnt in contours]
# 近似した輪郭の描画
approx_image = cv2.cvtColor(binary_image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(approx_image, approx_contours, -1, (0, 255, 0), 2)
# 画像の表示
cv2.imshow('Approximated Contours', approx_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、近似された輪郭が緑色で描画された画像が表示されます。
形状の特徴量抽出
形状の特徴量を抽出することで、形状を識別することができます。
cv2.contourArea()
やcv2.arcLength()
を使用して、面積や周囲の長さを計算します。
以下のサンプルコードでは、輪郭の面積と周囲の長さを計算します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 画像の二値化
_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
# 輪郭の検出
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 特徴量の抽出
for cnt in contours:
area = cv2.contourArea(cnt)
perimeter = cv2.arcLength(cnt, True)
print(f'Area: {area}, Perimeter: {perimeter}')
このコードを実行すると、各輪郭の面積と周囲の長さがコンソールに表示されます。
Area: 0.0, Perimeter: 0.0
Area: 0.0, Perimeter: 2.8284270763397217
Area: 0.0, Perimeter: 2.0
Area: 0.0, Perimeter: 2.0
Area: 0.0, Perimeter: 2.0
Area: 0.0, Perimeter: 0.0
...各輪郭の面積と周囲の長さの結果が続く
ハフ変換による直線検出
ハフ変換を使用して画像内の直線を検出するには、cv2.HoughLines()
またはcv2.HoughLinesP()
を使用します。
以下のサンプルコードでは、ハフ変換を使用して直線を検出し、描画します。
import cv2
import numpy as np
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# エッジ検出
edges = cv2.Canny(image, 50, 150)
# ハフ変換による直線検出
lines = cv2.HoughLines(edges, 1, np.pi / 180, 100)
# 直線の描画
line_image = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
if lines is not None:
for rho, theta in lines[:, 0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
cv2.line(line_image, (x1, y1), (x2, y2), (0, 255, 0), 2)
# 画像の表示
cv2.imshow('Hough Lines', line_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、検出された直線が緑色で描画された画像が表示されます。
ハフ変換による円検出
ハフ変換を使用して画像内の円を検出するには、cv2.HoughCircles()
を使用します。
以下のサンプルコードでは、ハフ変換を使用して円を検出し、描画します。
import cv2
import numpy as np
# 画像の読み込み
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# エッジ検出
blurred_image = cv2.GaussianBlur(image, (9, 9), 2)
circles = cv2.HoughCircles(blurred_image, cv2.HOUGH_GRADIENT, dp=1, minDist=20, param1=50, param2=30, minRadius=0, maxRadius=0)
# 円の描画
color_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
# 円の外周
cv2.circle(color_image, (i[0], i[1]), i[2], (0, 255, 0), 2)
# 円の中心
cv2.circle(color_image, (i[0], i[1]), 2, (0, 0, 255), 3)
# 画像の表示
cv2.imshow('Hough Circles', color_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、検出された円が緑色で描画され、円の中心が赤色で表示された画像が表示されます。
画像の特徴量抽出
画像の特徴量抽出は、画像の内容を理解し、比較するための重要な手法です。
OpenCVでは、SIFT、SURF、ORBなどのアルゴリズムを使用して特徴量を抽出できます。
ここでは、これらの手法と特徴量マッチングについて解説します。
SIFT(Scale-Invariant Feature Transform)
SIFTは、スケール不変な特徴量を抽出するための手法です。
画像のスケールや回転に対して頑健で、特に物体認識に有効です。
以下のサンプルコードでは、SIFTを使用して特徴点を検出し、描画します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# SIFTオブジェクトの作成
sift = cv2.SIFT_create()
# 特徴点と特徴量の検出
keypoints, descriptors = sift.detectAndCompute(image, None)
# 特徴点の描画
sift_image = cv2.drawKeypoints(image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 画像の表示
cv2.imshow('SIFT Keypoints', sift_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、SIFTによって検出された特徴点が描画された画像が表示されます。
SURF(Speeded-Up Robust Features)
SURFは、SIFTよりも高速に特徴量を抽出できる手法です。
SURFもスケール不変で、回転に対しても頑健です。
以下のサンプルコードでは、SURFを使用して特徴点を検出し、描画します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# SURFオブジェクトの作成
surf = cv2.xfeatures2d.SURF_create()
# 特徴点と特徴量の検出
keypoints, descriptors = surf.detectAndCompute(image, None)
# 特徴点の描画
surf_image = cv2.drawKeypoints(image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 画像の表示
cv2.imshow('SURF Keypoints', surf_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、SURFによって検出された特徴点が描画された画像が表示されます。
SURFアルゴリズムは特許で保護されているため、通常のOpenCVでは使用できません。使用する場合は、OpenCV とOpenCV ContribをGithubのリポジトリをクローンし、ビルドしたものを使用してください。
ORB(Oriented FAST and Rotated BRIEF)
ORBは、SIFTやSURFに比べて計算が軽く、リアルタイムアプリケーションに適した特徴量抽出手法です。
以下のサンプルコードでは、ORBを使用して特徴点を検出し、描画します。
import cv2
# 画像の読み込み
image = cv2.imread('image.jpg')
# ORBオブジェクトの作成
orb = cv2.ORB_create()
# 特徴点と特徴量の検出
keypoints, descriptors = orb.detectAndCompute(image, None)
# 特徴点の描画
orb_image = cv2.drawKeypoints(image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 画像の表示
cv2.imshow('ORB Keypoints', orb_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、ORBによって検出された特徴点が描画された画像が表示されます。
特徴量マッチング
特徴量マッチングは、異なる画像間で特徴点を比較し、対応する点を見つける手法です。
以下のサンプルコードでは、SIFTを使用して2つの画像間で特徴点をマッチングします。
import cv2
# 画像の読み込み
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')
# SIFTオブジェクトの作成
sift = cv2.SIFT_create()
# 特徴点と特徴量の検出
keypoints1, descriptors1 = sift.detectAndCompute(image1, None)
keypoints2, descriptors2 = sift.detectAndCompute(image2, None)
# BFMatcherの作成
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
# 特徴量のマッチング
matches = bf.match(descriptors1, descriptors2)
# マッチング結果の描画
matches = sorted(matches, key=lambda x: x.distance)
matching_image = cv2.drawMatches(image1, keypoints1, image2, keypoints2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# 画像の表示
cv2.imshow('Feature Matching', matching_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、2つの画像間でマッチングされた特徴点が描画された画像が表示されます。
最も良い10個のマッチングが表示されます。
動画処理
OpenCVを使用すると、動画に対するさまざまな処理を行うことができます。
ここでは、動画の読み込みと表示、フレームの取得と保存、動画の書き出し、動画のフィルタリング、動体検知について解説します。
動画の読み込みと表示
動画を読み込むには、cv2.VideoCapture()
を使用します。
以下のサンプルコードでは、動画を読み込み、フレームを表示します。
import cv2
# 動画の読み込み
cap = cv2.VideoCapture('video.mp4')
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# フレームの表示
cv2.imshow('Video', frame)
# 'q'キーで終了
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# リソースの解放
cap.release()
cv2.destroyAllWindows()
このコードを実行すると、指定した動画が再生されます。
‘q’キーを押すと再生が終了します。
フレームの取得と保存
動画から特定のフレームを取得し、保存するには、cv2.VideoCapture()
とcv2.imwrite()
を使用します。
以下のサンプルコードでは、動画の最初のフレームを取得して保存します。
import cv2
# 動画の読み込み
cap = cv2.VideoCapture('video.mp4')
# 最初のフレームの取得
ret, frame = cap.read()
if ret:
cv2.imwrite('first_frame.jpg', frame)
# リソースの解放
cap.release()
このコードを実行すると、動画の最初のフレームがfirst_frame.jpg
として保存されます。
動画の書き出し
動画を新しいファイルに書き出すには、cv2.VideoWriter()
を使用します。
以下のサンプルコードでは、動画を読み込み、各フレームをそのまま新しい動画ファイルに書き出します。
import cv2
# 動画の読み込み
cap = cv2.VideoCapture('video.mp4')
# 動画の書き出し設定
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output_video.avi', fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# フレームを書き出し
out.write(frame)
# リソースの解放
cap.release()
out.release()
cv2.destroyAllWindows()
このコードを実行すると、output_video.avi
という新しい動画ファイルが作成されます。
動画のフィルタリング
動画の各フレームにフィルタを適用することもできます。
以下のサンプルコードでは、動画の各フレームにガウシアンフィルタを適用します。
import cv2
# 動画の読み込み
cap = cv2.VideoCapture('video.mp4')
# 動画の書き出し設定
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('filtered_video.avi', fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# ガウシアンフィルタの適用
filtered_frame = cv2.GaussianBlur(frame, (5, 5), 0)
# フレームを書き出し
out.write(filtered_frame)
# リソースの解放
cap.release()
out.release()
cv2.destroyAllWindows()
このコードを実行すると、各フレームにガウシアンフィルタが適用されたfiltered_video.avi
という新しい動画ファイルが作成されます。
動体検知
動体検知は、動画内の動く物体を検出するための手法です。
以下のサンプルコードでは、背景差分法を使用して動体を検出します。
import cv2
# 動画の読み込み
cap = cv2.VideoCapture('video.mp4')
# 背景差分オブジェクトの作成
fgbg = cv2.createBackgroundSubtractorMOG2()
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 背景差分の適用
fgmask = fgbg.apply(frame)
# 動体の表示
cv2.imshow('Motion Detection', fgmask)
# 'q'キーで終了
if cv2.waitKey(30) & 0xFF == ord('q'):
break
# リソースの解放
cap.release()
cv2.destroyAllWindows()
このコードを実行すると、動画内の動体が白く表示されるウィンドウが表示されます。
‘q’キーを押すと終了します。
応用例
OpenCVを使用すると、さまざまな応用例が実現できます。
ここでは、顔検出と顔認識、物体検出と追跡、画像のセグメンテーション、OCR(光学文字認識)、画像のスタイル変換について解説します。
顔検出と顔認識
顔検出は、画像や動画内の顔を特定する技術です。
OpenCVでは、Haarカスケード分類器を使用して顔を検出できます。
以下のサンプルコードでは、顔検出を行います。
import cv2
# Haarカスケード分類器の読み込み
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 画像の読み込み
image = cv2.imread('image.jpg')
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 顔の検出
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5)
# 検出した顔の描画
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 画像の表示
cv2.imshow('Face Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、検出された顔が青い矩形で囲まれた画像が表示されます。
物体検出と追跡
物体検出は、画像や動画内の特定の物体を検出する技術です。
YOLO(You Only Look Once)やSSD(Single Shot MultiBox Detector)などの深層学習モデルを使用することが一般的です。
以下のサンプルコードでは、YOLOを使用して物体検出を行います。
import cv2
import numpy as np
# YOLOの設定ファイルと重みファイルの読み込み
net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
# 画像の読み込み
image = cv2.imread('image.jpg')
height, width = image.shape[:2]
# 画像をBlobに変換
blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
# 物体検出
outs = net.forward(output_layers)
# 検出結果の描画
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)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 画像の表示
cv2.imshow('Object Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、検出された物体が緑色の矩形で囲まれた画像が表示されます。
画像のセグメンテーション
画像のセグメンテーションは、画像を意味のある部分に分割する技術です。
以下のサンプルコードでは、K-meansクラス
タリングを使用して画像のセグメンテーションを行います。
import cv2
import numpy as np
# 画像の読み込み
image = cv2.imread('image.jpg')
Z = image.reshape((-1, 3))
# K-meansクラスタリングの適用
K = 3
Z = np.float32(Z)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)
_, labels, centers = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# セグメンテーション結果の生成
centers = np.uint8(centers)
segmented_image = centers[labels.flatten()]
segmented_image = segmented_image.reshape(image.shape)
# 画像の表示
cv2.imshow('Segmented Image', segmented_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、K-meansクラス
タリングによってセグメンテーションされた画像が表示されます。
OCR(光学文字認識)
OCRは、画像内のテキストを認識する技術です。
Tesseractを使用してOCRを実行できます。
以下のサンプルコードでは、Tesseractを使用して画像内のテキストを認識します。
import cv2
import pytesseract
# 画像の読み込み
image = cv2.imread('text_image.jpg')
# OCRの実行
text = pytesseract.image_to_string(image, lang='eng')
# 認識したテキストの表示
print('Recognized Text:', text)
このコードを実行すると、画像内のテキストが認識され、コンソールに表示されます。
Tesseractがインストールされている必要があります。
画像のスタイル変換
画像のスタイル変換は、ある画像のスタイルを別の画像に適用する技術です。
以下のサンプルコードでは、スタイル変換を行います。
import cv2
import numpy as np
# スタイル変換のためのモデルの読み込み
net = cv2.dnn.readNetFromTorch('models/instance_norm/mosaic.t7')
# 画像の読み込み
content_image = cv2.imread('content.jpg')
style_image = cv2.imread('style.jpg')
# 画像をBlobに変換
blob = cv2.dnn.blobFromImage(content_image, 1.0, (content_image.shape[1], content_image.shape[0]), (103.939, 116.779, 123.68), swapRB=False, crop=False)
net.setInput(blob)
# スタイル変換の実行
output = net.forward()
# 出力画像の整形
output = output.reshape((output.shape[2], output.shape[3], output.shape[1]))
output += np.array((103.939, 116.779, 123.68))
output = np.clip(output, 0, 255).astype('uint8')
# 画像の表示
cv2.imshow('Styled Image', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードを実行すると、コンテンツ画像にスタイル画像のスタイルが適用された画像が表示されます。
スタイル変換のためのモデルが必要です。
よくある質問
まとめ
この記事では、OpenCVを使用した画像処理や動画処理の基本から応用例まで幅広く解説しました。
OpenCVのインストール方法や基本操作、さまざまな画像処理技術を学ぶことで、実際のプロジェクトに応用できる知識を得ることができました。
ぜひ、実際に手を動かしてOpenCVを使ったプロジェクトに挑戦してみてください。