Andreas Demmelbauer 3 лет назад
Сommit
6f3cb48c90
8 измененных файлов: 864 добавлений и 0 удалений
  1. +10
    -0
      .gitignore
  2. +0
    -0
     
  3. +3
    -0
      Requirements.txt
  4. +110
    -0
      canvas.svg
  5. +263
    -0
      export-gis-jpg.py
  6. +238
    -0
      gis-svg-stitcher.py
  7. +197
    -0
      mask.svg
  8. +43
    -0
      thermal-image-extractor.py

+ 10
- 0
.gitignore Просмотреть файл

@@ -0,0 +1,10 @@
source_images*
sources
output
playing-around
__pycache__
*.png
*.R
*.tif
*.tiff
*.jpg


+ 3
- 0
Requirements.txt Просмотреть файл

@@ -0,0 +1,3 @@
lxml
wand
PyExifTool

+ 110
- 0
canvas.svg Просмотреть файл

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="6000"
height="3000"
viewBox="0 0 6000 3000"
version="1.1"
id="svgroot"
sodipodi:docname="canvas.svg"
inkscape:version="1.1 (ce6663b3b7, 2021-05-25)"
enable-background="new"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<style>
.thermal_image {
opacity: .5 ;
}
g.tile[data-direction='down'] {
opacity: 1;
}
<!-- g.tile[data-direction='down'] .tile-offset-corr {
transform: translate(120px, 0px)
} -->
</style>
<defs id="defs2">
<!-- <filter
xmlns="http://www.w3.org/2000/svg"
style="color-interpolation-filters:sRGB;"
inkscape:label="Blur"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="filter156128"
x="-0.2" y="-0.2"
width="1.5"
height="1.5">
<feGaussianBlur
result="blur"
in="fbSourceGraphic"
id="feGaussianBlur156190"
stdDeviation="45 35"/>
</filter>
<mask
maskUnits="userSpaceOnUse"
id="tilefademask">
<rect
id="rect156378"
width="640"
height="512"
x="-180"
y="-25"
style="fill:#ffffff;filter:url(#filter156128)"
transform="matrix(0.77703373,0,0,0.74018882,207.24036,100.70559)" />
</mask> -->

</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="745"
inkscape:cy="535"
inkscape:document-units="px"
inkscape:current-layer="tiles"
showgrid="false"
units="px"
scale-x="1"
inkscape:window-width="1920"
inkscape:window-height="1080"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:pagecheckerboard="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>


<g
inkscape:label="tiles"
inkscape:groupmode="layer"
id="tiles"
transform="translate(0,0)"
style="" />

<g
inkscape:label="tile_rows"
inkscape:groupmode="layer"
id="tile_rows"
transform="translate(0,0)"
style="" />

</svg>

+ 263
- 0
export-gis-jpg.py Просмотреть файл

@@ -0,0 +1,263 @@
import os
import argparse
import lxml.etree as ET
import subprocess
import flirimageextractor
import cv2
import numpy as np
from pathlib import Path
from wand.image import Image
from osgeo import gdal
from osgeo import osr

arg_parser = argparse.ArgumentParser(description='Export SVG composition of FLIR images as TIFF with thermo layer')

arg_parser.add_argument('Input',
metavar='input_svg',
type=str,
help='Path to the input SVG file cotaining xlinks to FLIR images')

arg_parser.add_argument('Output',
metavar='output_tiff',
type=str,
help='Output filename')


args = arg_parser.parse_args()
dirname = os.path.dirname(__file__)
INPUT_PATH = os.path.join(dirname, args.Input)
INPUT_DIR = os.path.split(INPUT_PATH)[0]

TEMP_MAP_THERMALPNG_SVG_PATH = os.path.join(INPUT_DIR, 'map_thermalpng.svg')
TEMP_MAP_THERMALPNG_PATH = os.path.join(INPUT_DIR, 'map_thermalpng.png')
TEMP_MAP_PREVIEW_PATH = os.path.join(INPUT_DIR, 'map_preview.png')
THERMALPNG_DIR = 'thermalpngs'

