Я хочу обрабатывать отформатированное видео "h264" кадр за кадром. Обработайте кадр, чтобы добавить в него некоторый шум (например, шум соли и перца) и воссоздайте отформатированное видео «h264» из обработанных изображений (изображений с шумом) в той же последовательности, что и исходное видео «h264».
Я пытался сделать то же самое, используя openCV, но я не получаю какой-либо работающий определенный кодек (требуется cv2.VideoWriter) для создания видео в формате h264. Итак, я создал mp4-видео из зашумленных изображений, а затем преобразовал его из формата mp4 в h264 с помощью ffmpeg. Но я предполагаю, что теряю слишком много информации из исходного кадра из-за преобразования h264 -> mp4 -> h264. Ниже приведен код, написанный мной для того же.
import numpy as np
import os
from skimage.util import random_noise
def processVideo(videoPath, noiseType="", outVideoPath=""):
"""
Add the specified noise in the provided video.
videoPath: Video file path
noiseType: noise type which needs to be added in the video.
Supported noise types: gaussian, localvar, poisson, salt, pepper, s&p, speckle
Returns:
Noisy video path, in case of success
None, in case of failure
"""
if noiseType not in ['gaussian', 'localvar', 'poisson', 'salt', 'pepper', 's&p']:
print "noiseType is not specified."
return None
videoPath = os.path.abspath(videoPath)
print "The video path under process: {}".format(videoPath)
if outVideoPath:
outVideoPath = os.path.abspath(outVideoPath)
else:
outVideoPath = os.path.abspath(os.path.dirname(videoPath))
if os.path.exists(videoPath):
video = cv2.VideoCapture(videoPath)
if os.path.isdir(outVideoPath):
outVideoPath = os.path.join(outVideoPath, os.path.splitext(
os.path.basename(videoPath))[0] + "_Noisy" + ".mp4")
elif os.path.exists(outVideoPath):
print "The given location already contains the file named {}.\nPlease delete the same.".format(outVideoPath)
return None
elif os.path.exists(os.path.dirname(outVideoPath)):
outVideoPath = os.path.splitext(outVideoPath)[0] + ".mp4"
else:
print "The given location {} does not exists".format(os.path.dirname(outVideoPath))
return None
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
frame_width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
video_fps = int(video.get(cv2.CAP_PROP_FPS))
totalFrames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
print "Total Frames in video = ", totalFrames
out = cv2.VideoWriter(outVideoPath, fourcc, video_fps, (frame_width, frame_height))
while (video.isOpened()):
ret, frame = video.read()
if ret is True:
noise_img = random_noise(frame, mode=noiseType)
noise_img = np.array(255 * noise_img, dtype='uint8')
out.write(frame)
else:
video.release()
out.release()
break
return outVideoPath
else:
print "Provided Video Path: {} is not present in the specified location.".format(videoPath)
return None
def mp4Toh264VideoConv(mp4VideoPath, h264VideoPath=""):
mp4VideoPath = os.path.abspath(mp4VideoPath)
print "h264 video:", os.path.abspath(h264VideoPath)
if h264VideoPath:
h264VideoPath = os.path.abspath(h264VideoPath)
else:
h264VideoPath = os.path.abspath(os.path.dirname(mp4VideoPath))
if os.path.isdir(os.path.abspath(h264VideoPath)):
h264VideoPath = os.path.join(h264VideoPath, os.path.splitext(os.path.basename(mp4VideoPath))[0] + ".h264")
elif os.path.exists(h264VideoPath):
print "The given location already contains the file named {}.\nPlease delete the same.".format(h264VideoPath)
return None
elif os.path.exists(os.path.dirname(h264VideoPath)):
h264VideoPath = os.path.splitext(h264VideoPath)[0] + ".h264"
else:
print "The given location {} does not exists.".format(os.path.dirname(h264VideoPath))
return None
print "The h264 video path: ", h264VideoPath
os.system('ffmpeg -i ' + mp4VideoPath + ' -an -vcodec libx264 -crf 23 ' + h264VideoPath)
return h264VideoPath
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='This script will add the specified noise in the given h264 video.')
parser.add_argument('-i', '--inputVideo', help='Input h264 formated Video Path', required=True)
parser.add_argument('-o', '--outputVideo', help='Output video path location', default="", required=False)
parser.add_argument('-n', '--noiseType', help='Type of noise to add in the video', default='', required=True)
args = vars(parser.parse_args())
inputVideo = os.path.expanduser(args['inputVideo'])
outputVideo = os.path.expanduser(args['outputVideo'])
noiseType = args['noiseType']
if os.path.splitext(inputVideo)[1].upper() != ".H264":
print os.path.splitext(inputVideo)[1].upper()
print "Noise Addition in {} formated video is not supported".format(os.path.splitext(inputVideo)[1])
exit(-1)
else:
noisymp4Video = processVideo(videoPath=inputVideo, noiseType=noiseType, outVideoPath=outputVideo)
if noisymp4Video:
mp4Toh264VideoConv = mp4Toh264VideoConv(mp4VideoPath=noisymp4Video, h264VideoPath=outputVideo)
exit(0)
else:
exit(-1)
Мне нужен какой-то лучший способ для прямой обработки видео h264, внесения некоторых изменений в кадр и создания видео h264. Я в порядке, если это возможно с комбинациями ffmpeg и openCV. Мне просто нужен какой-то лучший способ предотвратить потерю из-за преобразования h264 -> mp4 -> h264.
Заранее спасибо за помощь.