動画をモノクロ映画っぽくする
動画をモノクロ映画っぽくします。カラーの動画ファイルを読み出し各フレームをグレースケール変換して動画として保存します。画像処理ライブラリOpenCVで動画ファイルを読み出し、フレーム毎の画像をcv2.cvtColorでグレースケール変換しその画像をつなぎ合わせて動画にします。さらにコントラストを強調することでよりモノクロ映画っぽくします。
環境
準備
動画ファイルはMixkitの "Annoyed man yelling at his wife"をダウンロードし320x180にリサイズしたうえでjupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名’yelling.mp4'で保存しました。このブログにはmp4ファイルが貼れないのでアニメーションgifファイルに変換したものを下に貼ります。
コード
cv2.cvtColorにより各フレームをグレースケール変換しmp4動画として保存します。
from PIL import Image import cv2 # gifファイル作成用イメージリスト images =[] # 動画ファイル作成用イメージリスト frames =[] # 動画ファイルのキャプチャー cap = cv2.VideoCapture('yelling.mp4') # フレームの幅取得 width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # フレームの高さ取得 height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # 総フレーム数取得 allframes = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 動画ファイルのフレームレート取得 fps = cap.get(cv2.CAP_PROP_FPS) # 保存用動画ファイルのフォーマット設定 fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') out = cv2.VideoWriter('monochrome.mp4', fourcc, fps, (int(width), int(height))) # 動画を1コマずつ取り込んで処理 while(cap.isOpened()): ret, frame = cap.read() # キャプチャー画像の取り込み if ret==True: # キャプチャー画像がある場合 # グレースケール変換 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # BGR変換(動画ファイルとチャンネル数を合わせるため) bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR) # VideoWriterにフレームを追加 out.write(bgr) # gifファイル作成用イメージリストにフレームを追加 images.append(Image.fromarray(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))) else: # キャプチャー画像がない場合はループ終了 break cap.release() # 再生画像をクローズ out.release() # 出力動画ファイルをクローズ # gif動画保存 images[0].save('monochrome.gif', save_all=True, append_images=images[1:], optimize=False, duration=1000/fps, loop=0)
実行結果
モノクロ変換された動画が保存されます。
コード
よりモノクロ映画っぽくするために画像のコントラストを強調します。cv2.equalizeHistでヒストグラム平坦化しコントラストを強調してからグレースケール変換します。
from PIL import Image import cv2 # gifファイル作成用イメージリスト images =[] # 動画ファイル作成用イメージリスト frames =[] # 動画ファイルのキャプチャー cap = cv2.VideoCapture('yelling.mp4') # フレームの幅取得 width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # フレームの高さ取得 height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # 総フレーム数取得 allframes = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 動画ファイルのフレームレート取得 fps = cap.get(cv2.CAP_PROP_FPS) # 保存用動画ファイルのフォーマット設定 fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') out = cv2.VideoWriter('monochrome_eq.mp4', fourcc, fps, (int(width), int(height))) # 動画を1コマずつ取り込んで処理 while(cap.isOpened()): ret, frame = cap.read() # キャプチャー画像の取り込み if ret==True: # キャプチャー画像がある場合 # 色空間をBGR->HSVに変換 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # equalizeHistによるヒストグラム平坦化 hsv[:, :, 2] = cv2.equalizeHist(hsv[:, :, 2]) # HSV->BGR変換 bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # グレースケール変換 gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY) # BGR変換(動画ファイルとチャンネル数を合わせるため) bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR) # VideoWriterにフレームを追加 out.write(bgr) # gifファイル作成用イメージリストにフレームを追加 images.append(Image.fromarray(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))) else: # キャプチャー画像がない場合はループ終了 break cap.release() # 再生画像をクローズ out.release() # 出力動画ファイルをクローズ # gif動画保存 images[0].save('monochrome_eq.gif', save_all=True, append_images=images[1:], optimize=False, duration=1000/fps, loop=0)
実行結果
コントラストが強調されより古い映画っぽくなります。
以下のサイトを参考にさせていただきました
Pythonの文法メモ > 【OpenCV】動画ファイルの読み出しとプロパティ取得、キャプチャー画像の保存
Pythonの文法メモ > 【OpenCV】ヒストグラム平坦化による画像コントラストの向上