OUTPUT_PATH = os.path.join(dirname, args.Output)



def make_thermalpng_tiles():
"""
Extract thermal infomration as greyscale PNG-16 (temp * 1000 to retain some decimals)
and save the png tiles
"""
Path(os.path.join(INPUT_DIR, THERMALPNG_DIR)).mkdir(parents=True, exist_ok=True)
png_output_dir = os.path.join(INPUT_DIR, THERMALPNG_DIR)

for root_path, directories, file in os.walk(os.path.join(dirname, INPUT_DIR)):
for file in file:
if(file.endswith(".jpg")):
print('Extracting thermal info from ' + file)
full_filepath = os.path.join(root_path, file)
flir = flirimageextractor.FlirImageExtractor()
flir.process_image(full_filepath)
thermal_img_np = flir.thermal_image_np
multiplied_image = cv2.multiply(thermal_img_np, 1000)
output_file_path = os.path.join(png_output_dir, file + '.thermal.png')
print(output_file_path)
cv2.imwrite(output_file_path, multiplied_image.astype(np.uint16))




def make_thermalpng_svg():
"""
replaces the image paths with the thermal pngs
and creates new SVG file
"""
# print("svg_file")
# print(dir(svg_file))
tree = ET.parse(INPUT_PATH)
root = tree.getroot()
# print(ET.tostring(root))
# tile_rows = root.xpath('//image', namespaces={'n': "http://www.w3.org/2000/svg"})
# print(dir(root))
tile_elements = root.xpath('//*[@class="thermal_image"]')
linkattrib ='{http://www.w3.org/1999/xlink}href'
for tile in tile_elements:
tile.attrib[linkattrib] = os.path.join(THERMALPNG_DIR, tile.attrib[linkattrib] + '.thermal.png')
# newxml = ET.tostring(tree, encoding="unicode")
# print(newxml)
# return newxml

with open(TEMP_MAP_THERMALPNG_SVG_PATH, 'wb') as f:
tree.write(f, encoding='utf-8')

return tree



def make_thermalpng():
"""
exports the SVG canvas as Gray_16 PNG
"""
command = [
'/snap/bin/inkscape',
'--pipe',
'--export-type=png',
'--export-png-color-mode=Gray_16'
],
input_file = open(TEMP_MAP_THERMALPNG_SVG_PATH, "rb")
output_file = open(TEMP_MAP_THERMALPNG_PATH, "wb")
completed = subprocess.run(
*command,
cwd=INPUT_DIR, # needed for reative image links
stdin=input_file,
stdout=output_file
)
return completed

def make_thermalpreview():
"""
exports the preview image
"""
command = [
'/snap/bin/inkscape',
'--pipe',
'--export-type=png',
'--export-png-color-mode=Gray_8'
],
input_file = open(TEMP_MAP_THERMALPNG_SVG_PATH, "rb")
output_file = open(TEMP_MAP_PREVIEW_PATH, "wb")
completed = subprocess.run(
*command,
cwd=INPUT_DIR, # needed for reative image links
stdin=input_file,
stdout=output_file
)
return completed

# def make_thermalpreview():
# """
# exports the preview image
# """
# command = [
# '/snap/bin/inkscape',
# '--pipe',
# '--export-type=png',
# '--export-png-color-mode=Gray_8'
# ]
# input_file = open(TEMP_MAP_THERMALPNG_SVG_PATH, "rb")
# output_file = open(TEMP_MAP_PREVIEW_PATH, "wb")
# completed = subprocess.run(
# *command,
# cwd=INPUT_DIR, # needed for reative image links
# stdin=input_file,
# stdout=output_file
# )
# return completed


def get_thermal_numpy_array():
# input_file = open(TEMP_MAP_THERMALPNG_PATH, "rb")
image = cv2.imread(TEMP_MAP_THERMALPNG_PATH, cv2.IMREAD_ANYDEPTH)
image_float = image.astype(np.float32)
image_float_normalized = cv2.divide(image_float, 1000)
print(image_float_normalized[1000][905])
# cv2.imshow("OpenCV Image Reading", image)
return image_float_normalized

