Pythonを使ったOpenCVでの背景差分の数値化の方法 – python python3 opencv

質問:


Python3 OpenCV3で背景差分を求める

上記サイトの方法でPythonのOpenCVを使った背景差分画像の作成を行うことができたのですが、
画像の差分を数値化させ、その数値を使って一定以上であるか否かを行いたいのですが、方法が分からず困っています。
何か良い方法を教えていただけないでしょうか?
よろしくお願いします。

質問者: 蘭夢風吹

nohzen さんの回答に補足して、「全体の中で違う部分がどれだけあったのか」を調べるためには、たとえば配列 img_diffm の全要素の和を計算するという手法が考えられます。img_diffm の中身は (少なくとも最初の段階では) 同じか違うかの 0/1 配列なので、しきい値より上だったピクセルの数を和として数えることができます。全体のピクセル数で割れば、「違ったピクセル」の割合を計算することもできます。あとは割合のしきい値を決めて大小比較することで、前の画像に比べて大きく変わったのかどうかを判定することができます。

コメントでも言いましたが、質問内容の「画像の差分を数値化させ、その数値を使って一定以上であるか否か」を決めるという内容は、質問にあるリンク先のサイトで行われています。
なので、リンク先のサイトで行われている処理を解説します。
(質問者が何が分からないのか分からないのでなるべく基本から解説しましたが、もしまだ分からない部分があるなら、コメントしてください。追記します。)

画像の差分を数値化

まず、そもそもデジタル画像は2次元の数字(画素値)の並びとして表現されます。
これをI(x,y)と表すことにしましょう(x,yが座標で、Iが画素値)。
普通は画素値としては0 – 255の値が使われます。
2枚の画像I1, I2の差分を数値化するには、
I_diff(x,y) = |I1(x,y) – I2(x,y)|
とすればいいでしょう。
ここで、差分がマイナスになってしまうのを防ぐために絶対値を取っています。
これを実装するには、自分で

for y in range(width):
  for x in range(height): 
    I_diff[y,x] = abs(I1[y,x]-I2[y,x])

みたいな感じで実装してもいいのですが、そういった基本的な画像処理を使えるライブラリが存在して、その一つがOpenCVです。
OpenCV自体はc/c++で実装されていて、それをPythonからでも呼び出すことができます(当然c++から使うこともできます)。
自分でPythonでfor文などを使って実装するより高速に動くので、特別な理由がない限りOpenCVなどのライブラリを利用して画像処理をするのがおすすめです。
PythonからOpenCVを使うには、まず最初に

import cv2

でライブラリをインポートします。するとcv2.function_nameみたいな形でライブラリの関数を呼び出すことができます。
「差分を数値化」を行う関数がcv2.absdiffです。
従って、

img_diff = cv2.absdiff(img_src2, img_src1)

の部分で計算したimg_diffが「差分を数値化」した画像(差分画像)になっています。

その数値を使って一定以上であるか否か

「違う部分」を見つけるには、前節で計算した差分画像の値があるしきい値より大きい場合には「違う部分」とすればいいでしょう。
このように、0 or 1(今回の場合は「同じ部分」と「違う部分」)で表される画像に2値画像といい、何らかの処理で得た2値画像をマスクなどと言ったりもします。
違う部分を取り出す処理は

I_mask = 1 if I_diff(x,y) < threshold
         0 otherwise

となります。これもfor文などを使って自分で実装してもいいのですが、当然OpenCVにこの処理をしてくれる関数があり、cv2.threshold(img, thresh, maxVal, type)です(引数はここを参考に)。
リンク先では

img_diffm = cv2.threshold(img_diff, 20, 255, cv2.THRESH_BINARY)[1]

で「違う部分」を計算しているので、このimg_diffmが質問者が求めていた答えになります。

後処理

こういった差分画像に対するしきい値処理(2値化)で「違う部分」を求めると画像のノイズなどにより綺麗に「違う部分」が求められないことがあります。
そこで、リンク先では「膨張処理、収縮処理」を行うことで計算した「違う部分」を綺麗にしています。なぜ、膨張収縮処理で綺麗にできるかは例えばこちらを参考にしてください。
綺麗にしたり安定化させる方法は、リンク先の方法以外にもあり、例えば

  • 2値化を単純なしきい値処理から、大津の方法などに変える
  • Blurをかけてから2値化する

などが考えられます。
最後にリンク先では、「同じ部分」は黒で、「違う部分」は2つ目の入力画像にすることで可視化しています。

追記:
リンク先におかしいところがあったので修正しました。
リンク先ではカラーのまま2値化しているので、マスクもカラーになっています。
そのため、最後の出力もRGBごとにマスクがことなっていて、色が変になっています。
普通、2値化する前にグレー画像にします。
後処理は省略してます。

