2016-10-16 10 views
1

Matplotlibヒスト機能を組み込んでいない画像のヒストグラムを表示できるコードを記述したいと思います。ここでPythonで画像ヒストグラムを手動で効率的に作成

は私のコードです:

import cv2 as cv 
import numpy as np 
from matplotlib import pyplot as plt 

def manHist(img): 
    row, col = img.shape # img is a grayscale image 
    y = np.zeros((256), np.uint64) 
    for i in range(0,row): 
     for j in range(0,col): 
     y[img[i,j]] += 1 
    x = np.arange(0,256) 
    plt.bar(x,y,color="gray",align="center") 
    plt.show() 

def main(): 
    img = cv.imread("C:/Users/Kadek/Documents/MATLAB/2GS.jpg") 
    manHist(img) 

main() 

私の質問は、forループを使用せずに、画素値周波数の配列を作るために、よりefficentの方法は何ですか?

A numpyのベースベクトル化ソリューションは np.bincountとなり
+0

を他はありませんイメージ内のすべての値を歩くよりも、ベクトル化されていますnumpyの解が数桁速くなります –

+0

したがって、チャンネルの3番目の軸を使っていません: 'y [img [i、j]]'? – Divakar

+0

これは 'collections.Counter'を使っても構いませんが、それはあなたには「マニュアル」ではないかもしれません。 – kindall

答えて

1

-

out = np.bincount(img.ravel(),minlength=256) 

.sum()に基づいて別のベクトル化のアプローチ - 結果を確認するために

out = (img.ravel() == np.arange(256)[:,None]).sum(1) 

サンプル実行 -

In [155]: # Input image (512x512) as array 
    ...: img = np.random.randint(0,255,(512,512)) 
    ...: 
    ...: # Original code 
    ...: row, col = img.shape 
    ...: y = np.zeros((256), np.uint64) 
    ...: for i in range(0,row): 
    ...:  for j in range(0,col): 
    ...:   y[img[i,j]] += 1 
    ...:   

In [156]: out1 = np.bincount(img.ravel(),minlength=256) 

In [157]: out2 = (img.ravel() == np.arange(256)[:,None]).sum(1) 

In [158]: np.allclose(y,out1) 
Out[158]: True 

In [159]: np.allclose(y,out2) 
Out[159]: True 
+0

は両方ともコードでfalseを返します。私はあなたのようにまったく同じように書いています。 –

+0

@KadekDwiBudiUtamaあなたは 'row、col = img.shape'でなければならないかどうか、コメントの質問で答えていませんか? – Divakar

+0

ああ、申し訳ありません。 1つのチャンネルだけを使用した後の作業です!ありがとう! –

関連する問題