Python 画像処理: OpenCV 入門チュートリアル
1. Python画像処理の概要
1 画像処理の基本概念
いわゆる画像処理とは、コンピューター技術を使用して画像を処理および強化するプロセスを指します。これはコンピュータ ビジョンに不可欠な部分であり、多くの分野で使用できます。
2 画像処理におけるPythonの利点
Python は、データ分析、機械学習、人工知能などの分野で広く使用されている高水準プログラミング言語です。画像処理の分野では、Python は OpenCV に関連付けられています。OpenCV は、Intel によって開発されたオープンソースのコンピュータ ビジョン ライブラリであり、画像処理、ビデオ処理、マシン ビジョンなどの分野で使用できます。
Python には、画像処理の分野で次のような多くの利点があります。
- コードは簡潔で理解しやすく、使いやすく、プログラミング経験はそれほど必要ありません。
- 複数の画像形式をサポートできる強力な画像処理ライブラリ (OpenCV など) があります。
- 他の Python ライブラリ (NumPy、SciPy など) とシームレスに統合する機能
2. OpenCV の概要
1 OpenCVの概要
OpenCV は、コンピューター ビジョン用のオープンソース ライブラリです。 Intel Corporation によって開発され、C++、Python、Java などの複数のプログラミング言語をサポートしています。主にリアルタイム コンピュータ ビジョン アプリケーションの開発に使用されます。強力な画像処理機能を備え、複数の画像形式と数学的演算をサポートしているため、開発者はこのライブラリを簡単に使用およびカスタマイズできます。さらに、クロスプラットフォームのパフォーマンスも優れており、Windows、Linux、macOS などの複数のオペレーティング システム上で実行できます。
OpenCVの2つの特徴
OpenCV には主に次の機能があります。
- 画像とビデオを処理し、複数の画像形式をサポートする機能
- 基本的な画像処理機能 (フィルタリング、形態学的演算、エッジ検出など) を提供します。
- 顔認識、ターゲット追跡、動作分析などの高度な機能をサポート
- 計算効率を最適化するために、C++ と Python の 2 つのプログラミング方法が提供されます。
- 優れたクロスプラットフォーム パフォーマンスを備えており、Windows、Linux、macOS などの複数のオペレーティング システム上で実行できます。
- 画像/ビデオのインポートとエクスポートが可能
3 OpenCVの応用分野
OpenCV は、次のようなコンピューター ビジョンおよびマシン ビジョンの分野で広く使用されています。
- 顔認識
- ターゲットの検出と追跡
- モーションキャプチャ
- ビデオの分析と処理
- 自動運転車
- 拡張現実技術など
3. OpenCVのインストールと環境構築
1 OpenCVのインストール方法
Python に OpenCV をインストールする最も簡単な方法は、次のように pip コマンドを使用することです。
pip install opencv-python
このコマンドは、OpenCV の最新の安定バージョンを自動的にダウンロードしてインストールします。
2 OpenCVの環境構成
画像処理にOpenCVを使用するには環境を構築する必要があります。まず、Python に OpenCV ライブラリをインポートする必要があります。 Python では、次のコードを使用できます。
import cv2
エラー メッセージが表示されなければ、OpenCV ライブラリは正常にインポートされています。次に、OpenCV ライブラリの関数を画像処理に使用できるようにします。
4. 画像処理の基礎知識
画像処理を行う前に、まず基本的な知識を理解する必要があります。この知識には、画像の読み取り、表示、保存の方法、画像のサイズと色空間の調整方法が含まれます。画像に対して幾何学的変換、しきい値演算、畳み込みフィルタリングなどの演算を実行する方法。
1 読み取り 表示 画像保存
OpenCV ライブラリの関数を使用して、Python で画像を読み取り、表示、保存できます。具体的なコードは次のとおりです。
import cv2
# 读取图像
img = cv2.imread('image.jpg')
# 显示图像
cv2.imshow('Image', img)
cv2.waitKey(0)
# 保存图像
cv2.imwrite('new_image.jpg', img)
このうち、cv2.imread()
関数は画像の読み取りに使用され、cv2.imshow()
関数は画像の表示に使用され、cv2.waitKey()
関数を使用する キーボード入力を待つ場合は、cv2.imwrite()
関数を使用して指定したファイルに画像を保存します。プログラムの実行中に、任意のキーを押して画像ウィンドウを閉じます。
2 画像サイズを調整する
実際のアプリケーションでは、画像のサイズを変更する必要がある場合があります。 cv2.resize()
関数を使用して画像のサイズを調整できます。具体的なコードは次のとおりです。
import cv2
# 读取图像
img = cv2.imread('image.jpg')
# 调整图像大小
resized_img = cv2.resize(img, (600, 600))
# 显示原图和调整后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Resized Image', resized_img)
cv2.waitKey(0)
# 保存调整后的图像
cv2.imwrite('resized_image.jpg', resized_img)
ここcv2.resize()
関数の 2 番目のパラメータは、タプル形式の新しい画像サイズ、つまり新しい画像の幅と高さです。サイズ変更後、元の画像と比較して結果を確認できます。
3 画像の色空間を変更する
画像の色空間には、グレースケール空間と色空間が含まれます。 cv2.cvtColor()
関数を使用して、画像の色空間を変換できます。具体的なコードは次のとおりです。
import cv2
# 读取图像
img = cv2.imread('image.jpg')
# 将图像转换为灰度空间
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 显示原图和灰度图
cv2.imshow('Original Image', img)
cv2.imshow('Gray Image', gray_img)
cv2.waitKey(0)
# 保存灰度图
cv2.imwrite('gray_image.jpg', gray_img)
ここでcv2.cvtColor()
関数の最初のパラメータは元の画像で、2 番目のパラメータは変換された色空間を指定します。この例では、元の画像をグレースケール空間 (GRAY) に変換し、グレースケール画像として保存します。
4. 画像の幾何学的変換
画像に幾何学的変換を実行することにより、画像の回転、平行移動、拡大縮小などの操作を実現できます。以下では、回転を例として、画像の幾何学的変換を実行する方法を紹介します。具体的なコードは次のとおりです。
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg')
# 获取图像的旋转矩阵
rows, cols = img.shape[:2]
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
# 进行图像旋转
rotated_img = cv2.warpAffine(img, M, (cols, rows))
# 显示原图和旋转后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Rotated Image', rotated_img)
cv2.waitKey(0)
# 保存旋转后的图像
cv2.imwrite('rotated_image.jpg', rotated_img)
このうち、cv2.getRotationMatrix2D()
関数は、回転中心と回転角度 (45 度) を指定して回転変換行列を取得するために使用され、cv2.warpAffine()
関数は回転操作を実行するために使用されます。
5. 画像の閾値処理
しきい値演算を実行する場合、画像ピクセルのグレースケール値 (または RGB 値) を指定したしきい値と比較し、しきい値より大きい (または小さい) ピクセル値を特定の値に設定し、ピクセル値を設定できます。しきい値より小さい (または大きい) 値は、別の特定の値に設定されます。以下では、画像のグレー値の 2 値化を例として、閾値演算の実行方法を紹介します。具体的なコードは次のとおりです。
import cv2
# 读取图像并转换为灰度图
img = cv2.imread('image.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 进行阈值操作
_, threshold_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)
# 显示原图和阈值化后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Threshold Image', threshold_img)
cv2.waitKey(0)
# 保存阈值化后的图像
cv2.imwrite('threshold_image.jpg', threshold_img)
wherecv2.threshold()
関数は、しきい値操作を実行するために使用されます。この関数の 2 番目のパラメータは指定されたしきい値、3 番目のパラメータはしきい値より大きいピクセル値、4 番目のパラメータはしきい値より小さいピクセル値です。
6 画像の畳み込みとフィルタリングの操作
画像の畳み込みとフィルタリング操作は、画像を平滑化および強調するための基本的な方法です。 cv2.filter2D()
関数を使用して、畳み込み演算とフィルタリング演算を実行できます。具体的なコードは次のとおりです。
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg')
# 定义滤波器
kernel = np.ones((5, 5), np.float32) / 25
# 进行滤波操作
filtered_img = cv2.filter2D(img, -1, kernel)
# 显示原图和滤波后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Filtered Image', filtered_img)
cv2.waitKey(0)
# 保存滤波后的图像
cv2.imwrite('filtered_image.jpg', filtered_img)
wherecv2.filter2D()
関数は、畳み込み演算とフィルタリング演算を実行するために使用されます。この例では、各ピクセル値が周囲の 5x5 領域のピクセル値の平均に等しい平均フィルターが使用されています
5. 高度な画像処理スキル
基本的な画像処理の知識を習得した後は、画像エッジ検出、特徴抽出、輪郭抽出、セグメンテーションと分離、形態学的操作などの高度な技術を学び続けることができます。このセクションでは、これらのテクニックの基本的な概念と実装方法を紹介します。
1 画像のエッジ検出
エッジ検出は画像処理における一般的なタスクです。その目的は、画像内の明確なエッジ、輪郭、または線を見つけることです。ソーベル オペレーター、ラプラシアン オペレーター、キャニー オペレーターなど、いくつかの特定のアルゴリズムを使用して画像エッジ検出を実装できます。以下では、Canny オペレーターを例として、画像のエッジ検出を実行する方法を紹介します。具体的なコードは次のとおりです。
import cv2
# 读取图像并转换为灰度图
img = cv2.imread('image.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 进行边缘检测
edges = cv2.Canny(gray_img, 100, 200)
# 显示原图和边缘检测后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
# 保存边缘检测后的图像
cv2.imwrite('edges.jpg', edges)
ここでcv2.Canny()
関数はエッジ検出に使用されます。この関数の 2 番目と 3 番目のパラメーターは指定されたしきい値で、エッジ検出の感度を制御するために使用されます。
2 画像の特徴抽出
画像特徴抽出は、画像内の情報を数値的な特徴に変換する処理方法です。画像認識、ターゲット検出などの分野で広く使用されています。 SIFT、SURF、ORB などの一般的に使用されるアルゴリズムを使用して、画像から特徴を抽出できます。以下では、SIFT アルゴリズムを例として、画像から特徴を抽出する方法を紹介します。具体的なコードは次のとおりです。
import cv2
# 读取图像并转换为灰度图
img = cv2.imread('image.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 初始化SIFT算法对象并提取图像的关键点和描述符
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(gray_img, None)
# 在图像中绘制关键点
res_img = cv2.drawKeypoints(img, keypoints, None)
# 显示原图和特征点标注后的图像
cv2.imshow('Original Image', img)
cv2.imshow('SIFT Features', res_img)
cv2.waitKey(0)
# 保存特征点标注后的图像
cv2.imwrite('sift_features.jpg', res_img)
ここでcv2.xfeatures2d.SIFT_create()
関数は SIFT アルゴリズム オブジェクトの初期化に使用され、sift.detectAndCompute()
関数は画像のキー ポイントと記述子を抽出するために使用されます。cv2.drawKeypoints()
関数は画像内のキーポイントを描画するために使用されます。
3 画像から輪郭を抽出する
輪郭抽出とは、画像の境界抽出と接続性チェックを実行して、画像内の輪郭形状を取得することを指します。 OpenCV ライブラリの cv2.findContours()
関数を使用して、画像から輪郭を抽出できます。具体的なコードは次のとおりです。
import cv2
# 读取图像并转换为灰度图
img = cv2.imread('image.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 进行边缘检测
edges = cv2.Canny(gray_img, 100, 200)
# 进行轮廓提取
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 在图像中绘制轮廓
res_img = cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
# 显示原图和绘制轮廓后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Contours', res_img)
cv2.waitKey(0)
# 保存绘制轮廓后的图像
cv2.imwrite('contours.jpg', res_img)
どこcv2.findContours()
関数は輪郭抽出に使用されます。この関数の 2 番目のパラメーターは輪郭の取得モードを指定し、3 番目のパラメーターは輪郭の近似方法を指定します。 >cv2.drawContours()
関数は、画像に輪郭を描画するために使用されます。
4 画像を分割して分離する
画像のセグメント化と分離は、複雑な画像を複数の独立した領域または画像に分割する処理方法です。GrabCut アルゴリズム、K 平均法アルゴリズムなど、いくつかのアルゴリズムを使用して画像をセグメント化して分離できます。以下では、例として K 平均法アルゴリズムを使用して、画像をセグメント化して分離する方法を紹介します。具体的なコードは次のとおりです。
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg')
# 获取图像像素并进行K-means聚类
pixel_values = img.reshape((-1, 3))
pixel_values = np.float32(pixel_values)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)
_, labels, center = cv2.kmeans(pixel_values, 5, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# 对图像进行分割和分离
center = np.uint8(center)
res_img = center[labels.flatten()]
res_img = res_img.reshape((img.shape))
# 显示原图和分割后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Segmented Image', res_img)
cv2.waitKey(0)
# 保存分割后的图像
cv2.imwrite('segmented_image.jpg', res_img)
ここでcv2.kmeans()
関数は、K 平均法クラスタリングを実行するために使用されます。この関数の 2 番目のパラメータはクラスタの数を指定し、3 番目のパラメータは初期化されたクラスタの中心です。< / a>np.uint8()
関数は、クラスター中心を符号なし 8 ビット整数に変換するために使用されます。
5 画像に対して形態学的操作を実行する
形態学的操作は一般的な画像処理方法です。画像の拡大、侵食、オープニング操作、クローズ操作などを実行でき、画像のノイズ除去、セグメンテーション、検出などのタスクに使用されます。 OpenCV ライブラリの cv2.erode()
、 cv2.dilate()
、 cv2.morphologyEx()
関数を使用して、画像に対して形態学的操作を実行できます。以下では、オープニング操作を例として、画像に対してモルフォロジー操作を実行する方法を紹介します。具体的なコードは次のとおりです。
import cv2
import numpy as np
# 读取图像并转换为灰度图
img = cv2.imread('image.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对图像进行二值化处理
_, binary_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)
# 进行开运算操作
kernel = np.ones((5, 5), np.uint8)
opened_img = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
# 显示原图和开运算后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Opened Image', opened_img)
cv2.waitKey(0)
# 保存开运算后的图像
cv2.imwrite('opened_image.jpg', opened_img)
このうち、cv2.threshold()
関数は画像の二値化処理に使用され、cv2.morphologyEx()
関数はモルフォロジー演算に使用されます。この関数は、操作のタイプを指定し、3 番目のパラメーターはカーネル関数を指定します。この例では、オープン操作に 5x5 all-1 カーネル関数が使用されます。
この時点で、画像エッジ検出、特徴抽出、輪郭抽出、セグメンテーションと分離、形態学的操作などを含む高度な画像処理技術を習得したことになります。これらの技術は、画像をより適切に処理し、より多くの画像特徴情報を提供するのに役立ち、後続の処理タスクの良い基盤を築くことができます。
6. 実例:OpenCVによる画像処理プロジェクトのデモ
1 顔認識の例
アルゴリズムの概要
顔認識は、画像やビデオに基づく自動認識技術です。画像処理では、通常、顔の検出と顔認識に顔の特徴に基づく分類器を使用します。 OpenCV は、Haar 分類器、LBP 分類器など、顔認識に基づく多くの分類器を提供します。これらの分類子を使用して、独自の顔認識システムを構築できます。
コード
# 导入OpenCV和numpy库
import cv2
import numpy as np
# 加载人脸分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 加载图片并转化为灰度图像
img = cv2.imread('img.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(gray, 1.2, 5)
# 绘制矩形框
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(0)
cv2.destroyAllWindows()
実装手順
まず、必要なライブラリをインポートする必要があります。cv2
モジュールは Python3.0 での OpenCV のインターフェイスであり、numpy
は科学技術コンピューティングです。ツールキット。ここでは配列処理に使用されます。
import cv2
import numpy as np
次に、すでにトレーニングされた顔分類器をロードする必要があります。ここでは Haar 分類子が使用されています。これは、OpenCV によって提供される CascadeClassifier
クラスを通じてロードできます。
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
次に、顔認識用の画像を読み込んでグレースケール画像に変換する必要があります。これは、グレースケール画像の方が計算量が少なく、処理速度が速いためです。 imread()
関数を使用して画像を読み込み、 cvtColor()
関数を使用して画像をグレースケール イメージに変換できます。
img = cv2.imread('img.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
次に、detectMultiScale()
関数を使用して写真内の顔を検出できます。この関数は写真内の複数のターゲットを検出するために使用されるため、カスケード検出器と呼ばれます。この関数は比較的複雑なので、パラメータを慎重に設定する必要があります。一般的なパラメータは次のとおりです:
gray
: グレースケール画像データを入力します。1.2
:画像の拡大縮小率を示します。5
: ターゲットの近傍の最小数を示します。つまり、顔を検出するには少なくとも 5 つが検出される必要があります。
faces = face_cascade.detectMultiScale(gray, 1.2, 5)
最後に、検出された顔を長方形の枠でマークします。このうち、 (x,y)
は長方形の枠の左上隅の座標を表し、 w
と h
は長方形の幅と高さを表します。長方形のフレーム。
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
最後にimshow()
関数を使用して最終画像を表示します。waitKey()
この関数はユーザーがキーボードのキーを押すのを待ちます。destroyAllWindows()
この関数は、開いているウィンドウをすべて閉じるために使用されます。
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2 動的ジェスチャ認識の例
アルゴリズムの概要
ジェスチャー認識は、画像やビデオに基づいた自動認識技術で、人間の手の動きを機械が認識できる言語や動作に変換し、より人間的で親しみやすいものにします。ジェスチャー認識技術はスマートホームや自動運転などの分野で広く活用され、人々の生活の重要な一部となっています。
コード
# 导入OpenCV和numpy库
import cv2
import numpy as np
# 常量定义
camera_width = 640
camera_height = 480
camera_fps = 30
# 手势分类器定义
gesture_cascade = cv2.CascadeClassifier('palm.xml')
# 打开摄像头
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
camera.set(cv2.CAP_PROP_FPS, camera_fps)
# 循环检测
while True:
# 读取当前帧
ret, frame = camera.read()
# 灰度转换
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 手势检测
gestures = gesture_cascade.detectMultiScale(gray, 1.3, 5)
# 绘制矩形框
for (x, y, w, h) in gestures:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 显示结果
cv2.imshow('Gesture detection', frame)
# 等待用户输入
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 关闭摄像头,并销毁所有窗口
camera.release()
cv2.destroyAllWindows()
実装手順
まず、必要なライブラリをインポートする必要があります。cv2
このモジュールは、Python3.0 での OpenCV のインターフェイスであり、ビデオ ストリームの収集と処理に使用されます。numpy
は科学計算ツールキットであり、ここでは配列処理に使用されます。
import cv2
import numpy as np
次に、カメラの電源をオンにしてパラメータを設定する必要があります。カメラを読み取る方法は、VideoCapture()
関数を使用することです。カメラ オブジェクトの set()
メソッドを呼び出すことで、フレーム レート、解像度、その他のパラメータを含むパラメータを構成できます。
camera_width = 640
camera_height = 480
camera_fps = 30
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
camera.set(cv2.CAP_PROP_FPS, camera_fps)
次に、トレーニングされたジェスチャ分類子をロードする必要があります。ここでは、palm.xml 分類子が使用されます。
gesture_cascade = cv2.CascadeClassifier('palm.xml')
次に、while ループで、カメラ内のビデオ フレームを継続的に読み取ることができます。次に、現在のビデオ フレームがグレースケール イメージに変換され、計算量を削減し、処理速度を向上させるために使用されます。次に、detectMultiScale()
関数を使用して、現在のフレーム内のジェスチャを検出します。この機能は、画像内の複数のオブジェクトを検出するために使用されるため、カスケード検出器と呼ばれます。共通パラメータは次のように説明されます。
gray
: 入力グレースケール画像。このパラメータはコードで設定する必要があります。1.3
: 画像の拡大縮小率を示します。5
: ターゲットの近傍の最小数を示します。つまり、ジェスチャとみなされるには少なくとも 5 つが検出される必要があります。
ret, frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gestures = gesture_cascade.detectMultiScale(gray, 1.3, 5)
最後に、検出されたジェスチャを長方形の枠でマークします。このうち、 (x, y)
は長方形の枠の左上隅の座標を表し、 w
と h
は長方形の幅と高さを表します。長方形のフレーム。
for (x, y, w, h) in gestures:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
最後に while ループの外側でカメラを閉じ、すべてのウィンドウを破棄します。
camera.release()
cv2.destroyAllWindows()
3 ビデオ監視と分析の例
アルゴリズムの概要
ビデオ監視および分析システムは、動体検出、顔認識、花火検出など、シーン内の人物や物体を自動的に検出、追跡、分析できます。
コード
# 导入OpenCV, numpy和datetime库
import cv2
import numpy as np
import datetime
# 常量定义
camera_width = 640
camera_height = 480
camera_fps = 30
# 打开摄像头
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
camera.set(cv2.CAP_PROP_FPS, camera_fps)
# 初始化运动检测器
foreground_detector = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=50)
# 循环处理每一帧
while True:
# 读取当前帧
ret, frame = camera.read()
# 转换图像为灰度图
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 移除背景并二值化
fgmask = foreground_detector.apply(gray)
fgmask = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY)[1]
# 膨胀并腐蚀处理
kernel = np.ones((5, 5), np.uint8)
fgmask = cv2.dilate(fgmask, kernel, iterations=2)
fgmask = cv2.erode(fgmask, kernel, iterations=2)
# 检测并绘制运动物体的边框
contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) < 500:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示结果
cv2.putText(frame, datetime.datetime.now().strftime('%A %d %B %Y %I:%M:%S%p'),
(10, camera_height - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
cv2.imshow('Video Surveillance', frame)
# 等待用户输入
if cv2.waitKey(1) == ord('q'):
break
# 关闭摄像头,并销毁所有窗口
camera.release()
cv2.destroyAllWindows()
実装手順
まず、必要なライブラリをインポートする必要があります。ここで紹介する cv2
モジュールは、ビデオ ストリームの収集と処理に使用される Python3.0 での OpenCV のインターフェイスです。numpy
は科学計算ツールキットです。ここでは配列処理に使用されます。datetime
は、ビデオ ストリーム上のビデオ フレームの日付と時刻のタグをサポートするために使用されるライブラリです。
import cv2
import numpy as np
import datetime
次に、カメラの電源をオンにしてパラメータを設定する必要があります。カメラを読み取る方法は、VideoCapture()
関数を使用することです。カメラ オブジェクトの set()
メソッドを呼び出すことで、フレーム レート、解像度、その他のパラメータを含むパラメータを構成できます。
camera_width = 640
camera_height = 480
camera_fps = 30
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)
camera.set(cv2.CAP_PROP_FPS, camera_fps)
その後、動き検出器を初期化する必要があります。コードでは createBackgroundSubtractorMOG2()
メソッドを使用して、混合ガウス (MOG2) に基づいて背景減算器を作成し、100 フレームの履歴と 50 の変更しきい値を設定しました。
foreground_detector = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=50)
次に、while ループでカメラ内のビデオ フレームを連続的に読み込んで多段階の処理を実行します。現在のビデオ フレームは、計算量を削減し、処理速度を向上させるために、まずグレースケール画像に変換されます。次に、apply()
関数を使用して、入力グレースケール画像から背景を削除します。減算された行列は次に 2 値化されます。
ret, frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = foreground_detector.apply(gray)
fgmask = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY)[1]
次に、オープン操作を使用してバイナリ イメージを拡張および侵食し、オブジェクトに付いている不純物ポイントを除去します。
kernel = np.ones((5, 5), np.uint8)
fgmask = cv2.dilate(fgmask, kernel, iterations=2)
fgmask = cv2.erode(fgmask, kernel, iterations=2)
次に、findContours()
関数を使用してバイナリ イメージ内の接続されたドメインを見つけ、境界線を描画します。境界線を引く場合は、まずその領域が検出条件を満たすかどうかを判断する必要があります。
contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) < 500:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
最後に while ループの外側でカメラを閉じ、すべてのウィンドウを破棄します。
camera.release()
cv2.destroyAllWindows()
現在のビデオ フレームがいつ処理されたかを示す日時タグframe
も追加しました。
cv2.putText(frame, datetime.datetime.now().strftime('%A %d %B %Y %I:%M:%S%p'),
(10, camera_height - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)