def get_used_tiles_relpaths():
"""
outputs an array of all used tile filenames in the input SVG
(relative filepaths like they appear in the svg.)
"""
images = []
tree = ET.parse(INPUT_PATH)
root = tree.getroot()
tile_elements = root.xpath('//*[@class="thermal_image"]')
linkattrib ='{http://www.w3.org/1999/xlink}href'
for tile in tile_elements:
images.append(tile.attrib[linkattrib])
return images

def deg_coordinates_to_decimal(coordStr):
coordArr = coordStr.split(', ')
calculatedCoordArray = []
for calculation in coordArr:
calculationArr = calculation.split('/')
calculatedCoordArray.append(int(calculationArr[0]) / int(calculationArr[1]))
degrees = calculatedCoordArray[0]
minutes = calculatedCoordArray[1]
seconds = calculatedCoordArray[2]
decimal = (degrees + (minutes * 1/60) + (seconds * 1/60 * 1/60))
# print(decimal)
return decimal


def read_coordinates_from_tile(filename):
full_filepath = os.path.join(INPUT_DIR, filename)
with Image(filename=full_filepath) as image:
for key, value in image.metadata.items():
if key == 'exif:GPSLatitude':
# print('latstr', value)
lat = deg_coordinates_to_decimal(value) # lat -> Y vertical
if key == 'exif:GPSLongitude':
# print('lonstr', value)
lon = deg_coordinates_to_decimal(value) # lon -> X horizontal
if key == 'exif:GPSImgDirection':
direction = value.split('/')
print(int(direction[0])/int(direction[1])/2, ' ', (value))
return [lat, lon]

def get_coordinate_boundaries():
image_names = get_used_tiles_relpaths()
coordinates = {
'lat': [],
'lon': []
}
for filename in image_names:
tile_coordinates = read_coordinates_from_tile(filename)
coordinates['lat'].append(tile_coordinates[0])
coordinates['lon'].append(tile_coordinates[1])

boundaries = {
'xmin': min(coordinates['lon']),
'xmax': max(coordinates['lon']),
'ymin': min(coordinates['lat']),
'ymax': max(coordinates['lat']),
}
return boundaries


def make_geotiff_image():
thermal_numpy_array = get_thermal_numpy_array()

# coordinates of all tiles
geo_bound = get_coordinate_boundaries()
print('boundaries', geo_bound)

np_shape = thermal_numpy_array.shape
image_size = (np_shape[0], np_shape[1])

# set geotransform
nx = image_size[0]
ny = image_size[1]
xres = (geo_bound['xmax'] - geo_bound['xmin']) / float(nx)
yres = (geo_bound['ymax'] - geo_bound['ymin']) / float(ny)
geotransform = (geo_bound['xmin'], xres, 0, geo_bound['ymax'], 0, -yres)

# create the 3-band raster file
dst_ds = gdal.GetDriverByName('GTiff').Create(OUTPUT_PATH, ny, nx, 1, gdal.GDT_Float32)
dst_ds.SetGeoTransform(geotransform) # specify coords
srs = osr.SpatialReference() # establish encoding
res = srs.SetWellKnownGeogCS( "WGS84" ) # WGS84 lat/long
dst_ds.SetProjection(srs.ExportToWkt()) # export coords to file
dst_ds.GetRasterBand(1).WriteArray(thermal_numpy_array) # write thermal-band to the raster
dst_ds.FlushCache() # write to disk




# make_thermalpng_tiles()
# make_thermalpng_svg()
# make_thermalpreview()
# make_thermalpng()
make_geotiff_image()


# dataset = gdal.Open("working_result_example.tif", gdal.GA_ReadOnly)
# print(dir(dataset))
# print(dataset.GetMetadata_List())

+ 238
- 0
gis-svg-stitcher.py Просмотреть файл

@@ -0,0 +1,238 @@
from wand.image import Image
import PIL.Image
import io
import exiftool
import subprocess
import os
import lxml.etree as ET
import copy

import cv2
import flirimageextractor
from matplotlib import cm
import numpy as np
import urllib.request



