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/.