Гистограмма рисования в OpenCV-Python
Я просто пытался рисовать гистограмму с использованием нового интерфейса 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
отличается, когда входы одинаковы?
ИЗМЕНИТЬ
Я попробовал другой код. Теперь, numpy версия моего первого кода.
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
Скопировать массив:
b,g,r = img[:,:,0].copy(), img[:,:,1].copy(), img[:,:,2].copy()
Но, поскольку calcHist() может принимать параметры каналов, вам не нужно разделить ваш 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)