dirname = os.path.dirname(__file__)

working_dir = 'source_images_full'


filename = os.path.join(dirname, 'canvas.svg')
tree = ET.parse(filename)

root = tree.getroot()
d = root.nsmap

main_layer = root.xpath('//*[@id="tiles"]', namespaces={'n': "http://www.w3.org/2000/svg"})[0]

tile_rows = root.xpath('//*[@id="tile_rows"]', namespaces={'n': "http://www.w3.org/2000/svg"})[0]


def deg_coordinates_to_decimal(coordStr):
coordArr = value.split(', ')
calculatedCoordArray = []
for calculation in coordArr:
calculationArr = calculation.split('/')
calculatedCoordArray.append(int(calculationArr[0]) / int(calculationArr[1]))
degrees = calculatedCoordArray[0]
minutes = calculatedCoordArray[1]
seconds = calculatedCoordArray[2]
return (degrees + (minutes * 1/60) + (seconds * 1/60 * 1/60))

# # extracting TIF Data
# for root, directories, file in os.walk(os.path.join(dirname, working_dir)):
# for file in file:
# if(file.endswith(".jpg")):
# print(os.path.join(root, file))
# full_filepath = os.path.join(root, file)
# with exiftool.ExifTool() as et:
# cmd = ['exiftool', full_filepath, "-b", "-RawThermalImage"]
# tif_data = subprocess.check_output(cmd)
# tif_image = PIL.Image.open(io.BytesIO(tif_data))
# tif_filepath = os.path.join(dirname, working_dir, file.split('.')[0] + '_thermal.tif')
# tif_image.save(tif_filepath)
# print(tif_filepath)


# finding the boundaries of the whole canvas
latsArr = []
lonsArr = []
for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)):
for file in file:
if(file.endswith(".jpg")):
print(os.path.join(root_path, file))
full_filepath = os.path.join(root_path, file)
with Image(filename=full_filepath) as image:
print(image.width)
print(image.height)
for key, value in image.metadata.items():
if key == 'exif:GPSLatitude':
lat = deg_coordinates_to_decimal(value) # lat -> Y vertical
latsArr.append(lat)
print("{}: {}".format(key, value))
print('lat '+ str(lat))
if key == 'exif:GPSLongitude':
lon = deg_coordinates_to_decimal(value) # lon -> X horizontal
lonsArr.append(lon)
print("{}: {}".format(key, value))
print('lon '+ str(lon))


minLat = min(latsArr)
minLon = min(lonsArr)
maxLat = max(latsArr)
maxLon = max(lonsArr)
width = maxLon - minLon
height = maxLat- minLat




# placing the images into the svg

rotation = 125

y_scale = -1800000 #-400000
x_scale = 655000 #-950000

# y_scale = 2600000 #-400000
# x_scale = 1200000 #-950000

image_rotation_up = rotation #32
image_rotation_down = rotation + 180 #192

for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)):
for file in file:
if(file.endswith(".jpg")):
print(os.path.join(root_path, file))
full_filepath = os.path.join(root_path, file)
with Image(filename=full_filepath) as image:
print(image.width)
print(image.height)
for key, value in image.metadata.items():
# print("{}: {}".format(key, value))
if key == 'exif:GPSLatitude':
lat = deg_coordinates_to_decimal(value) - minLat
print('lat '+ str(lat))
if key == 'exif:GPSLongitude':
lon = deg_coordinates_to_decimal(value) - minLon
print('lon '+ str(lon))
if key == 'exif:GPSImgDirection':
direction = value.split('/')
rotation = int(direction[0])/int(direction[1])/2

g_pos_el_attributes = {
# 'x': str(lat*scale),
# 'y': str(lon*scale),
'transform': "translate({}, {})".format(format(lon*x_scale, '.20f'), format(lat*y_scale, '.20f')),
'data-lat': format(lat, '.20f'),
'data-lon': format(lon, '.20f'),
'class': 'tile',
'id': 'tile_{}'.format(file.split('.')[0]),
# 'style': 'opacity:.6',
}
g_pos_el = ET.SubElement(main_layer, 'g', attrib=g_pos_el_attributes)

