I'm trying to use the slider to control my lower and upper bounds for HSV masking. I'm able to get the slider but can't get it to hold the position I set; it keeps going back to zero each time a new frame is pulled in.
import numpy as np
import cv2
def nothing(x):
pass
cap = cv2.VideoCapture(0)
while(True):
# Make a window for the video feed
cv2.namedWindow('frame',cv2.CV_WINDOW_AUTOSIZE)
# Capture frame-by-frame
ret, frame = cap.read()
# Make the trackbar used for HSV masking
cv2.createTrackbar('HSV','frame',0,255,nothing)
# Name the variable used for mask bounds
j = cv2.getTrackbarPos('HSV','image')
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of color in HSV
lower = np.array([j-10,100,100])
upper = np.array([j+10,255,255])
# Threshold the HSV image to get only selected color
mask = cv2.inRange(hsv, lower, upper)
# Bitwise-AND mask the original image
res = cv2.bitwise_and(frame,frame, mask= mask)
# Display the resulting frame
cv2.imshow('frame',res)
# Press q to quit
if cv2.waitKey(3) & 0xFF == ord('q'):
break
# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()
You are creating track-bar inside while loop, that's why you are getting new track-bar on each frame.
So change your code like,
# Make a window for the video feed
cv2.namedWindow('frame',cv2.CV_WINDOW_AUTOSIZE)
# Make the trackbar used for HSV masking
cv2.createTrackbar('HSV','frame',0,255,nothing)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
........................
........................
Related
I’m using OpenCV3 and Python 3.7 to capture a live video stream from my webcam and I want to control the brightness and contrast. I cannot control the camera settings using OpenCV's cap.set(cv2.CAP_PROP_BRIGHTNESS, float) and cap.set(cv2.CAP_PROP_BRIGHTNESS, int) commands so I want to apply the contrast and brightness after each frame is read. The Numpy array of each captured image is (480, 640, 3). The following code properly displays the video stream without any attempt to change the brightness or contrast.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I get a washed-out video stream when I use Numpy’s clip() method to control the contrast and brightness, even when I set contrast = 1.0 (no change to contrast) and brightness = 0 (no change to brightness). Here is my attempt to control contrast and brightness.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
contrast = 1.0
brightness = 0
frame = np.clip(contrast * frame + brightness, 0, 255)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
How can I control the contrast and brightness of a video stream using OpenCV?
I found the solution using the numpy.clip() method and #fmw42 provided a solution using the cv2.normalize() method. I like the cv2.normalize() solution slightly better because it normalizes the pixel values to 0-255 rather than clip them at 0 or 255. Both solutions are provided here.
The cv2.normalize() solution:
Brightness - shift the alpha and beta values the same amount. Alpha
can be negative and beta can be higher than 255. (If alpha >= 255,
then the picture is white and if beta <= 0, then the picure is black.
Contrast - Widen or shorten the gap between alpha and beta.
Here is the code:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.normalize(frame, frame, 0, 255, cv2.NORM_MINMAX)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
The numpy.clip() solution:
This helped me solve the problem: How to fast change image brightness with python + OpenCV?. I need to:
Convert Red-Green Blue (RGB) to Hue-Saturation-Value (HSV) first
(“Value” is the same as “Brightness”)
“Slice” the Numpy array to the Value portion of the Numpy array and adjust brightness and contrast on that slice
Convert back from HSV to RGB.
Here is the working solution. Vary the contrast and brightness values. numpy.clip() ensures that all the pixel values remain between 0 and 255 in each on the channels (R, G, and B).
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
contrast = 1.25
brightness = 50
frame[:,:,2] = np.clip(contrast * frame[:,:,2] + brightness, 0, 255)
frame = cv2.cvtColor(frame, cv2.COLOR_HSV2BGR)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
import cv2 as cv
cap = cv.VideoCapture(0)
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# normalize the frame
frame = cv.normalize(
frame, None, alpha=0, beta=255, norm_type=cv.NORM_MINMAX, dtype=cv.CV_8UC1
)
# Display the resulting frame
cv.imshow("frame", frame)
# press q to quit
if cv.waitKey(1) & 0xFF == ord("q"):
break
I am trying to detect a (photography) flash in a video using OpenCV.
I detected the frame in which the flash occurs (average brightness above a threshold) and now I'd like to get the frame number.
I tried using CV_CAP_PROP_POS_FRAMES from the OpenCV docs without any success.
import numpy as np
import cv2
cap = cv2.VideoCapture('file.MOV')
while(cap.isOpened()):
ret, frame = cap.read()
BW = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)
average = np.average(v) #computes the average brightness
if average > 200: #flash is detected
cv2.imshow('frame',BW)
frameid = cap.get(CV_CAP_PROP_POS_FRAMES) # <--- this line does not work
print(frameid)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Any tips ?
You can either:
Use cap.get(cv2.CAP_PROP_POS_FRAMES) (see here, also), or
increment a variable at each iteration: its current value is the current frame number
From opencv-doc:
When querying a property that is not supported by the backend used by the VideoCapture class, value 0 is returned
Probably it is not supported. In that case you have to count the frame number yourself.
I'm brand new to OpenCV and I can't seem to find a way to do this (It probably has to do with me not knowing any of the specific lingo).
I'm looping through the frames of a video and pulling out a mask from the video where it is green-screened using inRange. I'm looking for a way to then insert an image into that location on the original frame. The code i'm using to pull the frames/mask is below.
import numpy as np
import cv2
cap = cv2.VideoCapture('vid.mov')
image = cv2.imread('photo.jpg')
# green digitally added not much variance
lower = np.array([0, 250, 0])
upper = np.array([10, 260, 10])
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame', frame)
# get mask of green area
mask = cv2.inRange(frame, lower, upper)
cv2.imshow('mask', mask)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Use Bitwise operations for masking and related binary operations. Please check below code to see how Bitwise operations are done.
Code
import numpy as np
import cv2
cap = cv2.VideoCapture('../video.mp4')
image = cv2.imread('photo.jpg')
# green digitally added not much variance
lower = np.array([0, 250, 0])
upper = np.array([10, 260, 10])
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
cv2.imshow('frame', frame)
# get mask of green area
mask = cv2.inRange(frame, lower, upper)
notMask = cv2.bitwise_not(mask)
imagePart=cv2.bitwise_and(image, image, mask = mask)
videoPart=cv2.bitwise_and(frame, frame, mask = notMask)
output = cv2.bitwise_or(imagePart, videoPart)
cv2.imshow('output', output)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
RGB bad color space
Since, you are doing color processing, I would suggest you to use appropriate color space. HSV would be a good start for you. For finding good range of HSV values, try this script.
Generating Video Output
You need a to create a video writer and once all image processing is done, write the processed frame to a new video. I am pretty sure, you cannot read and write to same video file.
Further see official docs here.
It has both examples of how to read and write video.
I'm currently learning how to use Open CV for python and I am trying to write a program to see an image in real time from a webcam based off of an hsv value range. When I run the program I am able to get the webcam to work (it shows a black screen as expected) but the trackbars to adjust the hsv range are not showing for some reason. Anyone have any solutions? Thanks.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
def nothing(x):
pass
#creates three trackbars for color change
cv2.createTrackbar('H','frame',0,255,nothing)
cv2.createTrackbar('S','frame',0,255,nothing)
cv2.createTrackbar('V','frame',0,255,nothing)
while(1):
# Capture frame-by-frame
_, frame = cap.read()
#creates trackbars
h = cv2.getTrackbarPos('H','frame')
s = cv2.getTrackbarPos('S','frame')
v = cv2.getTrackbarPos('V','frame')
# Converts from BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define color strenght parameters in HSV
weaker = np.array([h+10, s+10, v+10])
stronger = np.array([h-10,s-10,v-10])
# Threshold the HSV image to obtain input color
mask = cv2.inRange(hsv, weaker, stronger)
#displays mask
cv2.imshow('Result',mask)
#terminates program
if cv2.waitKey(1) == ord('q'):
break
cv2.waitKey(0)
cv2.destroyAllWindows()
The second argument of cv2.createTrackbar('H','frame',0,255,nothing) should be the name of the window that will show the trackbars. You've used frame, but there doesn't seem to be a window named frame opened in your code. You could do so by adding
cv2.namedWindow('frame')
or by changing your display line to
cv2.imshow('frame', mask)
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_green, upper_green)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
Note: i'm new to open cv ,so please help guys!!!
In this program
while reading a frame , why is there the symbol ' _, ' before frame
is it a syntax??
The lowerbound and upper bound of blue color is specified.
is that RGB values or BGR values or HSV values??
How can i find lower bound and upperbound of others colors like red,green?
Please explain the process of finding values of other colour ,i tried other colours but it gave me black screen output for hsv and res!!!
Can some one change this program to detect red color or other color so i can know the difference?
This is tuple unpacking; cap.read() returns two values, we assign the first to _ (convention for "we won't be using this") and the second to frame.
The comment literally says "in hsv".
You just need to specify your own bounds, or change the ones already there, and see the difference yourself. Use an HSV converter to see what colours you are using. If the colours within your range aren't in the image you process, it will be black.