解码使用 FFMPEG、EXIFTOOLS 和 EXIV2 的批处理脚本,以创建类似 Google Cardboard 的 VR180 和 VR360 全景图像

解码使用 FFMPEG、EXIFTOOLS 和 EXIV2 的批处理脚本,以创建类似 Google Cardboard 的 VR180 和 VR360 全景图像

我正在努力弄清楚两件事:

  1. 为什么这个脚本对谷歌来说是完全不可见的

  2. 此类脚本如何工作(比第 1 点重要得多......)

为了更好地研究该脚本,我使用了一百万条调试行来打印脚本正在执行的操作......但目前尚不清楚:

  • ffmpeg:好的,我完全明白了,我可以进行任何我需要的转换
  • exiftool:它做什么,怎么做?它应该将扩展的 exif 数据写入“普通”图像,使它们看起来像 VR180、VR360 或纸板,但我不明白它如何/从哪里获取数据以及何时写入最终输出。如果我只输入了“普通”图像,我在哪里可以获取正确的 exif 数据?
  • exiv2:一片黑暗……

“文档”没有太大帮助:我只知道我必须创建这个奇怪的文件夹结构:

  • 光盘
  • 目录:\D\R
  • 目录:\VR

..并输入 C:\D 和 C:\D\R... 一些我不太明白的东西:我所拥有的源是使用 235° FOV 的全景/鱼眼相机拍摄的几张圆形图像,我想将它们放入纸板格式 (.vr.jpg) 并在此查看器中查看结果:https://vr.caffeinum.com/create.html

左球面图像

右球面图像

我使用 ffmpeg 将它们转换为等距矩形:

等距矩形左

等距矩形右

我用了:

ffmpeg -i input.jpg -vf v360=fisheye:e:ih_fov=235:iv_fov=235 -y output.jpg

我的脚本:

@echo off
@echo ============================
echo Run "JPG2VR.bat" without parameters to place it in "%UserProfile%\SendTo"
echo                                                     -
echo ---- Option 1 ----
echo Place dual fisheye files:
echo from right vr360 cam to "c:\d\R\df.jpg" "c:\d\R"
echo from left vr360 cam to "c:\d\df.jpg" "c:\d"
echo                                                     -
echo ---- Option 2 ----
echo Place equirectangular panorama files:
echo from right vr360 cam to "c:\d\R\vr360.jpg" "c:\d\R"
echo from left vr360 cam to "c:\d\vr360.jpg" "c:\d"
echo                                                     -
echo ---- Option 3 ----
echo Send files or dirs: "c:\d\df.jpg" "c:\d\vr360.jpg" "c:\d" "c:\d\R" ... to "JPG2VR"
echo or drop it to "JPG2VR.bat" then look at:
echo "c:\VR\dfF.vr.jpg" - front view vr180 3D panorama
echo "c:\VR\dfB.vr.jpg" - back view vr180 3D panorama
echo "c:\VR\vr360F.vr.jpg" - front view vr180 3D panorama
echo "c:\VR\vr360B.vr.jpg" - back view vr180 3D panorama
echo "c:\VR\vr360.vr.jpg" - vr360 3D panorama
echo ----------------------------------------------

SetLocal EnableExtensions EnableDelayedExpansion

:forfiles
if "%~1"=="nul" (
@echo ==== par1 = nul, hence use par2 (%~2)
 call :doit "%~2"
 goto :ERR001
)
:main

set cmd="cmd /c "%~f0" nul "@path""

:loop
 if "%~1"=="" (
  pause
  goto :ERR002
 )

 forfiles /s /p "%~1" /m *.jpg /c %cmd% 2>nul||call :doit "%~1"
 shift
goto :loop

:doit
@echo file f1="%~f1", suffisso x1="%~x1"
rem Check for full path+file:
if not exist "%~f1" goto :ERR003

rem Check for extension:
if /i not ".jpg"=="%~x1" goto :ERR004

rem percorso della prima (dp1) , piu sottodir \R , piu nome della seconda (~nx1)
@echo Imposto pair a "%~dp1R   -  %~nx1"
set pair="%~dp1R\%~nx1"

set suff=F
set vr=..\VR
set crop=0
if exist %pair% goto :setOutputFilename
@echo ==== "pair" does NOT exist (%pair%), hence setting PAIR to "%~dp1..\%~nx1"
set pair="%~dp1..\%~nx1"


set suff=B
set vr=..\..\VR
set crop=iw/2
if not exist %pair% goto :ERR005

:setOutputFilename
@echo ==== "pair" exists (%pair%), hence setting OUTPUT to "%~dp1%vr%\%~n1%suff%.vr.jpg"
set out="%~dp1%vr%\%~n1%suff%.vr.jpg"



if exist %out% goto :ERR006

set FOV=235
set interp=gauss
set vf=crop=iw/2:ih:%crop%,v360=fisheye:equirect:ih_fov=%FOV%:iv_fov=%FOV%:interp=%interp%,crop=iw/2