g_offset_corr_el_attributes = {
'transform': "translate(150, 0)",
'class': 'tile-offset-corr',
}
g_offset_corr_el = ET.SubElement(g_pos_el, 'g', attrib=g_offset_corr_el_attributes)


g_center_el_attributes = {
'class': 'tile-center',
'transform': 'translate({}, {})'.format(str(image.width/2*-1), str(image.height/2*-1))
}
g_center_el = ET.SubElement(g_offset_corr_el, 'g', attrib=g_center_el_attributes)

g_rot_el_attributes = {
'class': 'tile-rotate',
'data-image-rotation': str(image_rotation_up),
'data-image-dimensions': str(image.width/2) + ' ' + str(image.height/2),
'transform': 'rotate({} {} {})'.format(str(image_rotation_up), str(image.width/2), str(image.height/2))
}
g_rot_el = ET.SubElement(g_center_el, 'g', attrib=g_rot_el_attributes)

xlinkns ="http://www.w3.org/1999/xlink"
image_el = ET.SubElement(g_rot_el, 'image', {
"class": 'thermal_image',
"{%s}href" % xlinkns: file,
"width": str(image.width),
"height": str(image.height),
"mask" : "url(#tilefademask)",
})

# transform_str = "translate(-{}, -{})".format(str(min(latsArr)*scale), str(min(lonsArr)*scale))
# print(transform_str)
# main_layer.attrib['transform'] = transform_str



# sort elements
def getkey(elem):
# Used for sorting elements by @LIN.
# returns a tuple of ints from the exploded @LIN value
# '1.0' -> (1,0)
# '1.0.1' -> (1,0,1)
return float(elem.get('id').split('_')[2])

main_layer[:] = sorted(main_layer, key=getkey)


# rotate image if previous element is under the current one
last_state = 'down'
for index, el in enumerate(main_layer):
if(el.getprevious() is not None):
if (el.getprevious().attrib['data-lon'] > el.attrib['data-lon'] or (el.getprevious().attrib['data-lon'] == el.attrib['data-lon'] and last_state == 'up')):
print('up')
rot_el = el[0][0][0]
# print(rot_el.attrib['data-image-rotation'])
# print(rot_el.attrib['data-image-dimensions'])
el.attrib['data-direction'] = 'up'

# print(el.attrib['data-lat'], el.getprevious().attrib['data-lat'])
else:
rot_el = el[0][0][0]
el.attrib['data-direction'] = 'down'
# el.attrib['style'] = 'opacity:0'
new_rotation = image_rotation_down #float(rot_el.attrib['data-image-rotation']) + 180
rot_el.attrib['transform'] = "rotate({} {})".format(str(new_rotation), rot_el.attrib['data-image-dimensions'])
print('down')
# print(rot_el.attrib['data-image-rotation'])
# print(rot_el.attrib['data-image-dimensions'])

# merge tiles into groups
print(index)
print("el.attrib['data-direction'] " + el.attrib['data-direction'])
print("last_state " + last_state)
if index is 1 or last_state != el.attrib['data-direction']:
current_row = ET.SubElement(tile_rows, 'g', attrib={ 'class': 'tile-row' })
copyElem = copy.deepcopy(el)
current_row.insert(0, copyElem)
last_state = el.attrib['data-direction']

root.remove(main_layer)


with open(os.path.join(working_dir,'map.svg'), 'wb') as f:
tree.write(f, encoding='utf-8')



# # get some base satellite map for reference
# apikey = "MYaMHCLtPz1fUfe0FzZqOMI35m893jIV80oeHG19Piw"
# lon_center =
# lat_center =
# zoom =
# map_width =
# request = "https://image.maps.ls.hereapi.com/mia/1.6/mapview?apiKey={}&c={},{}&sb=mk&t=1&z={}&w={}&nodot".format(apikey, lon_center, lat_center, zoom, map_width)

# svg = ET.tostring(tree, encoding="unicode")
# print(svg)

print('Done!')

