images2avi.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. # Copyright (C) 2012, Almar Klein
  2. # All rights reserved.
  3. #
  4. # This code is subject to the (new) BSD license:
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are met:
  8. # * Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # * Redistributions in binary form must reproduce the above copyright
  11. # notice, this list of conditions and the following disclaimer in the
  12. # documentation and/or other materials provided with the distribution.
  13. # * Neither the name of the <organization> nor the
  14. # names of its contributors may be used to endorse or promote products
  15. # derived from this software without specific prior written permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. # ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  21. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #
  28. #
  29. # changes of this file GRASS (PNG instead of JPG) by Anna Petrasova 2013
  30. """ Module images2avi
  31. Uses ffmpeg to read and write AVI files. Requires PIL
  32. I found these sites usefull:
  33. http://www.catswhocode.com/blog/19-ffmpeg-commands-for-all-needs
  34. http://linux.die.net/man/1/ffmpeg
  35. """
  36. import os, time
  37. import subprocess, shutil
  38. from grass.imaging import images2ims
  39. def _cleanDir(tempDir):
  40. for i in range(3):
  41. try:
  42. shutil.rmtree(tempDir)
  43. except Exception:
  44. time.sleep(0.2) # Give OS time to free sources
  45. else:
  46. break
  47. else:
  48. print("Oops, could not fully clean up temporary files.")
  49. def writeAvi(filename, images, duration=0.1, encoding='mpeg4',
  50. inputOptions='', outputOptions='' ):
  51. """ writeAvi(filename, duration=0.1, encoding='mpeg4',
  52. inputOptions='', outputOptions='')
  53. Export movie to a AVI file, which is encoded with the given
  54. encoding. Hint for Windows users: the 'msmpeg4v2' codec is
  55. natively supported on Windows.
  56. Images should be a list consisting of PIL images or numpy arrays.
  57. The latter should be between 0 and 255 for integer types, and
  58. between 0 and 1 for float types.
  59. Requires the "ffmpeg" application:
  60. * Most linux users can install using their package manager
  61. * There is a windows installer on the visvis website
  62. """
  63. # Get fps
  64. try:
  65. fps = float(1.0/duration)
  66. except Exception:
  67. raise ValueError("Invalid duration parameter for writeAvi.")
  68. # Determine temp dir and create images
  69. tempDir = os.path.join( os.path.expanduser('~'), '.tempIms')
  70. images2ims.writeIms( os.path.join(tempDir, 'im*.png'), images)
  71. # Determine formatter
  72. N = len(images)
  73. formatter = '%04d'
  74. if N < 10:
  75. formatter = '%d'
  76. elif N < 100:
  77. formatter = '%02d'
  78. elif N < 1000:
  79. formatter = '%03d'
  80. # Compile command to create avi
  81. command = "ffmpeg -r %i %s " % (int(fps), inputOptions)
  82. command += "-i im%s.png " % (formatter,)
  83. command += "-g 1 -vcodec %s %s " % (encoding, outputOptions)
  84. command += "output.avi"
  85. # Run ffmpeg
  86. S = subprocess.Popen(command, shell=True, cwd=tempDir,
  87. stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  88. # Show what ffmpeg has to say
  89. outPut = S.stdout.read()
  90. if S.wait():
  91. # An error occured, show
  92. print(outPut)
  93. print(S.stderr.read())
  94. # Clean up
  95. _cleanDir(tempDir)
  96. raise RuntimeError("Could not write avi.")
  97. else:
  98. # Copy avi
  99. shutil.copy(os.path.join(tempDir, 'output.avi'), filename)
  100. # Clean up
  101. _cleanDir(tempDir)
  102. def readAvi(filename, asNumpy=True):
  103. """ readAvi(filename, asNumpy=True)
  104. Read images from an AVI (or MPG) movie.
  105. Requires the "ffmpeg" application:
  106. * Most linux users can install using their package manager
  107. * There is a windows installer on the visvis website
  108. """
  109. # Check whether it exists
  110. if not os.path.isfile(filename):
  111. raise IOError('File not found: '+str(filename))
  112. # Determine temp dir, make sure it exists
  113. tempDir = os.path.join( os.path.expanduser('~'), '.tempIms')
  114. if not os.path.isdir(tempDir):
  115. os.makedirs(tempDir)
  116. # Copy movie there
  117. shutil.copy(filename, os.path.join(tempDir, 'input.avi'))
  118. # Run ffmpeg
  119. command = "ffmpeg -i input.avi im%d.jpg"
  120. S = subprocess.Popen(command, shell=True, cwd=tempDir,
  121. stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  122. # Show what mencodec has to say
  123. outPut = S.stdout.read()
  124. if S.wait():
  125. # An error occured, show
  126. print(outPut)
  127. print(S.stderr.read())
  128. # Clean up
  129. _cleanDir(tempDir)
  130. raise RuntimeError("Could not read avi.")
  131. else:
  132. # Read images
  133. images = images2ims.readIms(os.path.join(tempDir, 'im*.jpg'), asNumpy)
  134. # Clean up
  135. _cleanDir(tempDir)
  136. # Done
  137. return images