@echo ==== Extracting exif data (ImageWidth, ImageHeight, ProjectionType, InitialHorizontalFOVDegrees, YCbCrPositioning, MakerNoteUnknown):
@echo #### exiftool -s2 -ImageWidth -ImageHeight -ProjectionType -InitialHorizontalFOVDegrees -YCbCrPositioning -MakerNoteUnknown "%~f1"
for /f "tokens=1,2,3 usebackq delims=: " %%i in (`exiftool -s2 -ImageWidth -ImageHeight -ProjectionType -InitialHorizontalFOVDegrees -YCbCrPositioning -MakerNoteUnknown "%~f1"`) do set %%i=%%j

@echo Tags found:
@echo ==== ImageWidth: %ImageWidth%
@echo ==== ImageHeight: %ImageHeight%
@echo ==== ProjectionType: %ProjectionType%
@echo ==== InitialHorizontalFOVDegrees: %InitialHorizontalFOVDegrees%
@echo ==== YCbCrPositioning: %YCbCrPositioning%
@echo ==== MakerNoteUnknown: %MakerNoteUnknown%

@echo ==== checking for image mandatory requirements: width must be 2 times height


if not defined ImageWidth (
    goto :ERR007
) else (
    @echo ==== ImageWidth found: %ImageWidth%
)
if not defined ImageHeight (
    goto :ERR008
) else (
    @echo ==== ImageHeight found: %ImageHeight%
)

set /a TrueVrWidth=%ImageHeight%*2

@echo ==== Checking aspect ratio (must be 2:1)...
if not "%ImageWidth%"=="%TrueVrWidth%" (
    goto :ERR009
) else (
    @echo ==== Aspect ratio ok
)
set ImageWidth=%ImageHeight%

if not defined InitialHorizontalFOVDegrees set InitialHorizontalFOVDegrees=75

@echo ==== Projection type found?...
if defined ProjectionType (
    @echo ======== yes, it's %ProjectionType%
 set vf=[0]crop=iw/4:ih:0[r];[0]crop=iw/4:ih:iw*3/4[l];[l][r]hstack
 @echo ==== Filter set to %vf%
 if "%suff%"=="F" set vf=crop=iw/2
) else (
    @echo ##### no
)
set tags="%temp%\%~n1.jpg"
set L="%temp%\%~n1L.jpg"
set R="%temp%\%~n1R.jpg"
call :deltemp
if defined MakerNoteUnknown set makernotes=-makernotes:all=


@echo ####  exiftool -ThumbnailImage= -ifd1:all= -PreviewImage= -FlashPix:all= -FlashpixVersion= -mpf:all= -trailer:all= %makernotes% "%~f1" -o %tags%
exiftool -ThumbnailImage= -ifd1:all= -PreviewImage= -FlashPix:all= -FlashpixVersion= -mpf:all= -trailer:all= %makernotes% "%~f1" -o %tags%
if not exist %tags% goto :ERR010

@echo ==== set xmp 1:
set xmp="%temp%\%ImageWidth%x%InitialHorizontalFOVDegrees%.xmp"
if exist %xmp% (
    @echo ==== set xmp1 ok: %xmp% , goto VR180...
    goto :vr180
) else (
    @echo ==== set xmp1 FAILED, do not go VR180, continue...
)

:xmp
set /a         FullPanoWidthPixels=%ImageWidth%*2
set /a CroppedAreaImageWidthPixels=%ImageWidth%
set /a       CroppedAreaLeftPixels=(%FullPanoWidthPixels%-%CroppedAreaImageWidthPixels%)/2

set /a         FullPanoHeightPixels=%ImageHeight%
set /a CroppedAreaImageHeightPixels=%ImageHeight%
set /a         CroppedAreaTopPixels=(%FullPanoHeightPixels%-%CroppedAreaImageHeightPixels%)/2

@echo ==== Running exiftool to set XMP tags...
echo 1|exiftool -tagsfromfile - -XMP-GPano:all^
 -XMP-GPano:UsePanoramaViewer="True"^
 -XMP-GPano:CroppedAreaLeftPixels="%CroppedAreaLeftPixels%"^
 -XMP-GPano:CroppedAreaTopPixels="%CroppedAreaTopPixels%"^
 -XMP-GPano:CroppedAreaImageWidthPixels="%CroppedAreaImageWidthPixels%"^
 -XMP-GPano:CroppedAreaImageHeightPixels="%CroppedAreaImageHeightPixels%"^
 -XMP-GPano:FullPanoWidthPixels="%FullPanoWidthPixels%"^
 -XMP-GPano:FullPanoHeightPixels="%FullPanoHeightPixels%"^
 -XMP-GPano:InitialViewHeadingDegrees="180"^
 -XMP-GPano:ProjectionType="equirectangular"^
 -XMP-GPano:InitialHorizontalFOVDegrees="%InitialHorizontalFOVDegrees%"^
 %xmp%
if not exist %xmp% (
    goto :ERR011
) else (
    @echo ---- XMO correctly set to %xmp%
)

