Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions multispectral/double4k.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
"""
double4k.py.py

@author: John Jackson
@date: 08/10/2017

Used for performing reflectance preprocessing for Double4k Imagery.
Prototype script, not production ready.
"""

import csv
import os
import sys

import piexif
from PIL import Image, ImageMath

PIX4DCSV_FILENAME = 'pix4d.csv'
NEWPIX4DCSV_FILENAME = 'newpix4d.csv'
AUTOEXPOSURECSV_FILENAME = 'autoexposure.csv'


def post_process(dirs, processed_subdir='processed'):
for dirstring in dirs:

outdirstring = os.path.join(dirstring, processed_subdir)
if not os.path.isdir(outdirstring): os.mkdir(outdirstring)

# csvname_autoexposure = os.path.join(dirstring, AUTOEXPOSURECSV_FILENAME)
# if not os.path.exists(csvname_autoexposure):
# raise Exception("File not found: " + csvname_autoexposure)
#
# csvname_pix4d = os.path.join(dirstring, PIX4DCSV_FILENAME)
# if not os.path.exists(csvname_pix4d):
# raise Exception("File not found: " + csvname_pix4d)

# csv_pix4d = open(csvname_pix4d, 'r')
#
# csvname_newpix4d = os.path.join(os.path.join(dirstring, processed_subdir), NEWPIX4DCSV_FILENAME)
# csv_newpix4d = open(csvname_newpix4d, 'w+')
# csv_newpix4d.write(csv_pix4d.readline())
#
# csvreader = csv.reader(csv_pix4d, delimiter=',')
# csvwriter = csv.writer(csv_newpix4d, delimiter=',')

allfiles = os.listdir(dirstring)
jpgfilenames = [name for name in allfiles if str.find(name, '.jpg') > 0]

# for row in csvreader:
# jpgfiles.append(row[0])
#
# row_new = row
# row_new[0] = row_new[0][0:len(row_new[0]) - 4] + '.tif'
# csvwriter.writerow(row_new)
#
# csv_pix4d.close()
# csv_newpix4d.close()

# This is naiive, assuming the right order of jpg files and autoexposure measurements without checking the timestamp.
# csv_autoexposure = open(csvname_autoexposure, 'r')
# csv_autoexposure.readline()
# csvreader = csv.reader(csv_autoexposure, delimiter=',')

# TODO: The value of this constant.
k = 1.

# TODO: Graphical Progress Update
for jpgfile in jpgfilenames:

jpgfilename = os.path.join(dirstring, jpgfile)
exif_dict = piexif.load(jpgfilename)

exposure_tup = exif_dict['Exif'][33434]
exposure_time = exposure_tup[0]/exposure_tup[1]
print("Exposure time: " + str(exposure_time))

# f_tup = exif_dict['Exif'][33437]
# f_number = f_tup[0]/f_tup[1]

iso = exif_dict['Exif'][34855]
iso_factor = iso/100
print("ISO factor: " + str(iso_factor))

# brightness = exif_dict['Exif'][37379]
# meteringmode = exif_dict['Exif'][37383]
# focallength = exif_dict['Exif'][37386]

cal = 1. / (k * exposure_time * iso_factor)

im = Image.open(os.path.join(dirstring, jpgfile))
[red, green, blue, ] = im.split()
im.close()

# Red
temp = ImageMath.eval("float(a)", a=red)
out = temp.point(lambda i: i * cal)
outsubdirstring = os.path.join(outdirstring, 'red')
if not os.path.isdir(outsubdirstring): os.mkdir(outsubdirstring)
outfile = os.path.join(outsubdirstring, jpgfile[0:len(jpgfile) - 4] + '-red.tif')
out.save(outfile, "TIFF")

# Red
temp = ImageMath.eval("float(a)", a=green)
out = temp.point(lambda i: i * cal)
outsubdirstring = os.path.join(outdirstring, 'green')
if not os.path.isdir(outsubdirstring): os.mkdir(outsubdirstring)
outfile = os.path.join(outsubdirstring, jpgfile[0:len(jpgfile) - 4] + '-green.tif')
out.save(outfile, "TIFF")

# Red
temp = ImageMath.eval("float(a)", a=blue)
out = temp.point(lambda i: i * cal)
outsubdirstring = os.path.join(outdirstring, 'blue')
if not os.path.isdir(outsubdirstring): os.mkdir(outsubdirstring)
outfile = os.path.join(outsubdirstring, jpgfile[0:len(jpgfile) - 4] + '-blue.tif')
out.save(outfile, "TIFF")

#csv_autoexposure.close()


if __name__ == "__main__":
usage = 'usage: double4k.py <list of dirs> <(opt) name of target subdirectory, default is \'processed\'>'
if len(sys.argv) > 1:
sys.argv.pop(0)
post_process(sys.argv)

else:
print(usage)
49 changes: 47 additions & 2 deletions multispectral/quadband.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,29 @@
import csv
import os
import sys
import numpy as np

from PIL import Image, ImageMath

PIX4DCSV_FILENAME = 'pix4d.csv'
NEWPIX4DCSV_FILENAME = 'newpix4d.csv'
AUTOEXPOSURECSV_FILENAME = 'autoexposure.csv'

# Defaults
LEAKAGE_LIGHT_FACTOR = 0.00
QE_FACTOR = 1.0

# 655nm
# LEAKAGE_LIGHT_FACTOR = 0.05
# QE_FACTOR = 18.53

# 725nm
# LEAKAGE_LIGHT_FACTOR = 0.085
# QE_FACTOR = 46.57

# 800nm
# LEAKAGE_LIGHT_FACTOR = 0.12
# QE_FACTOR = 60.29

def post_process(dirs, processed_subdir='processed'):
for dirstring in dirs:
Expand Down Expand Up @@ -60,18 +76,47 @@ def post_process(dirs, processed_subdir='processed'):

# TODO: The value of this constant.
k = 1.
frame_period_us = 22000
shutter_efficiency = 1/650

# TODO: Graphical Progress Update
for jpgfile, csvrow in zip(jpgfiles, csvreader):

cal = 1./(k * int(csvrow[1]) * pow(2,int(csvrow[2])) * int(csvrow[3]))

im = Image.open(os.path.join(dirstring,jpgfile))
[_, img, _,] = im.split()

if im.mode == 'RGB':
[_, img, _,] = im.split()
elif im.mode == 'L':
[img] = im.split()
else:
raise Exception("Invalid image format: " + im.mode)

im.close()

temp = ImageMath.eval("float(a)", a=img)
out = temp.point(lambda i: i*cal)
nimg = np.asarray(temp, dtype=np.float32)

# Apply Shutter Efficiency Correction
shutter_efficiency_correction_factor = 1 / (1 + ((shutter_efficiency * frame_period_us) / int(csvrow[1])))
nimg = nimg * shutter_efficiency_correction_factor

# Apply Leakage Light Correction
total = 0
mean = nimg.mean()
offset = LEAKAGE_LIGHT_FACTOR * mean
nimg = nimg - offset


# Apply Exposure Opportunity Correction
nimg = nimg * cal

# Apply Reflectance Scaling
nimg = nimg * QE_FACTOR

# Convert numpy to pillow
out = Image.fromarray(nimg)

outfile = os.path.join(outdirstring, jpgfile[0:len(jpgfile)-4] + '.tif')
out.save(outfile, "TIFF")
Expand Down