FFMpeg 命令在命令行中工作,但在 python 脚本中图像偏蓝? (半解决)
FFMpeg Command work in command line, but in python script the image is blueish? (Semi Solved)
好吧,有点奇怪的问题。但我不确定是 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 编解码器有问题吗?
谢谢!
openCV 由于一些奇怪的原因使用 BGR 而不是 RGB。必须切换像素以获得正确的颜色。
好吧,有点奇怪的问题。但我不确定是 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 编解码器有问题吗?
谢谢!
openCV 由于一些奇怪的原因使用 BGR 而不是 RGB。必须切换像素以获得正确的颜色。