问题描述
我正在使用v4l2-ctl(1)
从网络摄像头捕获图像,并且试图将convert(1)
的原始格式转换为png。
这是我运行的命令。
# This is the format my camera outputs.
$ v4l2-ctl --device /dev/video0 --list-formats-ext
ioctl: VIdioC_ENUM_FMT
Type: Video Capture
[1]: 'YUYV' (YUYV 4:2:2)
Size: discrete 640x480
Interval: discrete 0.033s (30.000 fps)
# This is how I'm capturing an image.
$ v4l2-ctl --device /dev/video0 --set-fmt-video=width=640,height=480,pixelformat=YUYV
$ v4l2-ctl --device /dev/video0 --stream-mmap --stream-to=frame.raw --stream-count=1
# This is how I tried to convert. (This didn't work.)
$ convert -size 640x480 -depth 8 -sampling-factor 4:2:2 -colorspace YUV yuv:frame.raw frame.png
这给了我绿色和粉红色的png。
我也尝试使用此命令显示原始图像。
$ display -size 640x480 -depth 8 -sampling-factor 4:2:2 -colorspace yuv yuv:frame.raw
该图像看上去更好一点,但是整个图像上都有一个蓝色滤镜。
这是来自我的网络摄像头的示例图像。 http://s000.tinyupload.com/?file_id=36420855739943963603
解决方法
我认为我有解决方法,但是正确着色的参考图像会有所帮助。最简单的方法似乎是使用ffmpeg
将采样率为4:2:2的原始YUYV转换为PNG,如下所示:
ffmpeg -f rawvideo -s 640x480 -pix_fmt yuyv422 -i frame.raw result.png
如果要使用 ImageMagick 进行操作,则需要使用其uyvy
像素格式,但是您的字节已交换,因此需要将它们交换为 ImageMagick 期望在送入之前-我在这里使用dd
及其conv=swab
选项:
dd if=frame.raw conv=swab | convert -sampling-factor 4:2:2 -size 640x480 -depth 8 uyvy:- result.png
如果您需要以其他更复杂的方式交换和重新排序字节,则可以使用xxd
和awk
相当简单地做到这一点:
xxd -c2 frame.raw | awk '{print $1,substr($2,3,2),1,2)}' | xxd -c2 -r - | convert -sampling-factor 4:2:2 -size 640x480 -depth 8 uyvy:- result.png
关键字:ImageMagick,图像处理,命令行,二次采样,4:2:2,YUYV,YUY2,YUV