问题
I have been having difficulty trying to generate a histogram for a 640x480 grayscale image I am working with.
I am using Python 2.7.3, OpenCV 2.4.6 (Python bindings) and Numpy
The image below was generated from the same image, using an executable software tool (programmed in C++)
The properties for this histogram were:
bins = 50
hist_width = 250
normalised_height_max = 50
The image specs are therefore 250x50
I have consulted this documentation:
Histogram Calculation in OpenCV http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html
Hist.py - OpenCV Python Samples https://github.com/Itseez/opencv/blob/master/samples/python2/hist.py
The code in the second reference compiles fine, yet I have tried to edit it to get these block style columns rather than the thin lines and I can't seem to get it right.
import cv2
import numpy as np
cv2.namedWindow('colorhist', cv2.CV_WINDOW_AUTOSIZE)
img = cv2.imread('sample_image.jpg')
h = np.zeros((50,256))
bins = np.arange(32).reshape(32,1)
hist_item = cv2.calcHist([img],0,None,[32],[0,256])
cv2.normalize(hist_item,hist_item,64,cv2.NORM_MINMAX)
hist=np.int32(np.around(hist_item))
pts = np.column_stack((bins,hist))
cv2.polylines(h,[pts],False,(255,255,255))
h=np.flipud(h)
cv2.imshow('colorhist',h)
cv2.waitKey(0)
I am aiming to make my histogram with the following specs:
bins = 32
hist_width = 256
normalised_height_max = 64
How can I fix this code in order to achieve a histogram like the one above with the specs specified?
回答1:
I have managed to solve the problem:
import cv2
import numpy as np
#Create window to display image
cv2.namedWindow('colorhist', cv2.CV_WINDOW_AUTOSIZE)
#Set hist parameters
hist_height = 64
hist_width = 256
nbins = 32
bin_width = hist_width/nbins
#Read image in grayscale mode
img = cv2.imread('sample_image.jpg',0)
#Create an empty image for the histogram
h = np.zeros((hist_height,hist_width))
#Create array for the bins
bins = np.arange(nbins,dtype=np.int32).reshape(nbins,1)
#Calculate and normalise the histogram
hist_item = cv2.calcHist([img],[0],None,[nbins],[0,256])
cv2.normalize(hist_item,hist_item,hist_height,cv2.NORM_MINMAX)
hist=np.int32(np.around(hist_item))
pts = np.column_stack((bins,hist))
#Loop through each bin and plot the rectangle in white
for x,y in enumerate(hist):
cv2.rectangle(h,(x*bin_width,y),(x*bin_width + bin_width-1,hist_height),(255),-1)
#Flip upside down
h=np.flipud(h)
#Show the histogram
cv2.imshow('colorhist',h)
cv2.waitKey(0)
This was the result:
Note that the bottom of the image is slightly different to the C++ implementation. I assume this is due to rounding somewhere in the code
来源:https://stackoverflow.com/questions/19203388/how-do-i-plot-a-32-bin-histogram-for-a-grayscale-image-in-python-using-opencv