I can open a video and play it with opencv 2 using the cv2.VideoCapture(myvideo). But is there a way to delete a frame within that video using opencv 2? The deletion must happen in-place, that is, the file being played will end up with a shorter time due to deleted frames. Simply zeroing out the matrix wouldn't be sufficient.
For example something like:
video = cv2.VideoCapture(myvideo.flv)
while True:
img = video.read()
# Show the image
cv2.imgshow(img)
# Then go delete it and proceed to next frame, but is this possible?
# delete(img)??
So the above code would technically contain 0 bytes at the end since it reads then deletes the frame in the video file.
OpenCV is not the right tool for this job. What you need for this is a media processing framework, like ffmpeg (=libavformat/libavcodec/libswscale) or GStreamer.
Also depending on the encoding scheme used, simply deleting just a single frame may not be possible. Only in a video consisting of just Intra frames (I-frames), frame exact editing is possible. If the video is encoding in so called group of pictures (GOP) removing a single frame requires to reencode the whole GOP it was part of.
You can't do it in-place, but you can use OpenCV's VideoWriter to write the frames that you want in a new video file.
Related
I am fairly new to opencv and image editing, self learner you can say. I wanted have a poc of text morphing in videos like it happens with google lens but with the help of opencv.
I have achieved that for single video single run, but what I want to do is to take one input video, process it for the given positions of frames, save the output, then take that processed output as input for the next iteration and then save it after new edits are made.
I am trying to take data from a json file, which looks like this.
JSON FILE
Here is link to my code. I am a complete newbie trying to learn, so my methods and approch might be highly inefficient but I would appreciate any help.
https://colab.research.google.com/drive/1WJVklMHESUAOa5wlLfjjpPVjOSfKt2i5?usp=sharing
when you read the video till the end, it doesnt just reset.
so you need to reset the video on every loop. either open the videocapture again. move cap = cv2.VideoCapture(video_original) inside your loop for document in range
or set the frame to whatever start frame (eg 0) you want using cap.set(cv2.CAP_PROP_POS_FRAMES, self.frame_num) inside your loop
I'm trying to read a raw video file codified in bayer_rggb8 in python to store some specific frames. I Know that with FFmpeg I probably store all the frames in the format that I want and then work with them. Still, the point is that this is a first version of the program and the next step is to use it online with a grasshopper camera that sends the data in bayer_rggb8 format, and I want to process the frames without the need of storing them in the disk.
My first try was with the videocapture functions from OpenCV, but it didn't work. I think a right solution may be open the file with open(filepath,'rb') and read the number of bytes in a frame, and then transform from rggb8 space to OpenCV bgr. I haven't found a way to do it, however.
Have you ever done anything similar? Is there a bookstore that can help me? I don't ask for the code directly, but right now I think I'm so lost that I'm not able to see the solutions.
I'm using python 3.6 and opencv in Kubuntu 18.04. The frame size is 600X1920
Thanks!!
I found a solution; it was easier than I thought. I think I was blocked
video = open(filepath,'rb')
framesize = 600 * 1920
initbyte = framesize * initframe
video.seek(initbyte)
frame = self.video.read(framesize)
frame = np.frombuffer(frame, dtype=np.uint8).reshape(600,1920)
bgrframe = cv2.cvtColor(frame,cv2.COLOR_BayerBG2BGR)
I am capturing videos from a camera and saving them using the opencv VideoWriter function. I save the captured videos as uncompressed avi files. When I finish recording the video, I have another script that is supposed to read the video frame by frame, process the pixel values. However, when I try to read the frames of the saved video, the pixel values are off a bit.
For example, comparing the first frames of the video being written, and the video being read (supposed to be 100% identical), I notice that the pixel values are off by a small number (RGB values off by a small number, usually less than 5).
I have already made sure that I am using the exact same video codex when writing the video, and when reading the video (Check code below)
def write_video():
out = cv2.VideoWriter("encrypted.avi" ,cv2.VideoWriter_fourcc(*'XVID'),30, (640,480))
foreach frame:
out.write(frame)
def read_video():
cap = cv2.VideoCapture("encrypted.avi")
cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc(*'XVID'))
while(cap.isOpened()):
ret, frame = cap.read()
For my application, the frames being written and read should match 100%. I have included an image highlighting the difference between the first frame in the video being written, and the video being read. Any help is much appreciated!
These are the compression artifacts, since you are using lossy compression. If you would like your frames match down to the last bit, write them as a sequence of .PNG files -- these are losslessly compressed and preserve everything. Beware that .PNG will take much more of your HDD space than compressed video.
I'm writing a multi-threaded application in python 3, one thread grab frames from a webcam using opencv, another one record audio frames using pyaudio. Both threads put the frames in a separate circular buffer, with absolute timestamp for every frame.
Now I'd like to create another thread who read from the buffers and join audio and video frame together using the timestamp information, then save everything to a mp4 file. The only thing I found is merging audio and video files using for example ffmpeg, but nothing related to frames on the fly.
Do I really need to create the audio and video files before join them? What I don't understand in this case is how to handle synchronization..
Any hints will be appreciated.
EDIT
In reponse to the comments, the timestamps are created by me and are absolute, I use a data structure which contains the actual data (video or audio frame) and the timestamp. The point is that audio is recorded with a microphone and video using a webcam, which are different hardware, not synchronized.
Webcam grab a frame, elaborate it and put in a circular buffer using my data structure (data + timestamp).
Microphone record an audio frame, elaborate it and put in a circular buffer using my data structure (data + timestamp).
So I have 2 buffers, I want to pop frames and join together in whatever video file format, matching the timestamps in the most accurate way possible. My idea is something that can add an audio frame to a video frame (I will check about timestamps matching).
I've got a videostream (for now I just use a video). I need to get a one frame per every second or more seconds and I need to cut some part of these pictures based on 8 coordinates(leftupper x/y, rightupper x/y, rightlower x/y and leftlower x/y).
I thinkg that I'm able to do that cutting in java but I would rather do it in python as entire application is written in python / django.
It's possible to do both of that things directly in python?
Could you point me to some documentation or whatever?
You can start with some Video Handling in Python Using OpenCV
Python : Reading Video File and Saving Video File using OpenCV
It contains all the basic links like Reading from File and Camera , that gives a initial idea of how to process Frames .
Then after you get Each Frame in OpenCV mat , you can form a Bounding Box Rect to extract the Region or ROI from that
Close to this Question
Cropping Live Video Feed
Cropping a Single Frame can be done as done in
Cropping a Single Image in OpenCV Python
This can be repeated for every Frame and you can even Write to a Video File taking reference from First Reference.