2017-11-02 26 views
1

ヒストグラムの最高と最高の2つのピークの中間の値を探しようとしています。私は手動でこれを手動で行うことができますが、私は自動化された方法を作りたいと思います。私のヒストグラムを計算するために私が使用します。ヒストグラムの2つの最高ピークの中心値を見つけるPython

hist= cv2.calcHist([gray_scale_img], [0], None, [256], [0, 256]) 

これまでのところ、私は唯一のmax = np.argmax(hist)を使用して最大ピーク値をうまくする方法を考え出しました。私はイメージを付けました、赤は私が探しているものです。 HISTOGRAM IMAGE

+0

最大ピークを "どのように"調整するかを追加します。あなた自身のコードを多く表示するほど、より良いレスポンスが得られます。そうでなければ、回答は広がり、疑問は広がる –

+0

また、あなたの質問 –

+0

を使って、純粋にnp.argmax(hist)を使って学ぶ人もいます。最大ピーク値は – mDumple

答えて

1

ヒストグラムの上位2つのピーク(OpenCVとPython 3を使用)の間のインデックスと値を計算する方法は次のとおりです。

import numpy as np 
import cv2 

img = cv2.imread('../test.jpg', cv2.IMREAD_GRAYSCALE); 

#Compute histogram 
hist = cv2.calcHist([img], [0], None, [256], [0, 256]) 

#Convert histogram to simple list 
hist = [val[0] for val in hist]; 

#Generate a list of indices 
indices = list(range(0, 256)); 

#Descending sort-by-key with histogram value as key 
s = [(x,y) for y,x in sorted(zip(hist,indices), reverse=True)] 

#Index of highest peak in histogram 
index_of_highest_peak = s[0][0]; 

#Index of second highest peak in histogram 
index_of_second_highest_peak = s[1][0]; 


print(index_of_highest_peak) 
print(index_of_second_highest_peak) 

#If top 2 indices are adjacent to each other, there won't be a midpoint 
if abs(index_of_highest_peak - index_of_second_highest_peak) < 2: 
    raise Exception('Midpoint does not exist'); 
else: #Compute mid index 
    midpoint = int((index_of_highest_peak + index_of_second_highest_peak)/2.0); 



print('Index Between Top 2 Peaks = ', midpoint); 
print('Histogram Value At MidPoint = ', hist[midpoint]); 

私は、トップ2のピークが互いに隣接している場合、中間点は存在しないと仮定しました。必要に応じてこのケースを調整することができます。

0

あなたが試みているのは、Otsu thresholding algorithmとよく似ています。その場合、あなたはあなたのデータは強く三峰性であり、大津の方法が十分でない場合には、相手方は、3つのクラスタでkmeans clusteringを適用することであろう

ret, otsu = cv2.threshold(gray_scale_img , 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) 

を使用することができます。大津の方法とkmeansは、クラス内の分散を最小限に抑えてデータを分類します。コード内:

import numpy as np 
from sklearn.cluster import KMeans 
# Make trimodal data 
# (if image is large, consider downsampling it) 
n1 = np.random.normal(80, 10, 200) 
n2 = np.random.normal(120, 10, 200) 
n3 = np.random.normal(180, 10, 400) 
imflat = np.r_[n1, n2, n3] 
# shuffle and reshape 
np.random.shuffle(imflat) 
im = imflat.reshape(-1, 1) 
km = KMeans(n_clusters=3, random_state=0).fit(im) 
lab = km.labels_ 
# maxmimum data value in each cluster 
[im[np.argwhere(lab==i)].flatten().max() for i in range(3)] 

これは、3つのクラスタのどれがヒストグラム内で最高のピークを持つかを特定しません。不完全な解決に対する謝罪。もう1つの提案は、ヒストグラムに6次の多項式を当てはめて、ターニングポイントを見つけることです。

+0

ようこそ!私は大津の方法がOPの良いアプローチのように聞こえることに同意します。いくつかのドキュメントやチュートリアルへのリンクを追加することをお勧めします。将来、この質問を見ている人は、大津の方法がOPが求めていることをなぜ/どのように見ることができるでしょうか。 –

+0

良い直感ですが、大津は**バイモーダル**分布を前提としているので一般的には機能しません – Miki

関連する問題