Как использовать numpy.hist, когда я хочу появления индексов - PullRequest
0 голосов
/ 21 января 2019

У меня есть набор изображений, и я хочу создать гистограмму для значений оттенков каждого изображения.Поэтому я создал массив длиной 180. В каждую ячейку я добавляю 1, если значение оттенка на изображении.В конце концов, у меня есть массив с вхождением каждого значения оттенка, но когда я использую numpy.hist, ось Y - это значения оттенка, а ось X - вхождение.Но я хочу это наоборот.

Вот мой код:

path = 'path'
sub_path = 'subpath'

sumHueOcc = np.zeros((180, 1), dtype=int) 

print("sumHue Shape")
print(sumHueOcc.shape)

for item in dirs:
    fullpath = os.path.join(path,item)
    pathos = os.path.join(sub_path,item)
    if os.path.isfile(fullpath):
        img = np.array(Image.open(fullpath))

        f, e = os.path.splitext(pathos)

        imgHSV = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)

        print("Img shape")
        print(img.shape)

        # want to work with hue only
        h, s, v = cv2.split(imgHSV)

        # the hue values in one large array
        Z = h.reshape((-1, 1))
        # convert to np.float32
        Z = np.uint32(Z)

        # add 1 for each hue value in the image
        for z in Z:
            sumHueOcc[z] = sumHueOcc[z] + 1

        plt.figure(figsize=(9, 8))
        plt.subplot(311)  # Hue Picture 1
        plt.subplots_adjust(hspace=.5)
        plt.title("Hue Picture 1")
        plt.hist(np.ndarray.flatten(h), bins=180)
        plt.subplot(312)  # Hue Picture 2
        plt.subplots_adjust(hspace=.5)
        plt.title("Hue Picture 2")
        plt.hist(np.ndarray.flatten(Z), bins=180)
        plt.subplot(313)  # Hue Picture 2
        plt.subplots_adjust(hspace=.5)
        plt.title("Sum Occ")
        plt.hist(np.ndarray.flatten(sumHueOcc), bins=180)
        plt.show()

#First Hue Sum
plt.figure(figsize=(9,8))
plt.title("Sum Hue Occ")
plt.hist(np.ndarray.flatten(sumHueOcc), bins=180)
plt.show()

Вот код Berriels с изменением с Half Hue на Full Hue:

print(glob.glob('path with my 4 images'))

# list of paths to the images
image_fname_list = glob.glob('path with my 4 images')

# var to accumulate the histograms
total_hue_hist = np.zeros((359,))

for image_fname in image_fname_list:
    # load image
    img = cv2.imread(image_fname)
    # convert from BGR to HSV
    img = np.float32(img)
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
    # get the Hue channel
    #hue = img_hsv[:, :, 0]
    hue, sat, val = cv2.split(img_hsv)
    # show histogram
    hist, bin_edges = np.histogram(hue, bins=range(360))
    total_hue_hist += hist

plt.bar(list(range(359)), hist)
plt.show()

Сумма Occ должнабыть таким же, как Hue Picture 1 и 2

Первое из 4 изображений

Второе из 4 изображений

Третья из 4 фотографий

Последняя из 4 фотографий

Мой результат, который должен быть правильным

результат Berriels

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Я использовал другую альтернативу и поместил изображения в один большой вектор и использовал функцию numpy.hist для этого вектора. Затем я получаю правильную гистограмму для всех изображений.

path = 'path'
sub_path = 'subpath'

sumHueOcc2 = np.zeros((1, 1), dtype=np.uint64) 
i=0

for item in dirs:
    fullpath = os.path.join(path,item)
    pathos = os.path.join(sub_path,item)
    if os.path.isfile(fullpath):
        img = np.array(Image.open(fullpath))

        f, e = os.path.splitext(pathos)

        #imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        imgHSV = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) #numpy RGB

        # want to work with hue only
        h, s, v = cv2.split(imgHSV)

        # the hue values in one large array
        Z = h.reshape((-1, 1))
        # convert to np.float32
        Z = np.uint64(Z)

        # Huge vector of Images stack
        sumHueOcc2 = np.vstack((sumHueOcc2, Z))

        if i==0:
            sumHueOcc2 = np.delete(sumHueOcc2, (0), axis=0)
            i +=1


#Hue Sum for all images
plt.figure(figsize=(9,8))
plt.title("Sum Hue Occ")
plt.hist(np.ndarray.flatten(sumHueOcc2), bins=180)
plt.show()
0 голосов
/ 21 января 2019

Вы можете сделать это так:

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

# load image
img = cv2.imread('lenna.png')
# convert from BGR to HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# get the Hue channel
hue = img_hsv[:, :, 0]
# show histogram
hist, bin_edges = np.histogram(hue, bins=range(180))
plt.bar(bin_edges[:-1], hist)
plt.show()

Если вам не нужны значения гистограммы, вы можете сделать это следующим образом:

import cv2
import matplotlib.pyplot as plt

# load image
img = cv2.imread('lenna.png')
# convert from BGR to HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# get the Hue channel
hue = img_hsv[:, :, 0]
# show histogram
plt.hist(hue.flatten(), bins=range(180))
plt.show()

Ввод (lenna.png):

enter image description here

Выход:

enter image description here


Если у вас есть несколько изображений, вы можете сделать что-то вроде этого:

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

# list of paths to the images
image_fname_list = ['lenna.png', 'other_image.png', ...]

# var to accumulate the histograms
total_hue_hist = np.zeros((179,))

for image_fname in image_fname_list:
    # load image
    img = cv2.imread(image_fname)
    # convert from BGR to HSV
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    # get the Hue channel
    hue = img_hsv[:, :, 0]
    # show histogram
    hist, bin_edges = np.histogram(hue, bins=range(180))
    total_hue_hist += hist

plt.bar(list(range(179)), hist)
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...