Take the 2-minute tour ×

I am using openCV for Python, the cv2 library. I use the following function to compute the histogram of an image im_converted

hist = cv2.calcHist([im_converted], channels, None, histSize, ranges,hist, 1)

where im_converted is loaded as a numpy array of type uint8.

hist seems to be forced to be a numpy array of type float32. A problem arises when I use the backprojection function. (note: I normalize the histogram s.t np.sum(hist)=1)

backProj = cv2.calcBackProject([im_converted], channels, hist, ranges,scale);

The documentation is here. backProj is forced to be an uint8 numpy array.

  • if scale=1, then backProj = 0
  • if scale=255 then backProj is non zero, but the values are very small.

My question is: what is the scale factor that should be applied, given the differences between the types? Isn't there a way of changing the types? (note: I tried to do hist=zeros(histSize, dtype=uint8) but this was unsuccessful, I still got a float32 histogram in the end.)

share|improve this question

1 Answer 1

up vote 2 down vote accepted

This depends on your image size. If your image has more than 255 pixels, then a uint8 datatype for your histogram is not sufficient because the bins may oveflow.

It seems line OpenCV forces the datatype of the returned image from calcBackProject to be the same as image passed in. If you pass in a uint8 image but your float32 histogram has values larger than 255 your backprojection image may be clipped.

The most sane way of doing this appears to be keep the scale = 1.0 but pass in a float32 image to calcBackProject:

backProj = cv2.calcBackProject([im_converted.astype('float32')], channels, hist, ranges,scale)

The other alternative is to pass in uint8 image but set the scale to be 255. / hist.max(). Thus 255 in your backprojected image will correspond to the most frequent color.

share|improve this answer

Your Answer


