I'm using the following code to create a video with rectangles in all its frames. However, the video is not being saved after it is created. How can I edit the code to have the video save in one of my folders.
import cv2
#Reads the video and collects it information
cap = cv2.VideoCapture('20150326_060700_062957_themis_rank_fisheye.mp4')
fps = cap.get(cv2.CAP_PROP_FPS)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
output = cv2.VideoWriter("output.mp4", -1, fps,(int(width),int(height)))
while (cap.isOpened()):
ret, frame = cap.read()
if (ret):
# Adds the rectangles in all frames
rect1 = cv2.rectangle(frame, (135, 510), (200,450), (255, 0, 0), 1)
rect2 = cv2.rectangle(frame, (365, 365), (430, 430), (255, 0, 0),1)
# writing the new frame in output
output.write(frame)
cv2.imshow("output", frame)
if cv2.waitKey(1) & 0xFF == ord('s'):
break
else:
break
cv2.destroyAllWindows()
output.release()
cap.release()
Code creates file for me when I set manually codec instead of -1
#fourcc = -1
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
output = cv2.VideoWriter("output.mp4", fourcc, fps,(int(width),int(height)))
I never saw code with -1. Maybe it doesn't work.
Related
This is my code, I've looked at some tutorials but can't find what I'm looking for
I want to overlay the Frame.png image on my webcam. I tried to add the image directly but it didn't work either. If possible, Is there a way to add an image, not to overlay but to keep the image at a certain coordinate in the live webcam window
import cv2
import numpy as np
def detect_and_save():
alpha = 0.2
beta = 1-alpha
cap = cv2.VideoCapture(0)
sciframe = cv2.imread('Frame.png')
classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
while True:
ret ,frame = cap.read()
overlay = frame.copy()
output = frame.copy()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = classifier.detectMultiScale(gray,1.5,5)
cv2.putText(output, "HUD Test",(175, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 50, 50), 3)
cv2
for face in faces:
x,y,w,h = face
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,200,0),-1)
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,0,0),1)
cv2.rectangle(overlay,(x,y-20),(x+w,y),(25,20,0),-1)
cv2.addWeighted(overlay,alpha,output,beta,0,output)
cv2.putText(output,"Human",(x+10,y-10),cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
if not ret:
continue
cv2.imshow("HUD",output)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite('./images/CID_{}.png'.format(time.strftime('%d%m%y_%H_%M_%S')),output)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
import time
detect_and_save()
You can directly add one image on top of another one at any coordinate easily in opencv.
cap = cv2.VideoCapture(0)
im_height = 50 #define your top image size here
im_width = 50
im = cv2.resize(cv2.imread("Frame.png"), (im_width, im_height))
while (True):
ret, frame = cap.read()
frame[0:im_width, 0:im_height] = im #for top-left corner, 0:50 and 0:50 for my image; select your region here like 200:250
cv2.imshow("live camera", frame)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
[enter image description here][1]I am working in a opencv program and i get the error: "index 1920 is out of bounds for axis 0 with size 1080". w is equal to 1920 and when i change it to 1079 it works.
import cv2 #opencv, computer vision
import time #import time
pTime = 0 #iniziating variable time
cap = cv2.VideoCapture("segment4_pumping_and_foiling.mp4") #open the video
cv2.namedWindow("video", cv2.WND_PROP_FULLSCREEN) #full screen
cv2.setWindowProperty("video", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) #full screen
while True: #while the video is playing
success, img = cap.read() #read the video link
h, w, c = img.shape #parameters of the images
cTime = time.time() #obtain the time
fps = 1 / (cTime - pTime) #calculate frames per second
pTime = cTime #restart the timer
cv2.putText(img, str(int(fps)), (70, 50), cv2.FONT_HERSHEY_PLAIN, 3,(255, 0, 0), 3) #write it in the window
ret,thresh = cv2.threshold(img,206,210,cv2.THRESH_BINARY)
i=1
point0=(0,h)
pointw=(w,h)
for i in range(200):
(b0, g0, r0)=thresh[0,(h-i)]
(bw, gw, rw)=thresh[w,(h-i)] #deberia ser hasta el wide, no 1079
if (b0>200 and g0>200 and r0>200): #and flag0=0
#flag0=1
point0=(0,h-i)
if (bw>200 and gw>200 and rw>200):
#flagw=1
pointw=(w,h-i)
image = cv2.line(thresh, (0, 830), (w, 830), (0, 255, 0), 4)
image = cv2.line(thresh, point0, pointw, (0, 255, 255), 4)
#cv2.imshow("video", img) #show the video
cv2.imshow("video", thresh)
if cv2.waitKey(1) & 0xFF == ord('q'): #if you write 0 (frame by frame), quit pressing q
break #close the video window
cv2.destroyAllWindows() #clear
cap.release() #clear
Two issues I can see - for one, pixels are 0-indexed. So for an HD image (1080x1920), the bottom right pixel is (1079, 1919).
In addition, you access an opencv image/Mat by [row][col]. So the last line should be:
(b, g, r) = img[h-1,w-1]
I'm trying to write a script that anonymized faces on videos.
here is my code (python):
import cv2
from mtcnn.mtcnn import MTCNN
ksize = (101, 101)
def decode_fourcc(cc):
return "".join([chr((int(cc) >> 8 * i) & 0xFF) for i in range(4)])
def find_face_MTCNN(color, result_list):
for result in result_list:
x, y, w, h = result['box']
roi = color[y:y+h, x:x+w]
cv2.rectangle(color, (x, y), (x+w, y+h), (0, 155, 255), 5)
detectedFace = cv2.GaussianBlur(roi, ksize, 0)
color[y:y+h, x:x+w] = detectedFace
return color
detector = MTCNN()
video_capture = cv2.VideoCapture("basic.mp4")
width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
length = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))
fps = int(video_capture.get(cv2.CAP_PROP_FPS))
video_out = cv2.VideoWriter(
"mtcnn.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
while length:
_, color = video_capture.read()
faces = detector.detect_faces(color)
detectFaceMTCNN = find_face_MTCNN(color, faces)
video_out.write(detectFaceMTCNN)
cv2.imshow("Video", detectFaceMTCNN)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
fourccIN = video_capture.get(cv2.CAP_PROP_FOURCC)
fourccOUT = video_out.get(cv2.CAP_PROP_FOURCC)
print(f"input fourcc is: {fourccIN, decode_fourcc(fourccIN)}")
print(f"output fourcc is: {fourccOUT, decode_fourcc(fourccOUT)}")
video_capture.release()
cv2.destroyAllWindows()
I'll get a perfect working window with the anonymization, so imshow() works fine. But the new saved video "mtcnn.mp4" can't be opened. I found out the problem is the fourcc format of the new video since my output is:
input fourcc is: (828601953.0, 'avc1')
output fourcc is: (-1.0, 'ÿÿÿÿ')
'ÿÿÿÿ' stands for unreadable so thats the core of the matter...
Can someone help me please?
They are facing probably the same problem:
Using MTCNN with a webcam via OpenCV
And I used this to encode the fourcc:
What is the opposite of cv2.VideoWriter_fourcc?
I've changes this line:
video_out = cv2.VideoWriter(
"mtcnn.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height))
to:
video_out = cv2.VideoWriter(
"mtcnn.avi", cv2.VideoWriter_fourcc(*'XVID'), fps, (width, height))
And now it works for me
I was following this tutorial and I tried to save the video to an avi file, but every time I tried the file was corrupted. I was able to save the frames individually using cv2.imwrite(), but stitching together the individual frames was a lot of work, and would lag the entire program. Here is my code:
from imutils.video import VideoStream
import imutils
import time
import cv2
MINIMUM_AREA = 500
# For Video Recording Purposes
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('vibralert_test001.avi', fourcc, 20, (640, 480))
vs = VideoStream(src=0).start()
print("Setting up feed.")
time.sleep(2)
print("Live")
firstFrame = None
while True:
frame = vs.read()
text = "No Movement Detected"
frame = imutils.resize(frame, width=500)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
if firstFrame is None:
firstFrame = gray
continue
delta = cv2.absdiff(firstFrame, gray)
thresh = cv2.threshold(delta, 25, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
if cv2.contourArea(c) < MINIMUM_AREA:
continue
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = "Movement Detected"
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("VibrAlert v0.1", frame)
out.write(frame)
key = cv2.waitKey(1) & 0xFF
if key == 27:
break
vs.stop()
out.release()
cv2.destroyAllWindows()
print('End Feed')
The size of the frame images need to be the same as the frameSize given to the VideoWriter, (640,480). The frame is being resized to have a width of 500, while the videoWriter is expecting a width of 640.
However, changing the resize to frame = imutils.resize(frame, width=640) probably won't work either. imutils.resize will return images with the same aspect ratio as the original image, so the height won't necessarily be 480. I would suggest replacing that line with the opencv.resize:
frame = cv2.resize(frame, (640,480))
I have a problem while running a function in Python 3 with OpenCV 3, I want to calibrate a video with a calibration data .npz and it results in an error message on remapping matrix line.
The calibrated video output is great but it came with an error message, which prevents any further execution. How could I make the script ignore the error and continue?
Any answer will be greatly appreciated.
This is the code:
import cv2, time, sys
import numpy as np
import matplotlib.pyplot as plt
filename = 'vtest3.mp4'
filename_2 = 'vtest3_undistort.mp4'
crop = 0.5
#FIRST FUNCTION (UNDISTORTION)
def undistortion(filename):
print('Loading data files')
npz_calib_file = np.load('calibration_data.npz')
distCoeff = npz_calib_file['distCoeff']
intrinsic_matrix = npz_calib_file['intrinsic_matrix']
npz_calib_file.close()
print('Finished loading files')
print(' ')
print('Starting to undistort the video....')
# Opens the video import and sets parameters
video = cv2.VideoCapture(filename)
# Checks to see if a the video was properly imported
status = video.isOpened()
if status == True:
FPS = video.get(cv2.CAP_PROP_FPS)
width = video.get(cv2.CAP_PROP_FRAME_WIDTH)
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
size = (int(width), int(height))
total_frames = video.get(cv2.CAP_PROP_FRAME_COUNT)
frame_lapse = (1 / FPS) * 1000
# Initializes the export video file
codec = cv2.VideoWriter_fourcc(*'DIVX')
video_out = cv2.VideoWriter(str(filename[:-4]) + '_undistort.mp4', codec, FPS, size, 1)
# Initializes the frame counter
current_frame = 0
newMat, ROI = cv2.getOptimalNewCameraMatrix(intrinsic_matrix, distCoeff, size, alpha=crop,
centerPrincipalPoint=1)
mapx, mapy = cv2.initUndistortRectifyMap(intrinsic_matrix, distCoeff, None, newMat, size, m1type=cv2.CV_32FC1)
while current_frame < total_frames:
success, image = video.read()
current_frame = video.get(cv2.CAP_PROP_POS_FRAMES)
dst = cv2.remap(image, mapx, mapy, cv2.INTER_LINEAR)
# dst = cv2.undistort(image, intrinsic_matrix, distCoeff, None)
video_out.write(dst)
video.release()
video_out.release()
else:
print('Error: Could not load video')
sys.exit()
#SECOND FUNCTION
def hauptprogramm(filename_2):
# Create an empty List for x- and y-Positions that will be filled in for-loop
# with the .append function
xposition = [] # Empty list for x-Positions
yposition = [] # Empty list for y-Positions
# Open the Video with die VideoCapture function
# Name the video that is opened cap
cap = cv2.VideoCapture(filename_2)
# set the framenumber to the last frame just to take a picture
cap.set(1, cap.get(cv2.CAP_PROP_FRAME_COUNT)); # Where frame_no is the frame you want
ret, frame = cap.read() # Read the frame
cv2.imwrite('kurve.jpg', frame)
# set the framenumber to 1, which is the first frame of the video
# from here we begin to analyse the video
cap.set(1, 1);
# cv2.imshow('window_name', frame) # show frame on window
# pos_frame = cap.get(cv2.CAP_PROP_POS_FRAMES)
# start an infinite while loop by setting while True
# the loop will go on until we break it
while True:
# read a frame of the video and name it frame0
# read the next frame of the video and name it frame1
# set both frames retangle by writing ret,frame
ret, frame0 = cap.read()
ret, frame1 = cap.read()
ret, frame2 = cap.read()
# the program will lateron compare every pixel from frame0 to frame1 and
# locate the areas where many pixels have changed
# we only are interested in the area where the missile is flying
# the moving of the catapult itself for exemple would cause trouble
# so we paint lines over the areas we are not interested in these lines
# will be painted every loop over frame1
cv2.line(frame1, (0, 0), (0, 511), (255, 0, 0), 200)
cv2.line(frame1, (0, 500), (1000, 500), (255, 0, 0), 350)
cv2.line(frame1, (0, 350), (150, 350), (255, 0, 0), 400)
# the same lines will be painted over frame2
cv2.line(frame2, (0, 0), (0, 511), (255, 0, 0), 200)
cv2.line(frame2, (0, 500), (1000, 500), (255, 0, 0), 350)
cv2.line(frame2, (0, 350), (150, 350), (255, 0, 0), 400)
# for the function that will compare frame1 and frame2 both frames have
# to be in black and white
# the next function will be used to convert frame1 and frame2 to black and
# white and will name them gray1 and gray2
gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
# the absdiff function will compare the gray1 and gray2 images and returns
# an image named diffimage
diffimage = cv2.absdiff(gray1, gray2)
# the result of that function returns a black and white image
# to get clear results the image will be converted to a binary image
# the new image called diffimage only has pixels that are white or black
ret, threshold = cv2.threshold(diffimage, 30, 255, cv2.THRESH_BINARY)
# to reduce the image noise we will make the threshold image blurry by using
# the blur function
threshold = cv2.blur(threshold, (25, 25))
# when converting the blurry image into a threshold image for a secound
# time the small noisy pixels of the image will be gone and the areas where
# a lot of pixels have changed in will be clearer and bigger
ret, threshold = cv2.threshold(threshold, 30, 255, cv2.THRESH_BINARY)
# ========================find the white areas ==================
# now we want to find the white areas in the picture that show
# our flying missile
# !exakte funktion noch nicht verstanden
image, contours, hierarchy = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# !exakte funktion noch nicht verstanden
for cnt in contours:
area = cv2.contourArea(cnt)
# to reduce the chance of tracking background noise that might be left
# even after reducing it with the blur and threshold functions
# we only track the position of if the white area is bigger than x=10
if area > 10:
# we are looking for the bounding rectangle that is around our area
# x and y equal the pixelposition of the top right point of the rectangle
# w and h equal the width and height of the rectangle
x, y, w, h = cv2.boundingRect(cnt)
# we are interested in the center of the rectangle so we add w/2 to x
# and h/2 to y
# because the x- and y-positions have to be integer we round the values
# and declare them as such
xpos = int(round(x + w / 2))
ypos = int(round(y + h / 2))
# to see if everything works fine wile running the program the positions
# can be printed in the console by removing the hashtag
# print("x= ", xpos)
# print("y= ", ypos)
# now the list of x- and y-positions will be extended by every loop
# with these list of positions we can work later on for the
# post-processing of the curve the object is flying
xposition.append(xpos)
yposition.append(ypos)
# not necessary to post-process but a nice visualisation and checking
# if everything works as it is supposed to
# a small circle will be painted on the x- and y-position
# therefore we take the "empty" frame0 that does not have the colored
# lines painted into
cv2.circle(frame0, (xpos, ypos), 5, (0, 255, 0), -1)
# a rectangle will be surrounding the center just to keep track of the
# moving object
cv2.rectangle(frame0, (x, y), (x + w, y + h), (255, 0, 0), 3)
# write the x- and y- position in each frame
cv2.putText(frame0, 'x = ' + str(xpos), (xpos - 20, ypos - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2, cv2.LINE_AA)
cv2.putText(frame0, 'y = ' + str(ypos), (xpos - 20, ypos + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2, cv2.LINE_AA)
# x-Positionen in Konsole mitschreiben
# print(xposition)
# ========================= Open Windows ====================
# the imshow functions open a window and show the selected frame each
# while loop (play the video)
# by removing the hashtag the selected video will open when running the
# program
# 1. Show the original frames and paint the previous visulisation
cv2.imshow('Orginal mit Verfolgung', frame0)
# 2. Show the threshold frames
cv2.imshow('threshold frames', threshold)
# 3. Show the painted lines in frame1 and frame2 (same parameters)
cv2.imshow('mit Balken', frame1)
# if we press the ESC button the loop will break
if cv2.waitKey(10) == 27: # mit ESC verlassen
break
# if we reach the total number of frames the loop will break
if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
# after we break the loop we release the cap and force all windows to close
cap.release()
cv2.destroyAllWindows()
# does not make sense, just a way to fix a bug in opencv
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(100)
# =================== Spielerei ====================
# cap2 = cv2.VideoCapture("vtest3.m4v")
# while True:
# cap2.set(1,cv2.CAP_PROP_FRAME_COUNT)
# ret, frame = cap.read()
# cv2.imshow('window_name', frame)
#
# if cv2.waitKey(10) == 27: # mit ESC verlassen
# break
#
# cap.release()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# cv2.waitKey(1)
# ========== Plot öffnen und speichern ===================
plt.plot(np.asarray(xposition), np.asarray(yposition), 'g^')
plt.axis('equal')
plt.savefig('positionen.png')
# ============== Image lesen und auswerten ===============
image = cv2.imread('kurve.jpg')
for i in range(0, len(xposition)):
cv2.circle(image, (xposition[i], yposition[i]), 5, (0, 255, 0), -1)
cv2.imwrite('positionen2.png', image)
undistortion(filename)
hauptprogramm(filename_2)