Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing Histogram in OpenCV-Python

I was just trying to draw histogram using new OpenCV Python interface ( cv2 ).

Below is the code i tried:

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)

And it works fine. Below is the resulting histogram i obtained.

enter image description here


Then i modified the code a little bit.

ie changed the sixth line in code b,g,r = cv2.split(img) to b,g,r = img[:,:,0], img[:,:,1], img[:,:,2] (because it works a little faster than cv2.split).

Now the output is something different. Below is the output.

enter image description here


I checked the values of b,g,r from both the codes. They are same.

Difference lies in the output of cv2.calcHist. Result of hist_item is different in both the cases.

Question:

How does it happen? Why the result of cv2.calcHist is different when inputs are same?

EDIT

I tried a different code. Now, a numpy version of my first code.

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)

And the output is same as first one.

enter image description here

You can get my original image here: zzz.jpg

Thank you.

like image 326
Abid Rahman K Avatar asked Feb 22 '12 07:02

Abid Rahman K


People also ask

How do you make an image histogram in Python?

We can create histograms of images with the np. histogram function. We can separate the RGB channels of an image using slicing operations. We can display histograms using the matplotlib pyplot figure() , title() , xlabel() , ylabel() , xlim() , plot() , and show() functions.

How do you plot a histogram of grayscale images in python?

Here is the code for calculating the histogram of a full grayscale image. In this case, hist is a (256,1) array. Each value of the array corresponds to the number of pixels with the corresponding tone value. In this example, the matplotlib library is used to plot the histograms.


1 Answers

You should copy the array:

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

But, since calcHist() can accept channels parameter, you need not to split your img to three 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)
like image 180
HYRY Avatar answered Oct 11 '22 06:10

HYRY