https://zhuanlan.zhihu.com/p/42940310
参考資料
[1]ビデオオブジェクト検出および追跡----隣接フレーム間差分方式三の差分法を移動監視 - CSDNブログ
https://blog.csdn.net/dcrmg/article/details/52234929
[2]移動目標検出 - フレーム間の差分 - CSDNブログ
https://blog.csdn.net/tiemaxiaosu/article/details/51558830
フレーム差分法の原理に基づいている:隣接するフレーム(または隣接する3つの)グレースケールの差を有するとの間の映像に移動物体が存在する場合、グレースケール画像は、差、の2つの絶対値が得られます。差分画像に現れる静止物体が全て0であり、特定の移動体における移動物体の輪郭は、非ゼロ階調の存在下、絶対値がある閾値を超えた場合に達成するために、移動物体は、と判断することができるによる変化します検出対象。フレーム間差分アルゴリズムの利点は、簡単な、低プログラミングの複雑さであり、シーンの変化の少ない光に敏感であると同様に、比較的強い堅牢性と、動的な環境に適応することができます。欠点は、物体の全領域を抽出していないということである、「ホール」内のオブジェクトは、実際のオブジェクトよりもしばしば大きく、かなり厚い境界、境界輪郭を抽出することができます。ゴースト現象を起こしやすい高速移動するオブジェクトの、それがあっても、オブジェクトがほぼ完全に重なり合う2つのフロントとリア2つの異なる移動物体、物体スローモーションとして検出することができる、オブジェクトが検出できませんでした。したがって、この方法は、一般的に、単純なリアルタイム動き検出の場合にも適用可能です。ここに達成するには2つの方法と3つの方法について説明します。
2.隣接フレーム間差分
隣接フレーム間差分法は、2枚の隣接フレーム画像の差分演算に直接行われ、差分演算の絶対値は、典型的には、オブジェクト間有する、移動物体、高速計算の利点は、リアルタイム高、突然変異照明に対応しないという欠点を構成しています空にします。
コードは次のように実装されています。
#インポートに必要なパッケージ 輸入CV2 #入力ビデオファイルの初期化 ファイル名= "E:/opencv_vs/opencv/sources/samples/data/vtest.avi" カメラ= cv2.VideoCapture(ファイル名) #動画ファイル出力パラメータの設定 フレームレートout_fps = 12.0#出力ファイル FOURCC = cv2.VideoWriter_fourcc( 'M'、 'P'、 '4'、 '2') OUT1 = cv2.VideoWriter( 'E:/video/v1.avi'、FOURCC、out_fps、(500、400)) OUT2 = cv2.VideoWriter( 'E:/video/v2.avi'、FOURCC、out_fps、(500、400)) #フレームの前に現在のフレームを初期化します lastFrame =なし ビデオの各フレームを介して# しばらくcamera.isOpened(): #次のフレームを読みます (右フレーム)= camera.read() あなたが一つにクロールできない場合は#、我々は、ビデオの最後に説明しました RETない場合: ブレーク フレームサイズを調整する# フレーム= cv2.resize(フレーム、(500、400)、補間= cv2.INTER_CUBIC) #最初のフレームはなし、初期化された場合 lastFrameがNoneの場合: lastFrame =フレーム 継続する #計算異なる現在のフレームと前のフレーム、 frameDelta = cv2.absdiff(lastFrame、フレーム) 次のフレームに現在のフレームの前に#フレーム lastFrame = frame.copy() グレースケールに#結果 THRESH = cv2.cvtColor(frameDelta、cv2.COLOR_BGR2GRAY) #値化 THRESH = cv2.threshold(THRESH、25、255、cv2.THRESH_BINARY)[1] 「」」 #削除画像ノイズ、および最初の膨張をエッチング(形態学的開放動作) THRESH = cv2.erode(THRESH、なし、反復= 1) THRESH = cv2.dilate(THRESH、なし、反復= 2) 「」」 しきい値画像#上のプロファイルの位置 バイナリ、カーボンナノチューブ、階層= cv2.findContours(thresh.copy()、cv2.RETR_EXTERNAL、cv2.CHAIN_APPROX_SIMPLE) #トラバースプロフィール カーボンナノチューブにおけるC用: #小さなプロファイルを無視し、エラーを排除 cv2.contourArea(C)<300であれば: 継続する #計算された輪郭のバウンディングボックス、ボックスが現在のフレームに描画されています (X、Y、W、H)= cv2.boundingRect(C) cv2.rectangle(フレーム、(X、Y)、(X + W、Y +のH)、(0、255、0)、2) #現在のフレームを表示 cv2.imshow( "フレーム"、フレーム) cv2.imshow( "frameDelta"、frameDelta) cv2.imshow( "脱穀"、脱穀) #保存ビデオ out1.write(フレーム) out2.write(frameDelta) #qキーは、ループの外に押された場合 cv2.waitKey(200)&0xFFの== ORD( 'Q')の場合: ブレーク #クリーンアップリソースと、開いているウィンドウを閉じます out1.release() out2.release() camera.release() cv2.destroyAllWindows()
差分2つの2進1
二つの差分法の二値化2
2. 3つの差分法
3差分法は、隣接するフレーム差分アルゴリズムに基づいて改良され、ある程度、隣接より3差分法に比べて、両側移動物体、現象粗い輪郭を最適化しますフレーム差方法は、道路上のインテリジェントモニタリングビヒクルとして高速移動するオブジェクトの場合に、より適用可能です。
次の3つの基本的な違いの方法ステップである:第一に、2つのフレーム画像間の灰色の差、および現在のフレーム画像とグレースケール画像が行う前フレーム、1及び2は、ビット単位を行う「と」画像の最終結果との差の前に操作、クエを行いますターゲットを移動する価値判断とドロー。
コードは次のように実装されています。
#インポートに必要なパッケージ 輸入CV2 #入力ビデオファイルの初期化 ファイル名= "E:/opencv_vs/opencv/sources/samples/data/vtest.avi" カメラ= cv2.VideoCapture(ファイル名) #動画ファイル出力パラメータの設定 フレームレートout_fps = 12.0#出力ファイル FOURCC = cv2.VideoWriter_fourcc( 'M'、 'P'、 '4'、 '2') OUT1 = cv2.VideoWriter( 'E:/video/v3.avi'、FOURCC、out_fps、(500、400)) OUT2 = cv2.VideoWriter( 'E:/video/v4.avi'、FOURCC、out_fps、(500、400)) 元2つの#は、現在のフレームを初期化します lastFrame1 =なし lastFrame2 =なし ビデオの各フレームを介して# しばらくcamera.isOpened(): #次のフレームを読みます (右フレーム)= camera.read() あなたが一つにクロールできない場合は#、我々は、ビデオの最後に説明しました RETない場合: ブレーク フレームサイズを調整する# フレーム= cv2.resize(フレーム、(500、400)、補間= cv2.INTER_CUBIC) #最初の二つはいずれも、初期化、最初の二つの異なる計算されていない場合 lastFrame2がNoneの場合: lastFrame1がNoneの場合: lastFrame1 =フレーム そうしないと: lastFrame2 =フレーム グローバル変数グローバルframeDelta1の# frameDelta1 = cv2.absdiff(lastFrame1、lastFrame2)#フレーム差分 継続する 3つの差動を計算#計算された現在のフレームと前のフレーム差分 frameDelta2 = cv2.absdiff(lastFrame2、フレーム)は、2つのフレーム間の差# THRESH = cv2.bitwise_and(frameDelta1、frameDelta2)#画像計算 THRESH2 = thresh.copy() #次のフレームに現在のフレームの前のフレーム、前のフレームの前に次のフレームの前のフレームには、2つのフレーム間の差分は、差分をフレームに lastFrame1 = lastFrame2 lastFrame2 = frame.copy() frameDelta1 = frameDelta2 グレースケールに#結果 THRESH = cv2.cvtColor(THRESH、cv2.COLOR_BGR2GRAY) #値化 THRESH = cv2.threshold(THRESH、25、255、cv2.THRESH_BINARY)[1] #削除画像ノイズ、および最初の膨張をエッチング(形態学的開放動作) THRESH = cv2.dilate(THRESH、なし、反復= 3) THRESH = cv2.erode(THRESH、なし、反復= 1) しきい値画像#上のプロファイルの位置 バイナリ、カーボンナノチューブ、階層= cv2.findContours(thresh.copy()、cv2.RETR_EXTERNAL、cv2.CHAIN_APPROX_SIMPLE) #トラバースプロフィール カーボンナノチューブにおけるC用: #小さなプロファイルを無視し、エラーを排除 cv2.contourArea(C)<300であれば: 継続する #計算された輪郭のバウンディングボックス、ボックスが現在のフレームに描画されています (X、Y、W、H)= cv2.boundingRect(C) cv2.rectangle(フレーム、(X、Y)、(X + W、Y +のH)、(0、255、0)、2) #現在のフレームを表示 cv2.imshow( "フレーム"、フレーム) cv2.imshow( "脱穀"、脱穀) cv2.imshow( "threst2"、THRESH2) #保存ビデオ out1.write(フレーム) out2.write(THRESH2) #qキーは、ループの外に押された場合 cv2.waitKey(200)&0xFFの== ORD( 'Q')の場合: ブレーク #クリーンアップリソースと、開いているウィンドウを閉じます out1.release() out2.release() camera.release() cv2.destroyAllWindows()