Рисование гистограммы в OpenCV-Python - PullRequest
14 голосов
/ 22 февраля 2012

Я просто пытался нарисовать гистограмму, используя новый интерфейс OpenCV Python (cv2).

Ниже приведен код, который я пробовал:

import cv2
import numpy as np
import time

img = cv2.imread('zzz.jpg')
h = np.zeros((300,256,3))
b,g,r = cv2.split(img)
bins = np.arange(256).reshape(256,1)
color = [ (255,0,0),(0,255,0),(0,0,255) ]

for item,col in zip([b,g,r],color):
    hist_item = cv2.calcHist([item],[0],None,[256],[0,255])
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX)
    hist=np.int32(np.around(hist_item))
    pts = np.column_stack((bins,hist))
    cv2.polylines(h,[pts],False,col)

h=np.flipud(h)

cv2.imshow('colorhist',h)
cv2.waitKey(0)

И все работает отлично. Ниже приводится итоговая гистограмма, которую я получил.

enter image description here


Затем я немного изменил код.

т.е. изменил шестую строку в коде b,g,r = cv2.split(img) на b,g,r = img[:,:,0], img[:,:,1], img[:,:,2] (потому что он работает немного быстрее, чем cv2.split).

Теперь вывод - это что-то другое. Ниже вывод.

enter image description here


Я проверил значения b,g,r из обоих кодов. Они такие же.

Разница заключается в выводе cv2.calcHist. Результат hist_item отличается в обоих случаях.

Вопрос

Как это происходит? Почему результат cv2.calcHist отличается при одинаковых входах?

EDIT

Я попробовал другой код. Теперь, нудистая версия моего первого кода.

import cv2
import numpy as np

img = cv2.imread('zzz.jpg')
h = np.zeros((300,256,3))
b,g,r = img[:,:,0],img[:,:,1],img[:,:,2]
bins = np.arange(257)
bin = bins[0:-1]
color = [ (255,0,0),(0,255,0),(0,0,255) ]

for item,col in zip([b,g,r],color):
    N,bins = np.histogram(item,bins)
    v=N.max()
    N = np.int32(np.around((N*255)/v))
    N=N.reshape(256,1)
    pts = np.column_stack((bin,N))
    cv2.polylines(h,[pts],False,col,2)

h=np.flipud(h)

cv2.imshow('img',h)
cv2.waitKey(0)

И вывод такой же, как первый.

enter image description here

Вы можете получить мое оригинальное изображение здесь: zzz.jpg

Спасибо.

1 Ответ

13 голосов
/ 22 февраля 2012

Вы должны скопировать массив:

b,g,r = img[:,:,0].copy(), img[:,:,1].copy(), img[:,:,2].copy()

Но, поскольку calcHist () может принимать параметр channel, вам не нужно разбивать ваш img на три массива.

import cv2
import numpy as np

img = cv2.imread('zzzyj.jpg')
h = np.zeros((300,256,3))

bins = np.arange(256).reshape(256,1)
color = [ (255,0,0),(0,255,0),(0,0,255) ]

for ch, col in enumerate(color):
    hist_item = cv2.calcHist([img],[ch],None,[256],[0,255])
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX)
    hist=np.int32(np.around(hist_item))
    pts = np.column_stack((bins,hist))
    cv2.polylines(h,[pts],False,col)

h=np.flipud(h)

cv2.imshow('colorhist',h)
cv2.waitKey(0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...