import cv2
import numpy as np
import matplotlib.pyplot as plt

img_src1 = cv2.imread("./image/dambo1.jpg", 1)
img_src2 = cv2.imread("./image/dambo2.jpg", 1)

img_diff = cv2.absdiff(img_src2, img_src1)
img_diff = cv2.cvtColor(img_diff, cv2.COLOR_BGR2GRAY)
img_diffm = cv2.threshold(img_diff, 20, 255, cv2.THRESH_BINARY)[1]

img_diff = cv2.cvtColor(img_diff, cv2.COLOR_GRAY2RGB)
img_diffm = cv2.cvtColor(img_diffm, cv2.COLOR_GRAY2RGB)
plt.subplot(121)
plt.imshow(img_diff)
plt.title("diff image")
plt.subplot(122)
plt.imshow(img_diffm)
plt.title("mask")
plt.show()

結果画像

出典

Related Posts:

NameErrorが出る – python
質問: 以下のコードを実行したいのですがエラーが出てしまいます。 解決方法を教えていただけると幸いです。 元のコードはdata-science-from-scratch/nearest_neighbors.pyにあります。 現在Pythonを学び始めたばかりなのですが、したいこととしてはk近傍方でk=1,3,5,7でどのような結果になるのか示したいと認識しています。 import math def knn_classify(k, labeled_points, new_point): """each labeled point should be a pair (point, label)""" # order the labeled ...
【Python3】Beautiful Soupについての質問 – python
質問: Beautiful Soupで <div class="hoge1"> <div class="hoge2"> <p>hogehoge</p> </div> </div> といったHTMLコードから<p>の部分を取得するにはどのようにしたら良いのでしょうか?   質問者: creamroid 下記ではいかがでしょうか。 from bs4 import BeautifulSoup html = """ <div class="hoge1"> ...
tensor flowのバージョンアップを行った結果、checkpointファイルのフォーマットが変更されている – python tensorflow
質問: tensorflowの学習モデルの出力フォーマットが以前のものとは変更されており、 model.ckptだけであったのが model.ckpt-1111.data-00000-of-000001, model.ckpt-1111.index, model.ckpt-1111.meta といった具合に3ファイルに変更されており対処に困っています。 どのckptファイルを参照するのか、またコード例が知りたいです。 ~~~下記は自分が使っているコードの一部です~~~ images_placeholder = tf.placeholder("float", shape=(None, IMG_PIXELS)) keep_prob = tf.placeholder("float") logits = inference(images_placeholder, keep_prob) sess = tf.InteractiveSession() saver = tf.train.Saver() sess.run(tf.global_variables_initializer()) saver.restore(sess, "model.ckpt") 質問者: nyannyan tensorflow r12よりcheckpointファイルのフォーマットが変更されております。 とりあえず過去フォーマットでsaveしたいのならば import tensorflow as tf from ...
jsonのtrueをTrueにしたい [クローズ済み] – python
質問: json = {"Hi":true} このHiのtrueをTrueにして論理演算できるようにしたいです。 質問者: たかなし json.dumps を使ってPythonのオブジェクトに変換できます。 >>> import json >>> d = json.loads('{"Hi":true}') >>> d {'Hi': True} 出典
tkinter の bad geometry specifier “200*100” というエラーの意味がよくわからない – python python3 tkinter
質問: このプログラムを実行しようとすると というメッセージが表示されます。 何が悪いのかよくわからないので一度Pythonをアンインストールして最新のPythonを再インストールしたのですが結果は変わりませんでした。 インストールする前のPathのチェック欄にはチェックを入れました。 すごく初歩的なことで恐縮ですが、お願いします。 質問者: 岸本真人 Kohei TAMURA 200*100ではなく、200x100ではないですかね。 tkinter の使い方は独特な所があり、色々とつまずくかも知れません。 使い方が解らないメソッドなどは help 関数などで説明を読むことができます。今回ですと、Pythonコード内で help(root.geometry) とすると、 Help on method wm_geometry in module tkinter: wm_geometry(newGeometry=None) method of ...
pythonからツイートの保存について – python twitter
質問: 下記のツイートを保存したいのですが上手くいきません。実行中でpython intento.py >> result.dat を書きました。 #-*- coding: utf-8 -*- from tweepy.streaming import StreamListener from tweepy import OAuthHandler from tweepy import Stream import json # Variables that contains the user credentials to ...
pythonパラメータエラーに関して(スクレイピング) – python
質問: いつもお世話になっております。 再度みなさまの知見をお借りしたく質問させていただきます。 ただいま、pyrhonでスクレイピングに挑戦をしていました。 実践しようとしているのはJRAのページの馬柱をスクレイピングしようとしていました。 url ='http://www.jra.go.jp/JRADB/accessD.html' fetched_dataframes = pandas.io.html.read_html(url) ...
異なるwebページからの情報取得を一本化したい – python
質問: 現在、Pythonを学習しています。 Google検索APIで「東京都 会社概要」と検索し、検索結果の各webページのURLを取得し、 それらのURL先をスクレイピングして会社概要を取得しようと考えています。 当たり前のことですが、各webページのhtmlの書き方が異なっていて、tableタグだったり、liタグだったりで上手く求めている情報を抽出できません。 何かアイデアがあれば教えて頂きたいです。 # コード1.googleAPI検索し、結果をjsonファイルに出力 import json import urllib.request import urllib.parse from urllib.request import urlopen QUERY = u'会社概要+東京都' key = 'KEY' cx = 'CX' NUM = 3 cseurl = 'https://www.googleapis.com/customsearch/v1?' params = ...
tensor flow をjupyter notebookで使っているんですがtensor boardが使えません。 – python tensorflow
質問: 初心者です。 tensor flow をjupyter notebookで使っているんですがtensor boardが使えません。 下記のプログラムをjupyter notebook上で打ち込んでtensorboad --logdir=/path/to/log をターミナルで打ち込みましたがうまくいきません。 教えてもらえると有難いです。 import tensorflow as tf import numpy as np import os LOG_DIR = os.path.join(os.path.dirname("__file__"), 'log') if os.path.exists(LOG_DIR) is False: os.mkdir(LOG_DIR) w ...
サイトが表示されません。 – python linux ubuntu
質問: https://github.com/blobmon/simplechan 上の掲示板をネット上に設置したのですが、ホーム画面は表示されるのですが、そこからクリックをして入ったら本来表示されるべきものが表示されません。クリックしたらこんなものが出てきます。 psycopg2.OperationalError OperationalError: FATAL: Peer authentication failed for user "simplech_role" Traceback (most recent call last) File "/root/simplechan/venv/lib/python2.7/site-packages/flask/app.py", line 2309, in __call__ return self.wsgi_app(environ, start_response) File "/root/simplechan/venv/lib/python2.7/site-packages/flask/app.py", line 2295, in ...
指定した通りに配列の要素を書き換えたい – python アルゴリズム
質問: 二次元配列の要素を、別の配列のデータに従って入れ替えたいです。 今、1つの配列に縦5横6の二次元配列があり、配列(array)の中身は全て "." で埋まっています。つまりarrayは array = [ , , , , # ←① ] となっています。 この "." を str_array 配列の数字に従って書き換えたいです。たとえば str_array が str_array ...
python3のエラー “TypeError: Tensors … that don’t all match” がわからない – python python3 tensorflow
質問: Traceback (most recent call last): File "/Users/oshikawaakinobu/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py", line 458, in _apply_op_helper raise TypeError() # All types should match. TypeError During handling ...
pip installコマンドでCould not open requirements file: [Errno 2] No such file or directory:というエラーが出る – python
質問: Colaというプログラムを使って、Weiboの投稿を取得したいです。pip install colaまではうまくいきますが 下記のコマンドを打つとエラーが表示されます。 エラーがなぜ起きるかわかる方がいれば教えてください。 # pip install -r/path/to/cola/app/weibo/requirements.txt Could not open requirements file: No such file or directory: '/path/to/cola/app/weibo/requirements.txt' 質問者: ...
ループ終了後に、結果を最後にまとめて取得したい – python
質問: 質問内容が分かりづらかったので、コードや欲しい結果を具体的に書きます ・再帰と勘違いしていたので、タイトルも変更しました 最終的にやりたいこと ・このリンク先にあるコード結果を、Bottleを使用してWeb画面上に表示したい 試したこと from urllib.request import urlopen from bs4 import BeautifulSoup import datetime import random import re from bottle import route, view random.seed(datetime.datetime.now()) def getLinks(articleUrl): html = urlopen("http://en.wikipedia.org"+articleUrl) ...
pyenvを使ってpythonをインストールしようとしているのですが。。。 – python
質問: pyenvを使ってMacにPythonの環境を構築する - Qiita このサイトに従ってpyenvを使ってpythonをインストールしようとしているのですがうまくいきません。 OSはmacの10.10.1です。 上記のサイトで言う所のpyenvにパスを通す、というところまではできたのですが、 その次のpyenvでpythonをインストールすることができません。 SSL/TLSが必要と出てきたのでぐぐってみたのですがいまいちよくわかりません。 どうすれば先に進めるでしょうか よろしくお願いします。 質問者: Kazutoshi Shinoda 3100 このあたりが参考になりそう。きっと良くなります。 pyenv のインストールメモ #python #mavericks - jitsu102's blog 出典

You Might Also Like

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です