好吧,有点奇怪的问题。但我不确定它是python,ffmpeg还是一些我做错的蠢事。
我正在尝试拍摄视频,每秒拍摄1帧,并将该帧输出到图像。现在,如果我使用命令行与ffmpeg:
ffmpeg -i test.avi -r 1 -f image2 image-%3d.jpeg -pix_fmt rgb24 -vcodec rawrvideo
它输出大约10张图像,图像看起来很好,很棒。现在我有了这个代码(现在有些github的代码,因为我想要的东西,我相对肯定会工作,而且我很复杂)
import subprocess as sp
import numpy as np
import re
import cv2
import time
FFMPEG_BIN = r'ffmpeg.exe'
INPUT_VID = 'test.avi'
def getInfo():
command = [FFMPEG_BIN,'-i', INPUT_VID, '-']
pipe = sp.Popen(command, stdout=sp.PIPE, stderr=sp.PIPE)
pipe.stdout.readline()
pipe.terminate()
infos = pipe.stderr.read()
infos_list = infos.split('\r\n')
res = re.search(' \d+x\d+ ',infos)
res = [int(x) for x in res.group(0).split('x')]
return res
res = getInfo()
command = [ FFMPEG_BIN,
'-i', INPUT_VID,
'-f', 'image2pipe',
'-pix_fmt', 'rgb24',
'-vcodec', 'rawvideo', '-']
pipe = sp.Popen(command, stdout = sp.PIPE, bufsize=10**8)
n = 0
im2 = []
try:
mog = cv2.BackgroundSubtractorMOG2(120,2,True)
while True:
raw_image = pipe.stdout.read(res[0]*res[1]*3)
# transform the byte read into a numpy array
image = np.fromstring(raw_image, dtype='uint8')
image = image.reshape((res[1],res[0],3))
rgbImg = image.copy()
fname = ('_tmp%03d.png'%time.time())
cv2.imwrite(fname, rgbImg)
# throw away the data in the pipe's buffer.
#pipe.stdout.flush()
n += 1
print n
except:
print 'done',n
pipe.kill()
cv2.destroyAllWindows()
当我运行这个时,我得到10张图片,但它们都有蓝色色调!我不能为我的生活找出原因。我已经完成了大量的搜索,我尝试了很多不同的编解码器(通常只会让事情变得更糟)。视频文件的媒体信息位于:
General
Complete name : test.avi
Format : AVI
Format/Info : Audio Video Interleave
File size : 85.0 KiB
Duration : 133ms
Overall bit rate : 5 235 Kbps
Video
ID : 0
Format : JPEG
Codec ID : MJPG
Duration : 133ms
Bit rate : 1 240 Kbps
Width : 640 pixels
Height : 480 pixels
Display aspect ratio : 4:3
Frame rate : 30.000 fps
Color space : YUV
Chroma subsampling : 4:2:2
Bit depth : 8 bits
Compression mode : Lossy
Bits/(Pixel*Frame) : 0.135
Stream size : 20.1 KiB (24%)
有什么建议吗?它似乎应该是一个RGB混音......只是不确定在哪里......
编辑:所以我通过使用以下代码切换蓝色和红色通道来解决问题: bChannel = rgbImg [:,:,0] rChannel = rgbImg [:,:,2] gChannel = rgbImg [:,:,1]
rgbArray = np.zeros((res[1],res[0],3), 'uint8')
rgbArray[...,0] = rChannel
rgbArray[...,1] = gChannel
rgbArray[...,2] = bChannel
所以我想这是一个问题,为什么python会混淆这些频道?这是编解码器的python或ffmpeg的问题吗?
谢谢!
答案 0 :(得分:2)
openCV使用BGR而不是RGB出于某种奇怪的原因。必须切换像素才能获得正确的颜色。