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