video to images then images to video in python - python

I'm trying to convert the following video to images
https://www.signingsavvy.com/media/mp4-ld/24/24851.mp4
however, I have done it by using OpenCV
# Importing all necessary libraries
import cv2
import os
# Read the video from specified path
cam = cv2.VideoCapture("C:\Users\ahmad\Hi_ASL.mp4")
print(cam.get(cv2.CAP_PROP_FPS))
try:
# creating a folder named data
if not os.path.exists('data'):
os.makedirs('data')
# if not created then raise error
except OSError:
print ('Error: Creating directory of data')
# frame
currentframe = 0
while(True):
# reading from frame
ret,frame = cam.read()
if ret:
# if video is still left continue creating images
name = './data/frame' + str(currentframe) + '.jpg'
# print ('Creating...' + name)
# writing the extracted images
cv2.imwrite(name, frame)
# increasing counter so that it will
# show how many frames are created
currentframe += 1
else:
break
# ret,frame = cam.read()
# Release all space and windows once done
cam.release()
cv2.destroyAllWindows()
After I have done it. I want to convert those images to video to be like the one above and I wrote this code
img = [img for img in os.listdir('data')]
frame = cv2.imread('data\' + img[0])
h , w , l = frame.shape
vid = cv2.VideoWriter('hiV.mp4' , 0 ,1 ,(w,h))
for imgg in img:
vid.write(cv2.imread('data\' + imgg))
cv2.destroyAllWindows()
vid.release()
The problem is the result of combining the images to a video using OpenCV is not the same as the original video. So, what is the problem? I want it to be the same as the original one.
The result of the code above is this video https://drive.google.com/file/d/16vwT35wzc95tBleK5VCpZJQkaLxSiKVd/view?usp=sharing
And thanks.

You should change cv2.VideoWriter('hiV.mp4' , 0 ,1 ,(w,h)) to cv2.VideoWriter('hiV.mp4' , 0 ,30 ,(w,h)) As the 1 sets the fps and that means that you write 1 frame every second and not 30 or 29.97(NTSC) as the original video.

Related

How to save one image every 25 frames into a folder

I am trying to write images from IP camera into a new folder. However, as for now, it is writing for each frame. How to only save one image every 25 frames? This is my current code:
import cv2
import os
folder = 'test_python'
os.mkdir(folder)
url = "rtsp://axis-media/media.amp"
count = 0
cap = cv2.VideoCapture(url)
while True:
# read next frame
ret, frame = cap.read()
cv2.imshow('frame', frame)
cv2.imwrite(os.path.join(folder, "frame{:d}.jpg".format(count)), frame)
count += 1
The trivial solution would be:
if count % 25 == 0:
cv2.imwrite(...)

Extract the text from the Video data

I want to extract the text from the video data. I can extract the text but facing some problems. I am getting repetitive texts from the video. I want to extract the exact text from the whole video. How could I solve my problem? I am sharing my code.
import cv2
import os
import pytesseract
import numpy as np
import time
# Mention the installed location of Tesseract-OCR in your system
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
FRAME_RATE = 2
# Read the video from specified path
video_data = cv2.VideoCapture(r"jonty.mp4")
video_length= int(video_data.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
fps=int(video_data.get(cv2.CAP_PROP_FPS))
pos_frame= int(video_data.get(cv2.CAP_PROP_POS_FRAMES))
width = int(video_data.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video_data.get(cv2.CAP_PROP_FRAME_HEIGHT))
frame_time = 0
frame_count = 0
print("total_frames: ", video_length)
print("FRAME_RATE", FRAME_RATE)
print("fps", fps)
print("pos_frame", pos_frame)
text_data=[]
while(True):
video_data.set(cv2.CAP_PROP_POS_MSEC, frame_time * 10000) # move frame to a timestamp
frame_time += 1/FRAME_RATE
# reading from frame
ret,frame = video_data.read()
if ret:
# if video is still left continue creating images
image = r'\images\frame' + str(frame_count) + '.jpg
# writing the extracted images
cv2.imwrite(image, frame)
# Apply OCR on the cropped image
text = pytesseract.image_to_string(image,lang='eng+deu+fra')
#print(text)
text_data.append(text)
# frame in every 1 second
frame_count += 1
else:
break
# Release all space and windows once done
video_data.release()
cv2.destroyAllWindows()

Grab video frames from all videos in folder, process with openCV, save to own folder?

I have code like this. I know it's not correct, but I'm new at this and not sure how to fix it. How do I make it so cv2 runs on every video I have in a folder, taking a frame every 3 seconds, and saving the frame images in a new folder within /data/ --- ex. /data/rise_of_skywalker?
Thanks
import cv2
import numpy as np
import os
def frame_capture(file):
cap = cv2.VideoCapture(file)
try:
if not os.path.exists('data'):
os.makedirs('data')
except OSError:
print('Error: Creating directory of data')
currentFrame = 0
while(True):
# Capture frame by frame
ret, frame = cap.read()
'''
(((how do I change this block here to get it for every 3 seconds?)))
'''
if currentFrame == 5:
name = './data/frame' + str(currentFrame) + '.jpg'
print ('Creating...' + name)
cv2.imwrite(name, frame)
# To stop duplicate images
currentFrame += 1
cap.release()
cv2.destroyAllWindows()
print ("Done!")
for file in os.listdir("/users/x/Desktop/y/videos"):
if file.endswith(".mp4"):
path=os.path.join("/users/x/Desktop/y/videos", file))
frame_capture(path)
If I understand correctly, what you want to do is to change the line if currentFrame == 5: to if currentFrame % (3 * fps) == 0:
And before that line, outside the loop, add fps = cap.get(cv2.CAP_PROP_FPS)

Why is my program not recognizing the Checkerboard?

I am running a Camera Calibration program from Python using openCV. I am using my computer camera from an XPS 15 9575 in order to capture different frames of a classic black and white checkerboard that I printed. For some reason, it never registers in the program that there is a checkerboard.
I've run this program by itself and with already produced images and it works. It only doesn't work as I try to capture new ones and process them instantly.
This is the beginning of the code. It runs to check to see if it finds the corners and then moves onto the next step. When running, it never makes it past this.
cam = cv2.VideoCapture(0)
cv2.namedWindow("test")
img_counter = 0
imgNames = []
size = (5,5)
while True:
ret, frame = cam.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow("test", gray)
if not ret:
break
k = cv2.waitKey(1)
if k%256 == 27:
break
elif k%256 == 32:
img_name = "{}.png".format(img_counter)
imgtemp = cv2.imread(img_name)
graytemp = cv2.cvtColor(imgtemp,cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(graytemp, size,None)
print (ret)
if ret == True:
print ("good!")
imgNames.append(img_name)
cv2.imwrite(img_name, frame)
img_counter += 1
else:
print ("again")
In your code above, you are trying to read an image which actually doesn't exist. See these lines:
img_name = "{}.png".format(img_counter)
imgtemp = cv2.imread(img_name)
Here, img_name is just a string, which doesn't point to an image file yet. You can do one thing, capture a frame and save it here and give it a name img_name and then try to read it via cv2.imread function, like below:
img_name = "{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
imgtemp = cv2.imread(img_name)
Alternatively, you can replace imgtemp = cv2.imread(img_name) with imgtemp = frame. In this case, you don't have to save and then process a frame. Here, once a spacebar is pressed, processing is done on the current captured video frame without saving it.
And don't forget to add below lines at the end of your code:
cam.release()
cv2.destroyAllWindows()

OpenCV - Save video segments based on certion condition

Aim : Detect the motion and save only the motion periods in files with names of the starting time.
Now I met the issue about how to save the video to the files with video starting time.
What I tested :
I tested my program part by part. It seems that each part works well except the saving part.
Running status: No error. But in the saving folder, there is no video. If I use a static saving path instead, the video will be saved successfully, but the video will be override by the next video. My codes are below:
import cv2
import numpy as np
import time
cap = cv2.VideoCapture( 0 )
bgst = cv2.createBackgroundSubtractorMOG2()
fourcc=cv2.VideoWriter_fourcc(*'DIVX')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
n = "start_time"
while True:
ret, frame = cap.read()
dst = bgst.apply(frame)
dst = np.array(dst, np.int8)
if np.count_nonzero(dst)>3000: # use this value to adjust the "Sensitivity“
print('something is moving %s' %(time.ctime()))
path = r'E:\OpenCV\Motion_Detection\%s.avi' %n
out = cv2.VideoWriter( path, fourcc, 50, size )
out.write(frame)
key = cv2.waitKey(3)
if key == 32:
break
else:
out.release()
n = time.ctime()
print("No motion Detected %s" %n)
What I meant is:
import cv2
import numpy as np
import time
cap = cv2.VideoCapture( 0 )
bgst = cv2.createBackgroundSubtractorMOG2()
fourcc=cv2.VideoWriter_fourcc(*'DIVX')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
path = r'E:\OpenCV\Motion_Detection\%s.avi' %(time.ctime())
out = cv2.VideoWriter( path, fourcc, 16, size )
while True:
ret, frame = cap.read()
dst = bgst.apply(frame)
dst = np.array(dst, np.int8)
for i in range(number of frames in the video):
if np.count_nonzero(dst)<3000: # use this value to adjust the "Sensitivity“
print("No Motion Detected")
out.release()
else:
print('something is moving %s' %(time.ctime()))
#label each frame you want to output here
out.write(frame(i))
key = cv2.waitKey(1)
if key == 32:
break
cap.release()
cv2.destroyAllWindows()
If you see the code there will be a for loop, within which the process of saving is done.
I do not know the exact syntax involving for loop with frames, but I hope you have the gist of it. You have to find the number of frames present in the video and set that as the range in the for loop.
Each frame gets saved uniquely (see the else condition.) As I said I do not know the syntax. Please refer and follow this procedure.
Cheers!

Categories

Resources