2012-02-22 11 views
14

Próbowałem tylko narysować histogram przy użyciu nowego interfejsu Python OpenCV (cv2).Histogram rysunkowy w OpenCV-Python

Poniżej znajduje się kod próbowałem:

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) 

i działa dobrze. Poniżej znajduje się uzyskany histogram i.

enter image description here


potem zmodyfikował kod trochę.

tj. Zmieniono szóstą linię w kodzie b,g,r = cv2.split(img) na b,g,r = img[:,:,0], img[:,:,1], img[:,:,2] (ponieważ działa nieco szybciej niż cv2.split).

Teraz wynik jest inny. Poniżej znajduje się wyjście.

enter image description here


Sprawdziłem wartości b,g,r z obu kodów. Są takie same.

Różnica leży na wyjściu cv2.calcHist. Wynik hist_item różni się w obu przypadkach.

Pytanie:

Jak to się stało? Dlaczego wynik cv2.calcHist jest inny, gdy dane wejściowe są takie same?

EDIT

Próbowałem inny kod. Teraz numpy wersja mojego pierwszego kodu.

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) 

A wynik jest taki sam jak pierwszy.

enter image description here

można dostać mój oryginalny obraz tutaj: zzz.jpg

Dziękuję.

Odpowiedz

11

Należy skopiować tablicę:

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

Ale ponieważ calcHist() może przyjmować parametr kanały, nie musisz podzielić img do trzeciej tablicy.

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) 
+0

Jaka jest potrzeba "kopiowania"? A co oznacza parametr calcHist() akceptacji kanału? Co to właściwie oznacza? –

+1

można wywołać 'cv2.calcHist ([img], [CH], None, [256], [0,255])', aby obliczyć histogram kanału CH img, czyli img [:,:, CH]. Musisz skopiować tablicę, ponieważ dane w img [:,:, 0] nie są ciągłe. – HYRY

+0

masz na myśli c_contiguous? Jakie jest jego znaczenie? –