Skip to content
Advertisement

Histogram of my cam in real time

Im trying to show the histogram in real time from grayscale of my webcam, the problem is that histogram is not being update and my cam stop until i close histogram’s window. How can i fix this? I want to show the grayscale img from my webcam and its histogram in same time, is possible do that?

import numpy as np
import cv2
from matplotlib import pyplot as plt

cap = cv2.VideoCapture(0)

while(True):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow('Janela', frame)
    cv2.imshow('Outra', gray)
    plt.hist(gray.ravel(), 256, [0, 256])
    plt.show()

    if (cv2.waitKey(1) & 0xFF == 27):
        break

cap.release()
cv2.destroyAllWindows()

Advertisement

Answer

I have been working for a while in the same task. After some time, I have a piece of code that works very good. It displays the camera image in a window and a histogram in other. Since I’m interested in finding colors, I’m working with the “hue” channel of each frame.

# import the necessary packages
import cv2
import numpy as np

#Create window to display image
cv2.namedWindow('colorhist', cv2.WINDOW_AUTOSIZE)

#Set hist parameters
hist_height = 64
hist_width = 256
nbins = 32
bin_width = hist_width/nbins

camera_id = 0 # type fo webcam [0 built-in | 1 external]
cameraWidth = 320
cameraHeight = 240

if camera_id == 0:
   cameraId = "PC webcam"
elif camera_id == 1:
   cameraId = "External webcam"

camera = cv2.VideoCapture(camera_id)

# set camera image to 320 x 240 pixels
camera.set(3,cameraWidth)
camera.set(4,cameraHeight)

cameraInfo = "Image size (%d,%d)" % (camera.get(3),camera.get(4))

# initialize mask matrix
mask = np.zeros((cameraHeight,cameraWidth),  np.uint8)

# draw a circle in mask matrix
cv2.circle(mask,(cameraWidth/2,cameraHeight/2), 50, 255, -1)

#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)

while True:
   # grab the current frame 
   (grabbed, frame) = camera.read()

   if not grabbed:
      "Camera could not be started."
      break

   hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
   #Calculate and normalise the histogram
   hist_hue = cv2.calcHist([hsv],[0],mask,[nbins],[0,256])
   cv2.normalize(hist_hue,hist_hue,hist_height,cv2.NORM_MINMAX)
   hist=np.int32(np.around(hist_hue))
   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('Color Histogram',h)
   h = np.zeros((hist_height,hist_width))

   frame = cv2.bitwise_and(frame,frame,mask = mask)
   cv2.putText(frame, cameraInfo, (10, 20),
    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

   cv2.imshow(cameraId, frame)            
   key = cv2.waitKey(1) & 0xFF

   # if the `q` key is pressed, break from the loop
   if key == ord("q"):
      break

camera.release()
cv2.destroyAllWindows()

The code is based on the code from JohnLinux post (How do I plot a 32-Bin Histogram for a Grayscale Image in Python using OpenCV) and other lines of code come from what I have learnt from Adrian Rosenbrock’s site https://www.pyimagesearch.com/.

Advertisement