2016-10-16 3 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() 

Мой вопрос, есть более ЭФФЕКТИВНЫЙ способ сделать массив частоты значений пикселей без использования для цикла?

+0

Там нет другого чем прохождение через каждое значение изображения, хотя векторизованное решение numpy будет на несколько порядков быстрее –

+0

Итак, вы не используете третью ось каналов, как у вас: 'y [img [i, j]]'? – Divakar

+0

Для этого вы можете использовать 'collections.Counter', хотя это может и не быть« ручным »для вас. – kindall

ответ

1

NumPy Векторизованных решение, основанное бы с np.bincount -

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 канала! Благодаря! –

Смежные вопросы