Ex3 - Apocalypse now

Introduction

You are working as a GIS specialist in an UN organization dealing with the Syrian conflict. Your boss gives you daily KML data on reported fights in the field (points) and territory definition (areas). He asks you to create nice visualization to prove that a surrounding technique is used to besiege the city of Ma‘baţlī.

You have already developed a fairly complex workspace. It reads all KML files and create images out of them. The images are centered on the city of Ma‘baţlī. You show the result to your boss, he is quite pleased, but he asks you to produce not only pictures, but also an animated movie.

https://inser.gitbooks.io/fme-python-course/content/assets/11_03_2018.png

Despite having many thousands of formats, FME can not directly export a movie. However, you know that with a litlle bit of python you could transform the images into a movie. After some research on the internet, the OpenCV package seems to be the perfect tool for that. Since it is not a build-in package, you need to use an external Python interpretor with FME. That will be the challenge of this exercise !

Objective

Create this movie :

https://youtu.be/nJDjT1eARqM

Workspace description

As mentioned, this workspace is fairly complex. Here's a quick run-down of what it does.

First of all, dates are read and formatted.

https://inser.gitbooks.io/fme-python-course/content/assets/dfhdgfh.png

We define the name and the color of the armed forces.

https://inser.gitbooks.io/fme-python-course/content/assets/fhgfhgf.png

Like this, the name will be nicely displayed on the legend map, rather than the abbreviation from the dataset.

Then, the text of the legend is created :

https://inser.gitbooks.io/fme-python-course/content/assets/gdfgimport.png

Same thing with the color of the legend :

https://inser.gitbooks.io/fme-python-course/content/assets/rthutzimport.png

And the date is also added to the image:

https://inser.gitbooks.io/fme-python-course/content/assets/fdsgaaimport.png

And the position of the city of Ma‘baţlī :

https://inser.gitbooks.io/fme-python-course/content/assets/dgfdgimport.png

Finally, the picture is created from the vector data and written on a local folder :

https://inser.gitbooks.io/fme-python-course/content/assets/dgdsafimport.png

The MapnikRasterizer is a fairly complex transformer to rasterize vector features. Note that we used a "group by" option to create one picture per day, so as to not end with all the information in one single picture. The same parameter (and mechanism) has been used in the writer to export one picture file per day.

Exercise

1) Add the OpenCV python package

From a Windows comand prompt, localise your PIP installation folder, as below :


cd C:\Python365-64\Scripts

After that, install OpenCV


pip install opencv-python

This python package will help us to create a movie out of the pictures

Once installed, check the installation by typing :


cd ..

followed by :

python

And then :


import cv2

If there is no error or warning, it means the installation was successful.

https://inser.gitbooks.io/fme-python-course/content/assets/fsdfsdg.png

2) Configure FME

As soon as python has been correctly installed on the computer, we need to tell FME to use this python interpreter. This can be done as follow :

  • Select Tools > FME Options from the menubar
  • Select the tab for "Translation“
  • Change the preferred Python interpreter as follows :

https://inser.gitbooks.io/fme-python-course/content/assets/sdfsfffffimport.png

Once this is done, FME will use the new python interpreter, and will be able to use the OpenCV package.

3) Change the Python Compatibility parameter

https://inser.gitbooks.io/fme-python-course/content/assets/dsfdsfimport.png

4) Shutdown script

The script that merges pictures into a movie must be, of course, run after all images have been written. We will therefore place the script in the Shutdown Python script:

https://inser.gitbooks.io/fme-python-course/content/assets/dsgdfaimport.png

First, let’s import the two following packages :


import cv2

import os

Next, we can define the paths :


# Path 

folder_pictures = FME_MacroValues['DestDataset_PNGRASTER']

path_movie = os.path.join(folder_pictures, 'movie.mp4')

And now, let’s create a list of the pictures :


# List of pictures 

images = []

for f in os.listdir(folder_pictures):

    images.append(f)

Next step is to define the format of the movie using the first image


# Determine the width and height from the first image

image_path = os.path.join(folder_pictures, images[0])

frame = cv2.imread(image_path)

cv2.imshow('video', frame)

height, width, channels = frame.shape

And we define the codec and the object


# Define the codec and create VideoWriter object

fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use lower case

out = cv2.VideoWriter(path_movie, fourcc, 1, (width, height))

Finally, pictures can be merged to create the movie


for image in images:

    image_path = os.path.join(folder_pictures, image)

    frame = cv2.imread(image_path)

    out.write(frame) # Write out frame to video

And now, if you run the workspace, you will see a new file called movie.mp4 in the pictures folder.

Full code :


import cv2

import os

# Path 

folder_pictures = FME_MacroValues['DestDataset_PNGRASTER']

path_movie = os.path.join(folder_pictures, 'movie.mp4')

# List of pictures 

images = []

for f in os.listdir(folder_pictures):

    images.append(f)

# Determine the width and height from the first image

image_path = os.path.join(folder_pictures, images[0])

frame = cv2.imread(image_path)

cv2.imshow('video', frame)

height, width, channels = frame.shape

# Define the codec and create VideoWriter object

fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use lower case

out = cv2.VideoWriter(path_movie, fourcc, 1, (width, height))

for image in images:

    image_path = os.path.join(folder_pictures, image)

    frame = cv2.imread(image_path)

    out.write(frame) # Write out frame to video

Optional advanced task

Having a script in the shutdown python parameter is not always ideal if you aren't working with FME on a regular basis - the functionality is kind of hidden away in the workspace. Another solution could be to use a FeatureWriter to write the picture files (rather than the normal writer) and move the movie generation code to a PythonCaller, which will be instantly visible in the workspace when you open it up.

Why don't you give it a go !