趣味の「カメラ」「バイク」をキャンプに絡めて、何かモノを作り上げることを主目的に記載をしています。 @engineer_osca. 物理的なモノに加えて、勉強がてらプログラムの作成も行って行きたいです。. >>> import cv2 >>> cv2.__version__ '4.1.1' 3 Webカメラの対応諸元. 基本的なことではありますが、「PythonとOpenCVを用いた動画から画像への変換」についてまとめておきます。フレームごとの画像への変換と、指定した間隔ごとの画像への変換をまとめます。 動画のプロパティを取得する まずは動画のプロパティを取得しておきます。 本稿では OpenCV ライブラリを利用して、コンピュータに接続された(内蔵された)カメラから動画を取得する方法について解説します。, まずは本稿を読み進めるのに重要な VideoCapture クラスについて説明します。 VideoCapture クラスは、カメラもしくは動画ファイルから画像データを取得することを責務とするクラスです。 VideoCapture クラスにはいくつものメソッドがありますが、本稿で利用するメソッドは次のものです。, それではさっそく、カメラから動画を取得して表示するプログラムを書いてみましょう。 プログラムは以下のようになります。, まずは cv2.VideoCapture() で VideoCapture オブジェクトを取得します。 引数にはコンピュータに接続されているカメラの番号を指定しています。 コンピュータにカメラが1台だけしか接続されていない場合には「0」を指定します。 もし複数のカメラが接続されている場合は「1」などの番号を指定します。, カメラから連続的に画像を取得するため、ここでは while 文で繰り返し処理を行います。 while 内の最初で、カメラから1コマのデータを取得するため capture.read() を呼び出しています。 取得した1コマの画像データは、変数 frame に代入されています。, OpenCV には、OSのフレーム(ウィンドウ)に画像を表示してくれる cv2.imshow() メソッドがあります。 第一引数は開くフレームの名前を文字列で指定します、特にどんな名前でも良いでしょう。 そして第二引数には、capture.read() で取得した画像データを指定します。 cv2.imshow() メソッドを呼び出すと、自動的にフレーム(ウィンドウ)が立ち上がって画像を表示してくれることでしょう。, 上のサンプルソースコードの while 内では、ループを止めるために「q」キーがタイプされたら break するための if 文を記述しています。(開かれたウィンドウにフォーカスがある状態で「q」キーをタイプします。) どのように while を抜けるかは、皆さんが好きなように決定してください。, while を抜けると、処理を終了させるために VideoCapture を終了して、開いたウィンドウも終了させます。, 本稿では OpenCV を利用して、コンピュータに接続したカメラから動画を取得する方法について解説しました。, Java, PHP 系のWEBエンジニア。 PythonとOpenCVを用いて複数の静止画から動画に変換する - 潔く銀のメモ的備忘録こんにちは、潔く銀です。 前回は、動画から静止画にするプログラムを作りました。今回は、その逆である静止画から動画にするプロyusei-roadstar.hatenablog.com 手持ちで撮影した複数枚連写写真の位置合わせを、PythonとOpenCVを使って行います。手持ちなのに、三脚使って連写したような画像を作ることが目的です。被写体も静止物と、微小な動きを伴ったものとを対象としていろいろ試した結果をまとめてみます。, このRenaさんをLenaさんに合わせて変換する。そんな処理です。どーでもいいですが、正解はLenaさんのようです。, これまでいろいろとスマホ、手持ち、オート、連写、で撮影した写真をソースにその合成をすることで画質の改善だったり、ちょっとしたエフェクトで遊んでました。, その際ポイントとなる画像処理の一つが、撮影した複数枚の写真の位置合わせです。そのまとめをします。, 連写した写真では、ある2枚の画像が時間的に離れている瞬間を撮影したものになります。その間カメラか被写体、あるいはその両者が動くことで、撮影された画像が微妙にずれます。このずれ方も、上下左右のシフト成分だけでなく、回転やあるいは拡大縮小も起こっている可能性があります。, このずれを補正する処理になります。これを補正して、あたかも三脚で撮影したかのような、動きが無い2枚の画像を作り、それらを合成することで、各種効果が得られます。, その位置合わせですが、いろいろ小難しい処理が必要になります。が、一番難しい部分はOpenCVが何とかしてくれます。中身を細かく理解しようと思うと論文行きですが、アプリケーションとして使うだけなら難しいことはありません。, ざっくりとは、ある画像から特徴的な箇所 (画像のエッジとか角とか) とその特徴量(傾斜とか)を求め、 別の画像からそれと同じ特徴を持つ箇所を見つけ出す。といった内容です。, この特徴量が、回転だったり拡大縮小、明るさの変化に対してロバストなすごい処理をどこかの天才が考え、どこかの天才がOpenCVに実装してくれているので、凡人はそれを使って遊ぶことができます。, 静止物を対象とした場合、このOpenCVに実装されている関数を基本そのまま使うだけで、あらかたできてしまいます。複数の動体を対象とした場合はもう少し工夫がいります。, 今回の実験に用いた写真は、スマホで、手持ちで、オートで、連写。なので手振れもあり、シャッター速度も環境によってまちまちです。ただ1枚1枚の写真はぶれていないことを前提としています。, いろいろなホームページで紹介されています。OpenCVのオフィシャルでも紹介されています。SIFTベースのアルゴリズムを使うものです。, ただこのSIFTは特許を取られているようで、OpenCVデフォルトでは動いてくれません。そこでパテントフリーな類似アルゴリズムであるAKAZEの方を使います。これだと追加インストールは不要です。関数のAPIが完全に同じなので簡単に性能比較もできそうです。, まずベースとなる、位置を合わせられたい方の画像の特徴量とその位置を取得します。この関数のインターフェースとしては、特徴量を求めたい画像の座標も指定するような作りにしています。画像の一部(例えば被写体の顔とか)を位置合わせしたい時を想定した引数です。座標を指定した部分位置合わせです。, どこぞのサンプルソースのままです。マスクの機能を使って、領域を絞っています。画素値が1(非ゼロ)のところだけ特徴量を出してくれるようです。rectangleのマスクを作っています。この関数の使い方としては、, 続いて、位置を合わせたい方の画像の特徴点を求め、先の特徴点とマッチングを取りますす。やはり公式にチュートリアルがあり、, これで、対応する座標のペアが取得できるので、そのペアから変換行列を求めます。今回はアフィン変換にします。一応射影変換も試したのですが、それほど差が出なかったので。あとバイリニアにしてます。Cubicの方がいいかもしれません。, この行列推定の関数ですが、昔はestimateRigidTransformという関数数だったようですが、新しいOpenCVのバージョンだと使えなくなっているみたいです。 昔は, これでbaseに位置が一致したframeが得られます。baseの特徴量取得を別関数にしているのは、2枚以上の画像をソースとした際に、毎度毎度baseの画像の特徴量を取得してたら処理時間かかってしょうがないので残しておくことにします。, こちらが難儀です。複数の動きを伴う連続画像を対象とすると、画像全体に対するアフィン変換や射影変換では対応できません。また、画像間の視差が大きいものもイマイチです。クールなのは機械学習から推定させるのかもしれませんが、今回は泥臭く行きます。, 基本思想は、小領域に分割して、その小領域単位で変換と微小位置合わせを繰り返すものです。隣接フレーム間の, を仮定します。あるベース画像と類似した隣接フレームの画像を取得し、位置合わせをします。言ってしまえばブロック単位に位置合わせをするだけ。, 小領域毎にアフィン行列推定さらに小さいブロック単位にアフィン行列補間ブロック単位にアフィン変換ブロック単位にパターンマッチング, まず全体に対して、静止物同様にAKAZEを使って、2枚の画像の特徴点ペアを作ります。上記静止物を対象とした処理と同じ関数です。, 静止画を対象とした際は、ベースの画像と合わせたい画像で、画像単位のマッチングを行っていましたが、合わせたい画像の方を16分割した小領域に分け、それぞれの小領域単位にマッチングを取ることにします。小領域の特徴量とベース画像の特徴量をマッチングし、その小領域ごとにアフィン行列を求め、16個のアフィン行列の列を作ります。, その後、画像をさらに細かく、ブロック(図では32×32画素)単位に分けます。そのブロック単位のアフィン行列を、マッチングで求めた16個のアフィン行列から補間します。, ここまでの処理で、各ブロックのアフィン行列が求まりますので、その行列を使ってアフィン変換を行います。これでブロック単位の画像がモザイク状に位置合わせがされます。, 微小な回転を伴っているイメージ。これに対して、さらにパターンマッチングを使って微調整をします。今回はブロックそのものをテンプレートに、上下左右32画素ずらしながら、最も相関が高い位置を探します。, 青い箇所が探索範囲で、その範囲をOpenCVの力を借りてパターンマッチングしています。, このままだと、ブロック境界がはっきりと見えてしまったので、ブロック開始座標をずらせるような作りにしました。複数枚合成する際に、そのブロック開始位置をずらしながら合成することで境界をぼかして目立たなくさせることができます。, 最後に画像に対してブロック分割する処理。ココでブロック開始位置をずらしたり、16個のアフィン行列を拡大したり、ブロック分割したりしてます。, 最後のこれが外部APIのイメージ。先の静止画を対象としたそれと似た見た目にしています。, ノイズを重畳したLenaさんと、傾き縮みほくろが2つついたRenaさんを用意しました。このRenaさんをLenaさんに位置合わせします。文字の位置も微妙にずらしてます。画像サイズは512×512 pixel。, 上記の関数群をalignment.pyとして外部ファイルにしたものをimportして使ってみました。, 気持ちいいくらいに位置が合いました。これくらいのノイズはなんてことはないですね。当たり前ですが、ほくろが消えたりRがLになるようなこともないです。, 一見見分けがつきません。ほくろが消え、RがLになっています。また隅っこの黒もなくなりました。拡大します。, ほくろの箇所です。消えたほくろは別の頬っぺたの箇所から補われました。見事にブロック状の影が見えます。鼻のエッジがずれています。, おでこのほくろの箇所は、近隣にマッチするブロックが見当たらなかったため、オリジナルのノイジーな箇所がそのまま使われています。ノイズブロックが出ています。, 文字部も同様。RとLで大外れしているのでオリジナルのノイジーブロックが使われています。aとかはRenaさんの方使ってもらえるかなぁと思ったのですが、文字をずらし過ぎたかもしれません。, 右下隅っこ。Renaさんの方には情報が存在しない箇所です。まったくない箇所はオリジナルのノイジーブロック、少し残っている箇所はブロック単位の位置合わせをしたうえで補っている様子が、ブロック状のスジとしてわかってしまいます。, 複数枚の連写写真を想定して、位置合わせを行い、あたかもカメラを三脚固定したかのような画像を作り出すことができました。, が、動体を対象としたブロック単位のマッチングではブロック境界が見えてしまいました。しょうがない。一応この対策として、ブロック開始座標をずらせるような関数にもしてあるので、ずらしながら複数回処理することで境界は幾分見えにくくなります。が処理は重たくなります。, 静止物を被写体とした時と、動体を被写体とした時で使い分ける必要があります。これらの処理で得られたずれの無い画像を元に、複数枚画像合成をすることで、いろいろ遊べます。この合成の処理で、上記のように出てしまったブロック状のノイズは消し去ります。なのでいったんこの段階でブロックが見えるのはしょうがないとします。, 位置が合っている前提のシンプルな合成と、手持ち、動体を対象にした合成とまとめてみました。, 次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。, とある電気メーカーのエンジニアをしています。ソフト屋さんです。ものを作るのが好きです。