I am trying to a write a python3-opencv3 code to read the color video and convert it to grayscale and save it back.
(Trying exercises to learn python & opencv)
As I am working in ubuntu, I found out cv2.VideoCapture isColor flag will not work (it works only windows)
import numpy as np
import cv2
cap = cv2.VideoCapture('output.avi')
ret, frame = cap.read()
print('ret =', ret, 'W =', frame.shape[1], 'H =', frame.shape[0], 'channel =', frame.shape[2])
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
height, width = gray.shape[:2]
print(height,width)
cv2.imshow('frame',gray)
FPS= 20.0
FrameSize=(frame.shape[1], frame.shape[0])
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('Video_output.avi', fourcc, FPS, (width,height))
while(ret):
ret, frame = cap.read()
if cv2.waitKey(1) & 0xFF == ord('q') or ret == False:
break
print('ret =', ret, 'W =', frame.shape[1], 'H =', frame.shape[0], 'channel =', frame.shape[2])
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Save the video
out.write(gray)
cv2.imshow('frame',gray)
cap.release()
out.release()
cv2.destroyAllWindows()
It is give me this
error: (-215) img.cols == width && img.rows == height*3 in function write
I am guessing, the problem is with framesize and grayscale image conversion but I am not able to figure out ? I have tried different combination of height & widht but none are able execute the program correctly.
Can someone help ?
As requested in the comments:
Traceback (most recent call last):
File "/home/akash/Coded/VideoCode/Test3", line 70, in <module>
out.write(gray)
cv2.error: /home/travis/miniconda/conda-bld/conda_1486587069159/work/opencv-3.1.0/modules/videoio/src/cap_mjpeg_encoder.cpp:834: error: (-215) img.cols == width && img.rows == height*3 in function write
OpenCV error -215 means "assertion failed". The assertion itself is listed in the message (the phrase "Assertion failed" itself probably should, too; you can open a ticket about this in OpenCV's bug tracker). (Update: my pull request with this change was accepted on 06.03 and was released in opencv 3.4.2.)
As one can deduce from the assertion, it expects the frame to be a 3-color-channel one. To make a grayscale video, you need to pass isColor=False to VideoWriter constructor:
out = cv2.VideoWriter('Video_output.avi', fourcc, FPS, (width,height), False)
Related
I am trying to run a simple objection detection on webcam using Yolov5 but I keep getting the error below.
zsh: segmentation fault
The camera appears to open then shut off immediately and the code exit with the above error.
Here is my code
def object_detector():
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
# mmocr = MMOCR(det='TextSnake', recog='SAR')
cam = cv2.VideoCapture(0)
while(True):
ret, frame = cam.read()
# ocr_result = mmocr.readtext(frame, output='demo/cam.jpg', export='demo/', print_result=True, imshow=True)
# print("RESULT \n ", ocr_result)
frame = frame[:, :, [2,1,0]]
frame = Image.fromarray(frame)
frame = cv2.cvtColor(np.array(frame), cv2.COLOR_RGB2BGR)
# ocr_result = mmocr.readtext(frame, output='demo/cam.jpg', export='demo/', print_result=True, imshow=True)
# print("RESULT \n ", ocr_result)
result = model(frame,size=640)
# Results
# crops = result.crop(save=True)
cv2.imshow('YOLO', np.squeeze(result.render()))
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cam.release()
cv2.destroyAllWindows()
what am i doing wrong and how can i fix it ?
You're not testing the return value from cam.read() ensure that ret is a success code, and that frame is not a nullptr before you proceed.
You need to check that an image is returned in the first place. The first return resulting from cam.read() tells you whether an image has been received. This is how you can make use of it:
...
while(True):
ret, frame = cam.read()
if ret:
frame = frame[:, :, [2,1,0]]
...
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cam.release()
cv2.destroyAllWindows()
I wrote a code that takes a video and recognizes face of a human and calculate the distance of the human from the camera (which is the eye of a robot). I need the data in a txt format so I am writing it in the distance_data.txt but my file is always empty.
I had run the code in a mac computer and it worked perfectly fine and the file was not empty.
import cv2
import time
import numpy as np
person_cascade = cv2.CascadeClassifier('human_recognition.txt')
cap = cv2.VideoCapture('oct23_2.avi')
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('oct23_2out.avi',fourcc, 20.0, (640,360))
distance_data = open('distance_data.txt','w')
timer=-1
while (cap.isOpened()):
r, frame = cap.read()
if r:
frame = cv2.resize(frame,(640,360)) # Downscale to improve frame rate
gray_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # Haar-cascade classifier needs a grayscale image
cv2.imshow('gray',gray_frame)
#print(gray_frame.type())
rects = person_cascade.detectMultiScale(gray_frame)
max=0
#print(rects)
(x, y, w, h) = rects[0]
cv2.rectangle(frame, (x,y), (x+w ,y+h),(0,255,0),2)
#fshape = frame.shape
#fheight = fshape[0]
#fwidth = fshape[1]
timer=timer+1
xpos=(0.03421)*(w*w)-8.1183*w+521.841
yn=360-y
heightinvid=0.0197377*yn-0.0194
realhieght=((-0.4901)*(heightinvid* heightinvid)+4.4269*heightinvid+8.30356)/ 0.927183854
horizontalp=x+w/2
#print(timer+1 , ",", xpos, )
#if (xpos<=41 and xpos>=40):
#print("height of the human is ", realhieght+149, "or", (-0.000184)*yn*yn+0.08506*yn+8.43461+149)
cm_deviation_in_x=-0.02033898*(320-horizontalp)
#print("Horizontal position of human is ", cm_deviation_in_x, " cm.")
newxpos = format (xpos, '.3f')
distance_data.write("Hi")
distance_data.write(str(newxpos))
distance_data.write(',')
distance_data.write(str(format(cm_deviation_in_x, '.3f')))
distance_data.write("\r\n")
#print(w)
#print("x position of the human is = ",xpos)
#fourcc = cv2.VideoWriter_fourcc(*'XVID')
#out = cv2.VideoWriter('output25.avi',fourcc, 20.0, (fwidth,fheight))
cv2.imshow("preview", frame)
out.write(frame)
k = cv2.waitKey(10)
#print(w,h)
if k & 0xFF == ord("q"): # Exit condition
break
distance_data.flush()
cap.release()
cv2.destroyAllWindows()
I'm trying to send pictures to the aws rekognition from my webcam to detect the activity of the person sitting in front of it using python.
To do so I take a picture every 5 seconds and I send it to the aws.
But when I do so it seems that he's always sending back information about the first frame that I sent
cap = cv2.VideoCapture(0)
while 1:
ret, img = cap.read()
client=boto3.client('rekognition')
print("hello")
ret, fileImg=cv2.imencode('.png',img)
response = client.detect_labels(Image={'Bytes':fileImg.tobytes()})
print('Detected labels for Camera Capture')
for label in response['Labels']:
print (label['Name'] + ' : ' + str(label['Confidence']))
sleep(5)
Here is the result i get from that call:
Detected labels for Camera Capture
Human : 99.1103897095
People : 99.1103744507
Person : 99.1103897095
Face : 56.5527687073
Crypt : 51.1719360352
hello
Detected labels for Camera Capture
Human : 99.0247421265
People : 99.0247344971
Person : 99.0247421265
Face : 57.7796173096
Lighting : 51.8473701477
Crypt : 51.08152771
hello
Detected labels for Camera Capture
Human : 99.0808181763
People : 99.0808105469
Person : 99.0808181763
Face : 56.4268836975
Lighting : 54.6302490234
Crypt : 50.8622779846
hello
Knowing during the time of the call the image has changed a lot and should (at least I think) show me other results.
Here's some code that I use to put rectangles around faces in a similar way:
import cv2
import numpy as np
import boto3
# Setup
scale_factor = .15
green = (0,255,0)
red = (0,0,255)
frame_thickness = 2
cap = cv2.VideoCapture(0)
rekognition = boto3.client('rekognition')
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
height, width, channels = frame.shape
# Convert frame to jpg
small = cv2.resize(frame, (int(width * scale_factor), int(height * scale_factor)))
ret, buf = cv2.imencode('.jpg', small)
# Detect faces in jpg
faces = rekognition.detect_faces(Image={'Bytes':buf.tobytes()}, Attributes=['ALL'])
# Draw rectangle around faces
for face in faces['FaceDetails']:
smile = face['Smile']['Value']
cv2.rectangle(frame,
(int(face['BoundingBox']['Left']*width),
int(face['BoundingBox']['Top']*height)),
(int((face['BoundingBox']['Left']+face['BoundingBox']['Width'])*width),
int((face['BoundingBox']['Top']+face['BoundingBox']['Height'])*height)),
green if smile else red, frame_thickness)
# Display the resulting frame
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
It scales-down the picture because Rekognition doesn't need full size to detect faces.
working with opencv-python for a tracking project. i get this error when calling the estiamte single marker..any idea?
cv2 version 3.2.0-dev
python version 2.7.12
Traceback (most recent call last):
File "test_aruco_detect.py", line 53, in <module>
rvecs , tvecs = aruco.estimatePoseSingleMarkers(corners, 0.1765, cameraMatrix, distCoeffs)
ValueError: too many values to unpack
the code:
import numpy as np
import cv2
import cv2.aruco as aruco
with np.load('/home/odroid/camera_calibration/testfile.npz') as X:
cameraMatrix,distCoeffs = [X[i] for i in ('arr_0','arr_1')]
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
#print(frame.shape) #480x640
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)
parameters = aruco.DetectorParameters_create()
#lists of ids and the corners beloning to each id
corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, aruco_dict, parameters=parameters)
if ids != None: #if atleast one id is detected
gray = aruco.drawDetectedMarkers(gray, corners,ids)
rvecs , tvecs = aruco.estimatePoseSingleMarkers(corners, 0.1765, cameraMatrix, distCoeffs)
aruco.drawAxis(gray, cameraMatrix, distCoeffs, rvecs, tvecs)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
rvecs , tvecs, _objPoints = aruco.estimatePoseSingleMarkers(...)
edit:
according to the documentation (http://docs.opencv.org/trunk/d9/d6a/group__aruco.html#ga84dd2e88f3e8c3255eb78e0f79571bd1) i was missing the _objPoints
I am trying to run the following code on my Raspberry Pi, but it is giving me this error:
Traceback (most recent call last):
File "video_capture_thresh.py", line 59, in
main ()
File "video_capture_thresh.py", line 11, in main
crop = frame[180:320, 0:638]
TypeError: 'NoneType' object has no attribute 'getitem
import numpy as np
import cv2
#cap=cv2.VideoCapture(0)
cap = cv2.VideoCapture(1)
def main():
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
crop = frame[180:320, 0:638]
crop2=cv2.cvtColor(crop,cv2.COLOR_BGR2GRAY)
th,crop2 = cv2.threshold(crop2,0,255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
previous = cv2.GaussianBlur(crop2, (5,5),0)
contours, hierarchy = cv2.findContours(crop2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.rectangle(previous,(0,0),(638,140),(0,255,0),5)
i=0
for cnt in contours:
moments = cv2.moments(cnt) # Calculate moments
if moments['m00']!=0:
cx = int(moments['m10']/moments['m00']) # cx = M10/M00
cy = int(moments['m01']/moments['m00']) # cy = M01/M00
moment_area = moments['m00'] # Contour area from moment
contour_area = cv2.contourArea(cnt) # Contour area using in_built function
perimeter = cv2.arcLength(cnt,True)
cv2.drawContours(previous, [cnt], 0, (0,255,0), 3)
px = previous[cy,cx]
if px == 255 :
i=i+1
cv2.circle(previous,(cx,cy),5,(0,0,255),-1)
cv2.imshow("Previous",previous)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
main ()
cap.release()
cv2.destroyAllWindows()
Try adding a check to make sure you actually read in OK before you do your processing
ret, frame = cap.read()
if ret==True:
crop = frame[180:320, 0:638]
The method read
This is the most convenient method for reading video files or capturing data from decode and return the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer.
Check if the image is captured from camera well.
What kind of camera are you using?
Note that cv2.VideoCapture does not work with Raspi module camera, it just works with usb webcam.