UOC-Assignments/uoc.tfg.jbericat

TASK#04.6.1 - Simulació de visió tèrmica nocturna

Closed this issue · 9 comments

He revisat tant el codi de la implementació de IR com el paper associat al cas d'ús:

Instruccions d'implementació:

https://microsoft.github.io/AirSim/InfraredCamera/

Cas d'ús:

https://www.microsoft.com/en-us/research/publication/airsim-w-a-simulation-environment-for-wildlife-conservation-with-uavs/

Aquesta implementació de IR és específica per a l'entorn UE "Africa environment" (AE), el qual ha sigut modificat per a què cada individu (especie animal) tingui un "blueprint" termal obtingut d'una base de dades externa (mitjana estadística). A l'entorn LandscapeMountains (LME) modificat que utilitzem per a la PoC, els actors "emissors" / VFX de foc (objectes de UE) no tenen assignat cap blueprint termal, però. Caldria: 1) obtenir l'entorn AE del Unreal Marketplace amb Windows, 2) adaptar-lo per a editar-lo amb el UE4Editor d'Ubuntu, 3) Obtenir informació de com s'ha assignat el blueprint termal (e.g. per enginyeria inversa, revisant el codi py), 4) Trobar la manera de fer que el els actors emissors del LME tinguin diferents blueprints en funció de la intensitat de les flames, tot modificant els mateixos paràmetres del AE al LME.

OK després de dedicar-li unes hores vaig poder posar en funcionament l'script següent a l'entorn Unreal "AE":

https://github.com/microsoft/AirSim/blob/master/PythonClient/computer_vision/capture_ir_segmentation.py

En un principi el codi generava el següent error a l'executar-se:

Connected!
Client Ver:1 (Min Req: 1), Server Ver:1 (Min Req: 1)

capture_ir_segmentation.py:131: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead
  img1d = numpy.fromstring(responses[0].image_data_uint8, dtype=numpy.uint8)
Traceback (most recent call last):
  File "capture_ir_segmentation.py", line 243, in <module>
    irFolder='/home/jbericat/Documents/AirSim/Images/IR/') 
  File "capture_ir_segmentation.py", line 199, in main
    client)
  File "capture_ir_segmentation.py", line 132, in get_image
    im = img1d.reshape(responses[0].height, responses[0].width, 4) 
ValueError: cannot reshape array of size 110592 into shape (144,256,4)

Un cop ajustats els path i el tercer argument de la funció "reshape" amb un "3" en comptes de "4" l'script s'executa correctament:

    #Change images into numpy arrays.
    img1d = numpy.fromstring(responses[0].image_data_uint8, dtype=numpy.uint8)
    im = img1d.reshape(responses[0].height, responses[0].width, 3) 

    img1dscene = numpy.fromstring(responses[1].image_data_uint8, dtype=numpy.uint8)
    imScene = img1dscene.reshape(responses[1].height, responses[1].width, 3)

El codi readaptat es troba a https://github.com/UOC-Assignments/uoc.tfg.jbericat/blob/FITA%2303/src/AirSim/PythonClient/TFG-PoC/capture_ir_segmentation.py

Pel que sembla és un bug de l'script de visió tèrmica per a AirSim capture_ir_segmentation.py, (la darrera modificació data del 2018, segurament ha canviat la API d'AirSim des d'aleshores i no s'ha actualitzat l'script). Diria que el mètode reshape només fa que vectoritzar (1D) una imatge en 2D (matriu de pixels) i amb 3 Canals (RGB).

S'ha provat amb els binaris de l'entorn de Unreal "AE" i s'aconsegueix capturar imatges però no es troba cap animal que generi calor per comprovar que funciona la visió tèrmica nocturna. Faré unes quantes proves més i intentaré implementar-ho a l'entorn Unreal de la PoC (LME).

Finalment s'aconsegueix fer funcionar la visió tèrmica a l'entorn AE (imatges a baixa resolució 144x256, les marques en blanc són elefants):

ir_00141
ir_00455