:vr180
@echo ***************************************
@echo ********* Creating VR180 image ********, i.e. two half panoramas loking in same direction TO single image 3d panorama 180° wide
@echo ==== Filter: %vf%
@echo ==== Input for Left image: %~f1%
@echo running FFMPEG with above filter : ffmpeg -v 0 -hide_banner -i "%~f1" -bsf:v mjpeg2jpeg -filter_complex %vf% -qmin 1 -q:v 1 -map_metadata -1 -y   %L%|| del %L%
ffmpeg -v 0 -hide_banner -i "%~f1" -bsf:v mjpeg2jpeg -filter_complex %vf% -qmin 1 -q:v 1 -map_metadata -1 -y   %L%|| del %L%
if not exist %L% goto :ERR012
@echo ==== Input for right image: %pair%
@echo running FFMPEG with above filter : ffmpeg -v 0 -hide_banner -i %pair% -bsf:v mjpeg2jpeg -filter_complex %vf% -qmin 1 -q:v 1 -map_metadata -1 -y "%R%"|| del "%R%"
ffmpeg -v 0 -hide_banner -i %pair% -bsf:v mjpeg2jpeg -filter_complex %vf% -qmin 1 -q:v 1 -map_metadata -1 -y "%R%"|| del "%R%"
if not exist "%R%" goto :ERR013

@echo ==== Creating folder "%~dp1%vr%" if does not exist
if not exist "%~dp1%vr%" md "%~dp1%vr%"
if defined YCbCrPositioning set YCbCrP=-YCbCrPositioning="%YCbCrPositioning%"
set tail=-XMP-exif:all= -XMP-tiff:all= -JFIF:all= -FlashpixVersion= %YCbCrP% "-XMP-GImage:ImageMimeType=image/jpeg" "-XMP-GImage:ImageData<=%R%" 

@echo #### exiftool -tagsFromFile %tags% -ExifIFD:ExifImageWidth="%ImageWidth%" -tagsFromFile %xmp% %L% -o %out% %tail%
exiftool -tagsFromFile %tags% -ExifIFD:ExifImageWidth="%ImageWidth%" -tagsFromFile %xmp% %L% -o %out% %tail%
@echo _____________
if not exist %out% goto :ERR014
call :date

:vr360
@echo ***************************************
@echo ******* Creatingt 360 image ***********
if not defined ProjectionType goto :ERR015
if "%suff%"=="B" goto :ERR016
set out="%~dp1%vr%\%~n1.vr.jpg"
if exist "%out%" goto :ERR006

:tag
@echo ==== deleting old temporary files: %R%...
del "%R%"

@echo ==== Calling exiftool for pair %pair%...
@echo #### exiftool -all= -o "%R%" %pair%
exiftool -all= -o "%R%" %pair%

if not exist "%R%" goto :ERR013

@echo ==== Calling exiftool for tail %tail%...
@echo #### exiftool %tags% -o %out% %tail%
exiftool %tags% -o %out% %tail%
if not exist %out% goto :ERR017
call :date


:deltemp
@echo ==== deleting temporary files: %tags% %L% "%R%"
del %tags% %L% "%R%"
rem ==== return back to caller
goto :EOF

:date
rem Any of -api Compact= or use -z or do not use -z breaks compatibility with https://arvr.google.com/vr180/apps/
exiv2 -M"set Xmp.GPano.InitialHorizontalFOVDegrees %InitialHorizontalFOVDegrees%" %out%
exiftool "-FileCreateDate<CreateDate" "-FileModifyDate<ModifyDate" %out%
:exiftool -X %out% -w! .xml


:ERR001
@echo     -------------  EXIT WITH ERROR
goto :EOF

:ERR002
@echo     -------------  Fine parametri"
goto :EOF

:ERR003
@echo     -------------  003 File '%~f1%' not found
goto :EOF

:ERR004
@echo     -------------  Not jpg
goto :EOF


:ERR005
@echo     -------------  005 File '%pair%' not found
goto :EOF

:ERR006
@echo     -------------  Overwrite prevented
goto :EOF

:ERR007
@echo     -------------  Missing width
goto :EOF


:ERR008
@echo     -------------  Missing height
goto :EOF


:ERR009
@echo     -------------  Image is not rectangular
goto :EOF

:ERR010
@echo     -------------  Error creating output file "%tags%" with exif
goto :EOF


:ERR011
@echo     -------------  Failed to set XMP tags
goto :EOF


:ERR012
@echo     -------------  Error on left image
goto :EOF


:ERR013
@echo     -------------  Error on right image
goto :EOF


:ERR014
@echo     -------------  Exiftools for tail failed
goto :EOF


:ERR015
@echo     -------------  Error, VR360 images require ProjectionType tag in source images
goto :EOF


:ERR016
@echo     -------------  Error, suffix = B (?)
goto :EOF


:ERR016
@echo     -------------   Failed on tail (?)
goto :EOF

相关内容