There is a difference while debayer an image with cmd ffmpeg
I have such a bayer image https://drive.google.com/file/d/1OjHQyR44ECMMs4BtlZacejkmgSjeY2Nq/view?usp=sharing
I need to get two output files
- Directly debayer this image and save it as
.bmp
- Debayer the image compress it to
.h264
and the decompress and save as.bmp
In order to do this, I use such a batch script
@echo off
set main_dir=my_main_dir
set file_name=orig_bayer
set input=%main_dir%\%file_name%.bmp
set output_direct_debayer_bmp=%main_dir%\gpl_cmd_direct_decompress.bmp
set output_h264=%main_dir%\result_h264_%file_name%.h264
set output_h264_to_bmp=%main_dir%\gpl_cmd_decompress.bmp
set video_size=4096x3000
rem direct debayering
ffmpeg -y -hide_banner -i %input% -vf format=gray -f rawvideo pipe: | ffmpeg -hide_banner -y -f rawvideo -pixel_format bayer_rggb8 -video_size %video_size% -i pipe: -pix_fmt yuv420p %output_direct_debayer_bmp%
rem debaer -> h264 -> decompress
ffmpeg -y -hide_banner -i %input% -vf format=gray -f rawvideo pipe: | ffmpeg -hide_banner -y -framerate 30 -f rawvideo -pixel_format bayer_rggb8 -video_size %video_size% -i pipe: -c:v hevc_nvenc -qp 0 -pix_fmt yuv420p %output_h264%
ffmpeg -y -i %output_h264% -f image2 %output_h264_to_bmp% -hide_banner
pause
So the problem that with #1 approach I
...
rem direct debayering
ffmpeg -y -hide_banner -i %input% -vf format=gray -f rawvideo pipe: | ffmpeg -hide_banner -y -f rawvideo -pixel_format bayer_rggb8 -video_size %video_size% -i pipe: -pix_fmt yuv420p %output_direct_debayer_bmp%
...
I get such an output https://drive.google.com/file/d/1-DA2440zZ2F9WRcd15iqFUt3UhtkQRZT/view?usp=sharing
and with #2 approach
...
rem debaer -> h264 -> decompress
ffmpeg -y -hide_banner -i %input% -vf format=gray -f rawvideo pipe: | ffmpeg -hide_banner -y -framerate 30 -f rawvideo -pixel_format bayer_rggb8 -video_size %video_size% -i pipe: -c:v hevc_nvenc -qp 0 -pix_fmt yuv420p %output_h264%
ffmpeg -y -i %output_h264% -f image2 %output_h264_to_bmp% -hide_banner
...
I get such an output https://drive.google.com/file/d/103dtgaDVaXsNy13XHaVLSgugQhh0Uj9N/view?usp=sharing
The second one has a difference in the colors...
It look like a bug in the color conversion algorithm, but I can't be sure.
When replacing -pix_fmt yuv420p
with -pix_fmt yuv444p
the colors are the same as the direct conversion.
- The color conversion path: Bayer -> yuv420p modifies the colors.
- The color conversion path: Bayer -> yuv444p works correctly.
The common Demosaicing algorithms converts from Bayer to RGB, and not from Bayer directly to YUV, but I don't know the internal conversion pipeline used by FFmpeg.
I found a solution that encodes yuv420p with the following color conversion path:
Bayer -> yuv444p -> yuv420p
The solution uses the format
video filter.
Add the arguments: -vf format=yuv444p
after -i pipe:
.
Use the following command:
ffmpeg -y -hide_banner -i %input% -vf format=gray -f rawvideo pipe: | ffmpeg -hide_banner -y -framerate 30 -f rawvideo -pixel_format bayer_rggb8 -video_size %video_size% -i pipe: -vf format=yuv444p -c:v hevc_nvenc -qp 0 -pix_fmt yuv420p %output_h264%
Results (reduced size) left to right:
- Without
-vf format=yuv444p
(incorrect colors): - With
-vf format=yuv444p
(correct colors): - Direct conversion (correct colors):
Note:
- HEVC is H.265 and not H.264