+ 197
- 0
mask.svg Просмотреть файл

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
width="1920"
height="1080"
viewBox="0 0 1920 1080"
version="1.1"
id="svg8"
sodipodi:docname="mask.svg"
inkscape:version="1.1 (ce6663b3b7, 2021-05-25)"
enable-background="new"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<style
id="style212248">
#image156515 {
fill:#f00;
}
</style>
<defs
id="defs2">
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Blur"
id="filter156128"
x="-0.225"
y="-0.28125"
width="1.45"
height="1.5625">
<feGaussianBlur
stdDeviation="20 20"
result="fbSourceGraphic"
id="feGaussianBlur156126" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix156166" />
<feGaussianBlur
id="feGaussianBlur156168"
stdDeviation="20 20"
result="fbSourceGraphic"
in="fbSourceGraphic" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix156188" />
<feGaussianBlur
id="feGaussianBlur156190"
stdDeviation="20 20"
result="blur"
in="fbSourceGraphic" />
</filter>
<mask
maskUnits="userSpaceOnUse"
id="mask156376">
<rect
id="rect156378"
width="640"
height="512"
x="762.2807"
y="227.90842"
style="fill:#ffffff;filter:url(#filter156128)"
transform="matrix(0.77703373,0,0,0.74018882,207.24036,100.70559)" />
</mask>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.28748238"
inkscape:cx="1087.0231"
inkscape:cy="-401.76375"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
scale-x="1"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:pagecheckerboard="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-11.249983)"
style="">
<g
id="g155860"
transform="translate(-728.00885,-195.75467)"
mask="url(#mask156376)">
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125946_R.jpg"
id="image155751"
x="728.00885"
y="207.00465" />
</g>
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125920_R.jpg"
id="image156515"
x="780"
y="-80.464302"
style="" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125921_R.jpg"
id="image156527"
x="1368.5714"
y="616.67853" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125922_R.jpg"
id="image156539"
x="1751.8823"
y="-283.38199" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125924_R.jpg"
id="image156563"
x="1785.2552"
y="-97.210777" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125923_R.jpg"
id="image156551"
x="1772.9646"
y="-189.51526" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125925_R.jpg"
id="image156575"
x="1800.0695"
y="1.4803357" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125926_R.jpg"
id="image156587"
x="1810.1398"
y="115.43749" />
<image
width="640"
height="512"
preserveAspectRatio="none"
xlink:href="source_images_full/20200621_125927_R.jpg"
id="image156599"
x="1830.4902"
y="197.49077" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 2391.8823,-283.38199 78.6079,480.87276"
id="path156735" />
</g>
</svg>

+ 43
- 0
thermal-image-extractor.py Просмотреть файл

@@ -0,0 +1,43 @@
import cv2
# import flirimageextractor
# flir = flirimageextractor.FlirImageExtractor()
# flir.process_image('source_images_full/20200621_125936_R.jpg',RGB=True)
# c = flir.get_metadata('source_images_full/20200621_125936_R.jpg')
# img = flir.extract_embedded_image()

import flirimageextractor
from matplotlib import cm
import numpy as np
# flir = flirimageextractor.FlirImageExtractor()
# flir.process_image('source_images_full/20200621_125936_R.jpg')
# flir.save_images()
# flir.plot()



flir = flirimageextractor.FlirImageExtractor()
flir.process_image('source_images_full/20200621_125936_R.jpg')
# img = flir.save_images() #min=0,max=64,
# print(dir(img))
# print(img)
thermal_img_np = flir.thermal_image_np
h,w = thermal_img_np.shape
# print(flir.flir_img_bytes())

print(thermal_img_np)
print(type(thermal_img_np[0][0]))
print(h)
print(w)

# cv2.imdecode(thermal_img_np)

multiplied_image = cv2.multiply(thermal_img_np, 1000)

cv2.imwrite('color_img.png', multiplied_image.astype(np.uint16))



# img.astype('uint8')

# image = cv2.imdecode(thermal_img_np,4)
# print('Image Dimensions :', image.shape)

Загрузка…
Отмена
Сохранить