質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.31%

Opencvを利用した特定の領域における画素の算出 グラフがplotされません(何度も質問申し訳ありません。使い方が分かってきたので連投させていただきます)

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,120

santamarianeed

score 21

指定した領域の画素値のプロット

何度も質問申し訳ありません。使い方が分かってきたので連投させていただきます。

私は今、ある18000フレームの動画をとっており、その動画内の特定の領域の発光強度を測定するプログラムをopencvを使って作っています。

作業として、指定した領域の最初の1フレームの各ピクセルごとの強度(R,G,Bを3で割る)を出し、それらを全て足し合わせ、全ピクセルの数で割り、これを18000フレームまで繰り返し行ないます。1フレームの強度を表す式は具体的に以下の式となります。

![イメージ説明

横軸をフレーム数、縦軸を強度(Intensity)を示したグラフをプロットしたいのですが何もプロットされません。
以下のプログラムを作成し、実行してみました。何か間違えているところがあればよろしくお願い致します

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

video_path = "movie.mkv"
cap = cv2.VideoCapture(video_path)


numS=raw_input("start frame:  ")
numS=int(numS)

numE=raw_input("end frame:  ")
numE=int(numE)

# 場所を決める

xmin=raw_input("左上のx座標:")
ymin=raw_input("左上のy座標:")
xmax=raw_input("右下のx座標:")
ymax=raw_input("右下のy座標:")

Xmin=int(xmin)
Ymin=int(ymin)
Xmax=int(xmax)
Ymax=int(ymax)

#初期ベクトルの設定
vIu=zeros((0)) # empty vector


for idx in range(numS,numE):
    cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
    res, fr = cap.read()
    In=0
    for i in range(Xmin,Xmax+1):
      for j in range(Ymin,Ymax+1):
          val =fr[i,j]
          I=sum(val)/3
          In +=I
          Intensity=In/((Xmax-Xmin+1)*(Ymax-Ymin+1))
          Intensity=append(vIu,Intensity)
          print(Intensity)
          print "flame number",idx




plt.plot(Intensity,linewidth=1,color="r")
plt.grid(True)
plt.xlabel("number of frame")
plt.ylabel("intensity of PL")
plt.legend(fontsize=17)
plt.xlim(numS,numE)
plt.ylim(0,255)
plt.show()
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • tiitoi

    2019/05/23 18:27

    以前にした質問のうち、解決または不要となったものはクローズしてください。

    キャンセル

回答 1

checkベストアンサー

0

平均の計算の部分は for 文を使わなくとも、
frame[ymin:ymax, xmin:xmax].mean() でいいと思います。

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

video_path = "Desktop/test.mp4"
cap = cv2.VideoCapture(video_path)

start = 0  # 開始フレーム No (include)
end = 100  # 終了フレーム No (exclude)
xmin, ymin = 10, 10  # 検出対象の矩形の左上の座標 (include)
xmax, ymax = 20, 20  # 検出対象の矩形の右下の座標 (exclude)

# フレーム [start, end) の範囲で各フレームの [ymin, ymax)x[xmin, xmax) の画素の平均を計算する。
frame_no = np.arange(start, end)
intensities = []
for i in frame_no:
    # フレーム i を取得する。
    cap.set(cv2.CAP_PROP_POS_FRAMES, i)
    ret, frame = cap.read()
    if not ret:
        print('Failed to grab frame.')
        break
    # 平均画素値を計算する。
    intensities.append(frame[ymin:ymax, xmin:xmax].mean())

# 描画する。
fig, ax = plt.subplots()
ax.plot(frame_no, intensities, lw=1, color='r')
ax.grid()
ax.set_xlabel('Frame')
ax.set_ylabel('Intensity of PL')
ax.legend(fontsize=17)
ax.set_ylim(0, 255)
plt.show()

イメージ説明

追記

縦方向がx で横方向がyではないのですか? 画像処理は左上を原点にして、縦がx軸、横がy軸と聞いたのですが、、、

左上原点は正しいですが、縦が y 軸、横が x 軸というのは変わりません。

イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/23 19:30 編集

    追記の画像の通り、画像座標系でも横がx軸、縦がy軸です。
    画像を表す numpy 配列は 縦x横xチャンネル数なので、切り出す場合は frame[縦方向の範囲, 横方向の範囲] となります。

    キャンセル

  • 2019/05/23 19:43

    最後に1つだけ質問ですが、試しに上のintensitiesをprint関数を使うことで以下のように画素値が表示されたのですが(10×10で合計121個のピクセル)、どのピクセルの画素値かどうかは分かりませんよね?

    [array([[[17, 13, 16],
    [17, 13, 16],
    [15, 11, 14],
    [15, 11, 14],
    [17, 13, 16],
    [18, 14, 17],
    [15, 15, 15],
    [15, 15, 15],
    [13, 13, 13],
    [12, 12, 12],
    [12, 12, 12]],

    [[17, 13, 16],
    [15, 11, 14],
    [14, 10, 13],
    [14, 10, 13],
    [15, 11, 14],
    [17, 13, 16],
    [15, 15, 15],
    [15, 15, 15],
    [15, 15, 15],
    [13, 13, 13],
    [11, 11, 11]],

    [[15, 11, 14],
    [14, 10, 13],
    [13, 9, 12],
    [13, 9, 12],
    [15, 11, 14],
    [17, 13, 16],
    [15, 15, 15],
    [15, 15, 15],
    [15, 15, 15],
    [13, 13, 13],
    [11, 11, 11]],

    [[15, 11, 14],
    [14, 10, 13],
    [13, 9, 12],
    [13, 9, 12],
    [15, 11, 14],
    [17, 13, 16],
    [15, 15, 15],
    [16, 16, 16],
    [16, 16, 16],
    [13, 13, 13],
    [11, 11, 11]],

    [[14, 9, 15],
    [13, 8, 14],
    [13, 9, 12],
    [13, 9, 12],
    [13, 9, 12],
    [14, 10, 13],
    [12, 12, 12],
    [12, 12, 12],
    [12, 12, 12],
    [12, 12, 12],
    [11, 11, 11]],

    [[14, 9, 15],
    [13, 8, 14],
    [13, 9, 12],
    [13, 9, 12],
    [13, 9, 12],
    [14, 10, 13],
    [13, 13, 13],
    [12, 12, 12],
    [12, 12, 12],
    [12, 12, 12],
    [11, 11, 11]],

    [[14, 9, 15],
    [13, 8, 14],
    [13, 9, 12],
    [13, 9, 12],
    [14, 10, 13],
    [14, 10, 13],
    [13, 13, 13],
    [13, 13, 13],
    [13, 13, 13],
    [12, 12, 12],
    [12, 12, 12]],

    [[14, 9, 15],
    [13, 8, 14],
    [13, 9, 12],
    [14, 10, 13],
    [14, 10, 13],
    [15, 11, 14],
    [15, 15, 15],
    [13, 13, 13],
    [13, 13, 13],
    [13, 13, 13],
    [12, 12, 12]],

    [[14, 9, 15],
    [13, 8, 14],
    [13, 9, 12],
    [14, 10, 13],
    [15, 11, 14],
    [15, 11, 14],
    [15, 15, 15],
    [15, 15, 15],
    [15, 15, 15],
    [13, 13, 13],
    [13, 13, 13]],

    [[13, 8, 14],
    [13, 8, 14],
    [13, 9, 12],
    [14, 10, 13],
    [15, 11, 14],
    [17, 13, 16],
    [16, 16, 16],
    [16, 16, 16],
    [15, 15, 15],
    [15, 15, 15],
    [15, 15, 15]],

    [[13, 9, 12],
    [13, 9, 12],
    [13, 9, 12],
    [14, 10, 13],
    [15, 11, 14],
    [17, 13, 16],
    [16, 16, 16],
    [16, 16, 16],
    [16, 16, 16],
    [16, 16, 16],
    [15, 15, 15]]], dtype=uint8)]

    キャンセル

  • 2019/05/23 21:35 編集

    > どのピクセルの画素値かどうかは分かりませんよね?
    わかりますよ

    print したのは、intensities ではなく、frame[ymin:ymax, xmin:xmax] ですよね?
    切り出した部分配列 x が (H, W, C) の形状だった場合、
    x[i, j] がその領域の (i, j) 成分の RGB 値を表します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.31%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • Opencvを利用した特定の領域における画素の算出 グラフがplotされません(何度も質問申し訳ありません。使い方が分かってきたので連投させていただきます)