2017-09-29 19 views
0

OpenCVのcalcHist()から返された3Dヒストグラムは正確には何ですか?OpenCV 3Dヒストグラム3軸ヒストグラムですか?

1dヒストグラムについて私はそれを知っています:
- x軸は私の希望するビンを表しています(簡略化のため、0-255 - グレースケールのカラー値を示しています)。
- y軸は、そのビン/カラー値を持つピクセルの数を表します。

3Dヒストグラムの場合は、これを修正します:
- 3つのx軸配列がありますか?各色チャンネルごとに1つ(私の場合はb、g、r)?
- 3つのy軸配列がありますか?上記のそれぞれについて1つ?

OR

  • のみ1、x及びy軸は、依然として存在します。しかし、x軸はb * g * rの連結(?)を表し、y軸は色数b * g * rのピクセル数を表します。

は、その最初のシナリオ場合、OpenCVのは、への道を持っています:
- (16進数またはb *表Gの* rを組み合わせる?)色を表す一意の番号を生成しますか?
- x軸のビンが上記の固有の色番号を表し、y軸がその色を持つピクセルの数を示している3チャンネル画像のヒストグラムを作成しますか?
- おそらく、255ビンの3Dヒストグラムを持つより計算効率が高いでしょうか?

答えて

0

OpenCVのcalcHist()は任意の**数の画像/チャンネルのヒストグラムを計算できます。返されるヒストグラムは、入力画像内のチャンネル数と同数の軸を持ち、各軸は、そのチャンネル用に指定されたビンと同数の値を持ちます。たとえば、RGBDイメージがあるとします。つまり、赤、青、緑、深度の4つのチャンネルがあります。あなたは、このような画像のヒストグラムを計算何らかの理由したい場合は、OpenCVのは、次のことができます。

import cv2 
import numpy as np 

img = cv2.imread('lane.jpg') 
img = np.dstack([img, img[:, :, 0]]) 
print('Input image shape:', img.shape) 
n_channels = img.shape[2] 
channels = list(range(n_channels)) 
sizes = [8,]*n_channels 
ranges = [0, 255]*n_channels 
hist = cv2.calcHist(img, channels, None, sizes, ranges) 
print('Output histogram shape: ', hist.shape) 

入力画像形状:(540、960、4)

出力ヒストグラムの形状:(8、 8,8,8)

np.dstack([img, img[:, :, 0]])私は、単に画像の最後に4番目のチャンネルとして最初のチャンネルを追加しています。あなたは9のチャネルの深さで画像上で実行するようにプログラムを変更し、出力9Dヒストグラムを得ることができます:

img = cv2.imread('lane.jpg') 
img = np.dstack([img, img, img]) 
print('Input image shape:', img.shape) 
n_channels = img.shape[2] 
channels = list(range(n_channels)) 
sizes = [8,]*n_channels 
ranges = [0, 255]*n_channels 
hist = cv2.calcHist(img, channels, None, sizes, ranges) 
print('Output histogram shape: ', hist.shape) 

入力画像形状:(540、960、9)

出力ヒストグラムを形状:(8,8、8,8、8,8、8,8、8)ここ

のみ変形Iは単純で画像を作成する画像を3回積層dstackラインに再度ました9チャンネル。

マルチチャンネル配列の場合、軸が少し違うと思っています。 xyなどと呼ぶのではなく、ch1bins, ch2bins, ...というように、それぞれのチャネルからbinsと考える必要があります。単一チャンネルの画像のヒストグラムを取る場合は、確かめてください。 プロットの場合、x軸にはビンがあり、y軸にはカウントがありますが、これはプロットする方法です。実際には、ビンの配列と数の配列を持っています。 2チャンネル画像のヒストグラムをプロットして3D棒グラフで視覚化した場合、x軸にはビンがありますが、y軸にも同様の軸があり、その場合はz軸にカウントがあります。 x軸には最初のチャネルのビンがあり、y軸には2番目のチャネルのビンがあります。 3チャンネルの画像を持っていて、プロットで視覚化するには、3つの軸すべてが各チャンネルに対応するビンであるため、各ビンの数量を他のもので視覚化する必要があります。そのビン、または強度や何かに基づいてマーカーを色付けする必要があります。

OpenCV docs for calcHist()には、色相と彩度のヒストグラムを分析できる2Dヒストグラム(つまり、2チャネル)の例があります。つまり、ある色相と彩度の範囲(0〜32の色相、および144と176の彩度)に対して、その範囲内のピクセル数を確認できます。

3Dヒストグラムの例については、check out some I've plottedとすることができます。ヒストグラムにOpenCVを使用しなかったのは...あなたがこの質問をするまで3Dヒストグラムを行うことができたのは実際にはわかりませんでした。しかし、numpyはOpenCVのようにD次元のヒストグラムをすべて同じにすることができます。これらのプロットでは、マーカーの色はbinが表す実際の色に対応し、マーカーのサイズは各ビンの値の数にいくらか対応します。

3Dヒストグラムを取って、各チャンネルの暗くて明るいカウントを知りたいとしましょう。だから各チャンネルの2つのビンだけでヒストグラムを取る。その後、私のビンは次のようになります。

  • チャンネル0:[0, 127], [128, 255]
  • チャンネル1:[0, 127], [128, 255]
  • チャンネル2:[0, 127], [128, 255]

は値[0, 255, 0]でピクセルを取ります。これは、チャネル0のビン0、チャネル1のビン1、チャネル3のビン0に対応します。そこにはどれだけの可能性がありますか?画素がビンであり得る:

  • 0、0、0
  • 0、0、1
  • 0、1、0
  • 0、1、1
  • 1,0,0
  • 1、0、1
  • 1、1、0
  • 1、1、1

8つの可能性があります。すべてのRGB値を3空間にプロットすると、これらの軸のそれぞれを2つに分割すると、8つのヒストグラムビンが得られます。次に、これらの8つのビンのそれぞれの数を単純に数えます。これがヒストグラムです。上記のリストを見ると、この単純なヒストグラムは、ビン0、0、0に対応するダークピクセルの数、ライトピクセルの数(1,1,1に対応する)、ほとんど緑の数ピクセルには(0,1,0)などがあります。そして実際これは、OpenCVのは与えるものである:

img = cv2.imread('lane.jpg') 
print('Input image shape:', img.shape) 
n_channels = img.shape[2] 
channels = list(range(n_channels)) 
sizes = [2, 2, 2] 
ranges = [0, 255]*n_channels 
hist = cv2.calcHist(img, channels, None, sizes, ranges) 
print('Output histogram shape: ', hist.shape) 

入力画像形状:(540、960、3)

出力ヒストグラムの形状:(2、2、2)

マルチチャネルヒストグラムの全体的なポイントは、各チャネルごとにいくつかの値の範囲内にいくつのピクセルがあるか把握することです。うまくいけば、このポストはそれをいくつかクリアしました!

**注:チャンネル数が多い小さなビンサイズを使用しないでください。メモリが不足している場合はすぐに使い果たします。

関連する問題