My camera is sporting 'GREY' and 'Y16' formats.
the output of v4l2-ctl --list-formats -d 0 # 0 is video0 is:
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'GREY' (8-bit Greyscale)
[1]: 'Y16 ' (16-bit Greyscale)
now if i use basic code of video streaming
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('/dev/video0')
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
it is returning black image
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('G','R','E','Y'))
by setting the property of the camera, now i am able to get the frame.
Related
I am getting yuy2 from my camera interfaced board and I need to process it to get raw16. for that I am developing an application in opencv-pyhton after applying Y16 codec but its giving me uint8 data when I checked with 'frame.dtype'. Isn't it should be uint16?
import cv2
import numpy as np
# open video0
cap = cv2.VideoCapture(0, cv2.CAP_MSMF)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('Y','1','6',' '))
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)
cap.set(cv2.CAP_PROP_FORMAT, -1)
enter code here
if cap.isOpened():
#for i in range(10):
# Capture frame-by-frame
ret, frame = cap.read()
else:
#if not ret:
#break
ret = False
while ret:
print('frame.shape = {} frame.dtype = {}'.format(frame.shape,
frame.dtype))
cap.release()
I tried using schedule. It works fine but the viewfinder of the webcam is stuck at the initial state so it produces only one image multiple times.
Any help?
import cv2
import time
import schedule
cam = cv2.VideoCapture(0)
cv2.namedWindow("Webcam")
img_counter = 0
def capture():
global img_counter
img_name = "opencv_frame_{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
print("screenshot taken")
img_counter += 1
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("test", frame)
k = cv2.waitKey(1)
if k % 256 == 27:
print("closing the app")
break
else:
schedule.every(5).seconds.do(capture)
while 1:
schedule.run_pending()
time.sleep(1)
cam.release()
cam.destroyAllWindows()
You are suffering from buffering. OpenCV VideoCapture() reads a few frames into a buffer - I think it is 5 but have not checked for a while and it may differ between platforms or versions.
There are a few possible work-arounds depending on your situation:
call read() 4-5 times when you want a frame - it will only take a couple of hundred milliseconds
call grab() either repeatedly in another thread or just before you want a frame
reduce the size of the buffer so it can only hold a single frame.
Sorry for the somewhat woolly answer as I am not set up to test more at the moment.
I think your code could be simplified to something like this while still retaining a near-realtime preview of the periodically saved images.
import cv2
import schedule
cam = cv2.VideoCapture(0)
cv2.namedWindow("Webcam")
img_counter = 0
def capture():
global img_counter
img_name = "opencv_frame_{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
print("screenshot taken")
img_counter += 1
# Set up schedule before loop
schedule.every(5).seconds.do(capture)
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("test", frame)
schedule.run_pending()
k = cv2.waitKey(100) # 1/10 sec delay; no need for separate sleep
if k % 256 == 27:
print("closing the app")
break
cam.release()
cam.destroyAllWindows()
i am getting a (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor' while making a face detection using openCv. Here is my code:
import cv2
import numpy as np
# Load HAAR face classifier
face_classifier = cv2.CascadeClassifier('Haarcascades/haarcascade_frontalface_default.xml')
# Load functions
def face_extractor(img):
# Function detects faces and returns the cropped face
# If no face detected, it returns the input image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = face_classifier.detectMultiScale(gray, 1.3, 5)
if faces is ():
return None
# Crop all faces found
for (x,y,w,h) in faces:
cropped_face = img[y:y+h, x:x+w]
return cropped_face
# Initialize Webcam
cap = cv2.VideoCapture(0)
count = 0
# Collect 100 samples of your face from webcam input
while True:
ret, frame = cap.read()
if face_extractor(frame) is not None:
count += 1
face = cv2.resize(face_extractor(frame), (200, 200))
face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
# Save file in specified directory with unique name
file_name_path = './faces/user/' + str(count) + '.jpg'
cv2.imwrite(file_name_path, face)
# Put count on images and display live count
cv2.putText(face, str(count), (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 2)
cv2.imshow('Face Cropper', face)
else:
print("Face not found")
pass
if cv2.waitKey(1) == 13 or count == 100: #13 is the Enter Key
break
cap.release()
cv2.destroyAllWindows()
print("Collecting Samples Complete")
and here is the output which is an error
error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
I tried converting / to \ but that resulted in another SyntaxError: EOL while scanning string literal.
Please help me solving this issue i have also tr
You need to specify the path to your haarcascade_frontalface_default.xml file.
Put double \ in your path as i did
I modified your code and hope it helps
`#importing library
import cv2
import numpy as np
# Load HAAR face classifier
face_classifier =
cv2.CascadeClassifier
('D:\\OpenCV\\opencv\\build\\etc\\Haarcascades\\haarcascade_frontalface_default.xml')
# crop the image into 20 by 20 px and change it to B&W
def face_extractor(img):
# Function detects faces and returns the cropped face
# If no face detected, it returns the input image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = face_classifier.detectMultiScale(gray, 1.3, 5)
if faces is ():
return None
# Crop all faces found
for (x,y,w,h) in faces:
cropped_face = img[y:y+h, x:x+w]
return cropped_face
#Asks for the total number of users
num=int(input("Enter no of user you want to add "))
user=1
# Initialize Webcam
cap = cv2.VideoCapture(0)
#count the total number of faces
count = 0
print("Start Capturing the input Data Set ")
d=input('Enter Face name')
# Collect 100 samples of your face from webcam input
while True:
ret, frame = cap.read()
print(type(frame))
#condition to check if face is in the frame or not
if face_extractor(frame) is not None:
count += 1
face = cv2.resize(face_extractor(frame), (200, 200))
face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
# Save file in specified directory with unique name
file_name_path = './faces/user/' +str(d)+'-' +str(count) + '.jpg'
cv2.imwrite(file_name_path, face)
# Put count on images and display live count
cv2.putText(face, str(count), (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 2)
cv2.imshow('Face Cropper', face)
else:
print("Face not found")
pass
#checks if ech user 100 images is captured
if(count%100)==0 and count!= num*100 and count!=0:
print("Place the new user Signature")
cv2.waitKey()
#checks if total images are captured
if cv2.waitKey(1) == 13 or count == num*100: #13 is the Enter Key
break
#closes all windows
cap.release()
cv2.destroyAllWindows()
print("Collecting Samples Complete")`
I am able to process the video frames by saing the frame as an image and then processing it. But was unable to pass frame directly to the object detection.
Saving image with imwrite is making program slow...
Here is my main method:
cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=2), cv2.CAP_GSTREAMER)
if cap.isOpened():
window_handle = cv2.namedWindow("CSI Camera", cv2.WINDOW_AUTOSIZE)
# Window
while cv2.getWindowProperty("CSI Camera", 0) >= 0:
ret_val, frame = cap.read()
if not ret_val:
break
frame = imutils.resize(frame, width=600)
#cv2.imwrite('box.jpg', frame)
#image = Image.open(path)
#Error in here!!!
predictions = od_model.predict_image(frame)
for x in range(len(predictions)):
probab = (predictions[x]['probability'])*100
if(probab > 45):
print(predictions[x]['tagName'], end=' ')
print(probab)
#cv2.imshow("CSI Camera", frame)
# This also acts as
keyCode = cv2.waitKey(30) & 0xFF
# Stop the program on the ESC key
if keyCode == 27:
break
cap.release()
cv2.destroyAllWindows()
else:
print("Unable to open camera")
Error Message:
predictions = od_model.predict_image(frame)
File "/home/bharat/New_IT3/object_detection.py", line 125, in
predict_image
inputs = self.preprocess(image)
File "/home/bharat/New_IT3/object_detection.py", line 130, in
preprocess
image = image.convert("RGB") if image.mode != "RGB" else image
AttributeError: 'numpy.ndarray' object has no attribute 'mode'
open cv reads image in bgr colour spectrum conver it to rgb and send the image for detection, api for the same is -
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
I need some direction on whats the best programming approach to overlay a live video from a webcam (or a pre loaded video), with paintbrush. i.e, drawing lines , circles and such, to mark areas in the video while its playing.
right now using OpenCV + Tkinter, is there a better way to approach this?
Thanks
EDIT: trying to paint directly on the video window, but cant get it to work.. here is my code:
import cv2
import numpy as np
def interactive_drawing(event,x,y,flags,param):
global ix,iy,drawing, mode
if event==cv2.EVENT_LBUTTONDOWN:
drawing=True
ix,iy=x,y
elif event==cv2.EVENT_MOUSEMOVE:
if drawing==True:
if mode==True:
cv2.line(frame,(ix,iy),(x,y),(0,0,255),10)
ix=x
iy=y
print x,y
elif event==cv2.EVENT_LBUTTONUP:
drawing=False
if mode==True:
cv2.line(frame,(ix,iy),(x,y),(0,0,255),10)
ix=x
iy=y
return x,y
drawing=False # true if mouse is pressed
mode=True # if True, draw rectangle. Press 'm' to toggle to curve
cap = cv2.VideoCapture('track.avi')
while(cap.isOpened()):
ret, frame = cap.read()
if frame is None:
break
# cv2.namedWindow("frame", cv2.WND_PROP_FULLSCREEN)
# cv2.setWindowProperty("frame",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
cv2.setMouseCallback('frame',interactive_drawing)
cv2.imshow('frame',frame)
if cv2.waitKey(15) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
# mouse callback function
##img = np.zeros((512,512,3), np.uint8)
##
##cv2.namedWindow('begueradj')
##cv2.setMouseCallback('begueradj',interactive_drawing)
##while(1):
## cv2.imshow('begueradje',img)
## k=cv2.waitKey(1)&0xFF
## if k==27:
## break
##cv2.destroyAllWindows()
I would only use OpenCV for that purpose, as it already provides drawing functions such as :
Lines
Rectangles
Circles
Ellipses
Polygons
etc.
EDIT: This code snippet should help you get started. The important point here is that you have to save the drawing elements in a variable (curve_points in my case) and draw them on each new frames:
import cv2
import numpy as np
def interactive_drawing(event,x,y,flags,param):
global drawing, mode
if event==cv2.EVENT_LBUTTONDOWN:
drawing=True
elif event==cv2.EVENT_MOUSEMOVE:
if drawing==True:
if mode==True:
curves[len(curves)-1].append((x,y)) #append new points to the last list of curves
elif event==cv2.EVENT_LBUTTONUP:
drawing=False
if mode==True:
curves.append([]) #adding a new list to curves
return x,y
def draw_curves(myArray):
for j in range(0, len(myArray)):
for i in range(1, len(myArray[j])):
cv2.line(frame,myArray[j][i-1],myArray[j][i],(0,0,255),10)
drawing=False # true if mouse is pressed
mode=True # if True, draw rectangle. Press 'm' to toggle to curve
cap = cv2.VideoCapture(0) #cap = cv2.VideoCapture('track.avi')
curves = [[]] # initializing curves list with an empty list
cv2.namedWindow('frame')
cv2.setMouseCallback('frame',interactive_drawing)
while(cap.isOpened()):
ret, frame = cap.read()
if frame is None:
break
draw_curves(curves)
cv2.imshow('frame',frame)
if cv2.waitKey(15) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()