cv2.calcHist - sum of histogram does not equal pixel count

asked 2014-03-28 09:37:43 -0500

slychief gravatar image

updated 2014-03-29 07:41:59 -0500

Hi,

I just observed a strange behaviour of cv2.calcHist. When calculating the sum of all bin-values it sometimes does not add up to the number of pixels of an image.

img = cv2.imread("Lenna.png")
print img.shape

# => (512L, 512L, 3L)

for i in range(3):
    hist = cv2.calcHist([img], [i], None, [256], [0,255])
    print np.sum(hist)

# => 262144.0
# => 262144.0
# => 262032.0

The number of pixels in each channel should be 262144, which is correct for the blue and green channel. The value of the red channel differes by 112. This seems to be a serious bug at least in the Python wrapper. I currently have no time to reproduce this in C++.

I am using OpenCV-Python 2.4.8 (64Bit) compiled for Windows by Christoph Gohlke: http://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv and Numpy 1.7.1

The error remains also after updating to Opencv 2.4.8.1 and Numpy 1.8.1

The image used was: http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png

edit 2014-03-29:

Some more debug data. The following two histograms have been created for the red channel. The first one is the result of the OpenCV function, the second was calculated using Numpy.

OpenCV:

print cv2.calcHist([img], [2], None, [256], [0,255]).astype(np.int).transpose()

[   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
    0    0    0    0    0    0    0    0    0    1    0    1    1    1    8
    6   10    9   20   37   32   41   53   74  103  132  179  193  242  238
  336  386  404  483  607  628  771  785 1001 1016 1177 1269 1332 1446 1487
 1457 1574 1585 1591 1557 1569 1660 1648 1420 1559 1418 1384 1319 1342 1156
 1120  955  969  828  782  752  737  719  700  628  673  587  617  610  592
  557  593  552  566  582  559  571  520  664  650  618  730  594  667  675
  685  771  715  667  740  744  766  765  772  817  817  744  806  760  777
  812  797  799  861  814  910  907  918  888 1011  879  996  912  952  884
 1074  977 1073 1040 1216 1250 1403 1534 1639 1682 1776 1874 1769 1582 1743
 1441 1477 1483 1409 1437 1449 1389 1479 1592 1655 1657 1666 1857 1896 1813
 1979 1814 1956 1928 2055 2012 2303 2333 2670 2787 3232 3154 3476 3424 3516
 3102 3176 2787 2885 2630 2731 2664 2955 2955 3360 3554 4138 3987 4057 4327
 3713 3185 2929 2551 2432 2195 2256 1960 2126 2186 2265 2417 2445 2282 1826
 1972 1456 1137  986  748  749  667  582  428  357  313  302  242  178   67
    0]

Numpy:

hist, _ = np.histogram(img[:,:,i],np.arange(0,257))
print hist

[   0    0    0    0    0    0    0    0    0 ...
(more)
edit retag flag offensive close merge delete

Comments

added further debugging output to the question body

slychief gravatar imageslychief ( 2014-03-29 07:40:28 -0500 )edit

Just noticed: the values of the last Numpy histogram bins of the other channels are all zero. This explains why the OpenCV results for the green and blue channel are not influenced.

slychief gravatar imageslychief ( 2014-03-29 07:48:45 -0500 )edit
1

the right border in the range is exclusive. ( so you don't fill the last bin there )

hist = cv2.calcHist([img], [i], None, [256], [0,256])

gives the correct result for all 3 channels

berak gravatar imageberak ( 2014-03-29 08:06:18 -0500 )edit

Just confirmed berak's comment. Values for all 3 channels are correct! Thanks! It's yet not clear to me why it is implemented that way, but since it is similar to Numpy, there seems to be a reason - even if it's just to be similar to numpy...

@berak: Kudos! Would you like to give the answer?

slychief gravatar imageslychief ( 2014-03-29 08:37:01 -0500 )edit