2012-02-22 62 views
14

Estaba tratando de dibujar un histograma usando la nueva interfaz OpenCV Python (cv2).Dibujando histograma en OpenCV-Python

A continuación se muestra el código he intentado:

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) 

y trabaja muy bien. A continuación se muestra el histograma resultante que obtuve.

enter image description here


A continuación, he modificado el código un poco.

es decir, se cambió la sexta línea en el código b,g,r = cv2.split(img) por b,g,r = img[:,:,0], img[:,:,1], img[:,:,2] (porque funciona un poco más rápido que cv2.split).

Ahora la salida es algo diferente. Debajo está la salida.

enter image description here


comprobado que los valores de b,g,r tanto de los códigos. Son lo mismo.

La diferencia se encuentra en la salida de cv2.calcHist. El resultado de hist_item es diferente en ambos casos.

Pregunta:

¿Cómo es posible? ¿Por qué el resultado de cv2.calcHist es diferente cuando las entradas son las mismas?

EDITAR

He intentado un código diferente. Ahora, una versión numpy de mi primer código.

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) 

Y la salida es la misma que la primera.

enter image description here

Puede obtener mi imagen original aquí: zzz.jpg

Gracias.

Respuesta

11

debería copiar la matriz:

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

Pero, puesto calcHist() puede aceptar parámetros canales, no es necesario dividir su img a tres matriz.

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

¿Cuál es la necesidad de 'copy'? ¿Y qué se entiende por calcHist() aceptar parámetro de canal? ¿Qué significa en realidad? –

+1

puede llamar a 'cv2.calcHist ([img], [CH], None, [256], [0,255])' para calcular el histograma del canal CH de img, que es img [:,:, CH]. Debe copiar la matriz porque los datos en img [:,:, 0] no son continuos. – HYRY

+0

te refieres c_contiguous? ¿Cuál es su significado? –