A grans trets, l'algorisme que implementa capture_ir_segmentation.py funciona de la següent manera:

  1. En primer lloc s'obté un llistat de tots els objectes que contenen un tag i/o nom d'actor específic (en el nostre exemple "Elephant, Zebra, etc") al vector "objectList".
  2. Seguidament, es posiciona la càmera durant 1800 seg (30 mins) a les coordenades on hi ha l'objecte
  3. tot seguit es transformen els pixels de la imatge 3D en una imatge 2D IR (captura d'imatge 2D)
  4. Després es canvien els colors dels pixels de l'objecte actual del vector "objectList" en funció de la temperatura assignada
  5. Finalment es vectoritza la imatge i es desa en png

Cal notar que per a poder debugar l'script ha calgut modificar la línia 189 de la següent manera:

while elapsedTime < 5:

Així la càmera canvia d'objecte cada 5 segons, i no cada 30 mins.

OBSERVACIÓ: Potser seria bona idea fer un pull-request a AirSim -> https://github.com/microsoft/AirSim.git proposant la modificació dels arguments per als mètodes "reshape"

Ara el següent pas és adaptar capture_ir_segmentation.py i create_ir_segmentation_map.py per a obtenir IR+visió termal nocturna a l'entorn Unreal LME

Implementació de la visió termal nocturna aconseguida per a l'escenari LME. Handicap: No es pot assignar el blueprint de calor als VFX de foc del UE (han de ser objectes "sòlids").

He fet la prova assignant diferents graus de calor a elements nadius de l'escenari (aigua, terra, arbres, etc) i el resultat és acceptable (tot allò que surt en negre són objectes/grups de pixels als quals no se'ls ha assignat temperatura. El bloc en blanc és un objecte tipus "cube block" deformat, inserit per a fer proves):

ir_00008

De moment es deixa el projecte uns dies en stand-by per a rumiar com afecta el handicap indicat més amunt i decidir quins canvis s'hauran de fer a l'escenari de la PoC per a procedir a generar el dataset d'imatges.

Finalment s'ha decidit afegir al TFG la implementació d'un simulador de visió nocturna rudimentari tipus FLIR, basat en una modificació del codi per a visió tèrmica que proporciona la plataforma AirSim amb create_ir_segmentation.py i capture_ir_segmentation.py (concretament, una escala de grisos que simula una IR però definida de manera manual per a cada tipus d'objecte 3D projectat al mapa de pixels / imatge).

Aquesta decisió s'ha pres després de fer recerca de com simular de la manera més fidel possible la presa i anàlisi d'imatges aèries d'incendis en condicions de nocturnitat, per tal de poder generar un dataset per a entrenar la NN que no sigui del tot trivial. El següent enllaç inclou imatges d'exemple de l'efecte que es vol aconseguir i informació tècnica relacionada d'especial interés per al TFG (cal fer-hi menció a la memòria):

https://www.flir.co.uk/news-center/military/swedish-national-police-use-flir-in-key-fight-against-recent-swedish-wildfire/

Concretament, la implementació consisteix en utilitzar de partida capture_ir_segmentation.py per a prendre dues imatges del mateix escenari; una en RGB "estandàrd" i una altra amb IR tèrmica amb escala de grisos, on cada tonalitat de gris indica un rang de temperatures (que s'assignaran als objectes que emeten calor de manera manual al entorn LME de UE). Després, només cal buscar en quina posició de la matriu de pixels s'ha detectat calor en la imarge IR tèrmica i projectar el valor d'aquests píxels a la imatge en color RGB, de manera que se superposin ambdues imatges.

Ja s'ha pogut implementar la superposició d'imatges "Thermal+RGB". S'adjunta una mostra amb iluminació activada per no haver de carregar l'escenari nocturn només per agafar una captura (triga molt). Es documenta breument capture_ir_segmentation.py i es dona la tasca pendent de fer el merge del pull request associat #70 (v03.8) per a donar-la per finalitzada.

A) Imatge termal

ir_00000

B) Imatge RGB

scene_00000

C) Imatge composta (retallada)

screenshot

Es reobre task per a fer ajustos en els path i format de les imatges

Es reobre TASK per a fer ajustos menors al codi (comentaris). Enllaçat pull request #77

Es reassigna la tasca a la FITA#04 i s'actualitza la documentació de memòria parcial