2012-02-22 19 views
14

Stavo solo cercando di disegnare l'istogramma usando la nuova interfaccia OpenCV Python (cv2).Istogramma del disegno in OpenCV-Python

Di seguito si riporta il codice ho provato:

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) 

e funziona benissimo. Di seguito è riportato l'istogramma ottenuto.

enter image description here


Poi ho modificato il codice un po '.

cioè cambiato sesta riga nel codice b,g,r = cv2.split(img)-b,g,r = img[:,:,0], img[:,:,1], img[:,:,2] (perché funziona un po 'più veloce di cv2.split).

Ora l'uscita è qualcosa di diverso. Di seguito è riportato l'output.

enter image description here


ho controllato i valori di b,g,r da entrambi i codici. Sono uguali.

La differenza si trova nell'output di cv2.calcHist. Il risultato di hist_item è diverso in entrambi i casi.

Domanda:

Come mai? Perché il risultato di cv2.calcHist è diverso quando gli input sono gli stessi?

EDIT

ho provato un codice diverso. Ora, una versione numpy del mio primo codice.

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) 

E l'uscita è uguale alla prima.

enter image description here

È possibile ottenere la mia immagine originale qui: zzz.jpg

Grazie.

risposta

11

è necessario copiare l'array:

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

Ma, dal momento che calcHist() può accettare parametri canali, non c'è bisogno di dividere l'img a tre array.

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

Qual è la necessità di 'copia'? E cosa si intende per calcHist() accetta il parametro del canale? Cosa indica in realtà? –

+1

puoi chiamare 'cv2.calcHist ([img], [CH], None, [256], [0,255])' per calcolare l'istogramma del canale CH di img, cioè img [:,:, CH]. Devi copiare l'array perché i dati in img [:,:, 0] non sono continui. – HYRY

+0

intendi c_contiguous? Qual è il suo significato? –