def processImage(iset, sub, imagePath, imageRoot, band, radianceToReflectance): '''Does 4 steps: converts raw image to radiance based on metadata, converts radiance to relfectance based on panel calibration, un-distorts based on lens correction, and adds metadata to output''' outnm = 'Output\\%04i_%s_%s_%s_radiance.tiff' % (band, iset, sub, imageRoot) img = image.Image(imagePath) outImg = img.undistorted(img.reflectance(radianceToReflectance)) rows, cols = outImg.shape driver = gdal.GetDriverByName('GTiff') outRaster = driver.Create(outnm, cols, rows, 1, gdal.GDT_Float32) outband = outRaster.GetRasterBand(1) outband.WriteArray(outImg[:, :]) outband.FlushCache() tagsToCopy = ["EXIF:GPSAltitude"] #, # "EXIF:GPSAltitudeRef", # "EXIF:GPSDOP", # "EXIF:GPSLatitude", # "EXIF:GPSLatitudeRef", # "EXIF:GPSLongitude", # "EXIF:GPSLongitudeRef", # "EXIF:GPSVersionID" # ] print("Copying") meta = metadata.Metadata(imagePath, exiftoolPath=os.environ['exiftoolpath']) meta.copy(outnm, tagsToCopy) printExif(imagePath, tagsToCopy) printExif(outnm, tagsToCopy)
def reading_gain_exposure(image_path, ms_ext='tif', sub_dir=False): columns = ['image', 'gain', 'exposure', 'dls_gain', 'dls_exposure'] data_list = [] if image_path.endswith(ms_ext) or image_path.endswith( 'tiff'): # loading only one image names_list = image_path elif sub_dir: names_list = [ f for f in sorted( glob.glob(image_path + "/**/*." + ms_ext, recursive=True)) ] else: names_list = [ f for f in sorted( glob.glob(image_path + "/*." + ms_ext, recursive=True)) ] for n, im in enumerate(names_list): meta = metadata.Metadata(im) name = meta.get_item('File:FileName')[:-4] gain = meta.get_item('XMP:Gain') exposure = meta.get_item('XMP:Exposure') dls_gain = meta.get_item('XMP:IrradianceGain') dls_exposure = meta.get_item('XMP:IrradianceExposureTime') row = [name, gain, exposure, dls_gain, dls_exposure] data_list.append(row) print('image {} out of {}'.format(n + 1, len(names_list))) df = pd.DataFrame(data_list, index=None, columns=columns) return df
def createJson(filename, bombCoors): filepath = directory + filename img = metadata.Metadata(filepath) lat = img.get_item('Composite:GPSLatitude') long = img.get_item('Composite:GPSLongitude') yaw, pitch, roll = img.dls_pose() alt = img.get_item('Composite:GPSAltitude') elevation = getElevation(str(lat),str(long)) GPS, bombs = checkingIfBomb(getGPS(img, elevation, lat, long, alt), bombCoors) image_name = filename.split('.')[0][:-2] + '_stacked.tiff' data = { "image_name" : image_name, "yaw" : yaw, "pitch" : pitch, "roll": roll, "height" : alt - elevation, "GPS" : [ {"area" : "center", "lat" : lat, "long": long}, {"area": "top right", "lat" :GPS[0][0], "long": GPS[0][1]}, {"area": "top left", "lat" :GPS[1][0], "long": GPS[1][1]}, {"area": "bottom right", "lat" :GPS[2][0], "long": GPS[2][1]}, {"area": "bottom left", "lat" :GPS[3][0], "long": GPS[3][1]} ], "bombs" : [ ], } for index, bomb in enumerate(bombs): item = {"id" : index , "lat" : bomb[0], "long" : bomb[1]} data["bombs"].append(item) print(json.dumps(data, indent=4, sort_keys=True)) print() meta_json = os.path.join('stacked', 'metadata.json') with open(meta_json) as json_file: curr_data = json.load(json_file) temp= curr_data["images"] if( len(temp) == 0): temp.append(data) else: append = True for image in temp: if(image["image_name"] == data["image_name"]): append = False if append: temp.append(data) write_json(curr_data, meta_json)
def __init__(self, image_path): if not os.path.isfile(image_path): raise IOError("Provided path is not a file: {}".format(image_path)) self.path = image_path self.meta = metadata.Metadata(self.path) if not self.meta.supports_radiometric_calibration(): raise ValueError( 'Library requires images taken with camera firmware v2.1.0 or later. ' + 'Upgrade your camera firmware to use this library.') self.utc_time = self.meta.utc_time() self.latitude, self.longitude, self.altitude = self.meta.position() self.dls_present = self.meta.dls_present() self.dls_yaw, self.dls_pitch, self.dls_roll = self.meta.dls_pose() self.dls_irradiance = self.meta.dls_irradiance() self.capture_id = self.meta.capture_id() self.flight_id = self.meta.flight_id() self.band_name = self.meta.band_name() self.band_index = self.meta.band_index() self.black_level = self.meta.black_level() self.radiometric_cal = self.meta.radiometric_cal() self.exposure_time = self.meta.exposure() self.gain = self.meta.gain() self.bits_per_pixel = self.meta.bits_per_pixel() self.vignette_center = self.meta.vignette_center() self.vignette_polynomial = self.meta.vignette_polynomial() self.distortion_parameters = self.meta.distortion_parameters() self.principal_point = self.meta.principal_point() self.focal_plane_resolution_px_per_mm = self.meta.focal_plane_resolution_px_per_mm( ) self.focal_length = self.meta.focal_length_mm() self.center_wavelength = self.meta.center_wavelength() self.bandwidth = self.meta.bandwidth() if self.bits_per_pixel != 16: NotImplemented("Unsupported pixel bit depth: {} bits".format( self.bits_per_pixel)) self.__raw_image = None # pure raw pixels self.__intensity_image = None # black level and gain-exposure/radiometric compensated self.__radiance_image = None # calibrated to radiance self.__reflectance_image = None # calibrated to reflectance (0-1) self.__reflectance_irradiance = None self.__undistorted_source = None # can be any of raw, intensity, radiance self.__undistorted_image = None # current undistorted image, depdining on source
def sortImageryByAlt(path, cutoffElev): '''sort imagery into lists of panel images or flight images''' data = {} count = 0 for i in range(100): for typ in ['SET', 'DUP']: iset = '%04i%s' % (i, typ) if os.path.exists(os.path.join(path, iset)): for j in range(100): sub = '%03i' % j if os.path.exists(os.path.join(path, iset, sub)): images = [] panels = [] for img in range(2001): fname = 'IMG_%04i_*.tif' % (img) found = True for band in range(1, 6): imageryPath = os.path.join( path, iset, sub, fname.replace("*", str(band))) if os.path.exists(imageryPath): count += 1 else: found = False print(count, imageryPath, "complete:", found) if found: meta = metadata.Metadata( imageryPath, exiftoolPath=os.environ['exiftoolpath']) if meta.position()[2] > cutoffElev: images.append(fname) else: panels.append(fname) for k in [images, panels]: if k: if iset not in data: data[iset] = {} if sub not in data[iset]: data[iset][sub] = {} if images: data[iset][sub]['images'] = images if panels: data[iset][sub]['panels'] = panels return data
def updateDatabase(filename, bombCoors): filepath = directory + filename img = metadata.Metadata(filepath) lat = img.get_item('Composite:GPSLatitude') lon = img.get_item('Composite:GPSLongitude') yaw, pitch, roll = img.dls_pose() alt = img.get_item('Composite:GPSAltitude') elevation = getElevation(str(lat),str(lon)) image_name = filename.split('.')[0][:-2] + '_stacked.tiff' image_id = newImgId() statement = "INSERT INTO images (image_id, image_name, yaw, pitch, roll, height) VALUES(" + str(image_id) + ", '"+ image_name + "', " + str(yaw) + "," + str(pitch) + "," + str(roll) + "," + str(height) + ")" result = db.query_db (statement, 'EDIT') GPS, bombs = checkingIfBomb(getGPS(img, elevation, lat, lon, alt), bombCoors) updateGps(image_id, GPS, lat, lon) updateBombs(image_id, bombs)
def meta_v3(): image_path = os.path.join('data', '0001SET', '000') return metadata.Metadata(os.path.join(image_path, 'IMG_0002_4.tif'))
def meta(): image_path = os.path.join('data', '0000SET', '000') return metadata.Metadata(os.path.join(image_path, 'IMG_0000_1.tif'))
def __init__(self, image_path, exiftool_obj=None): if not os.path.isfile(image_path): raise IOError("Provided path is not a file: {}".format(image_path)) self.path = image_path self.meta = metadata.Metadata(self.path, exiftool_obj=exiftool_obj) if self.meta.band_name() is None: raise ValueError("Provided file path does not have a band name: {}".format(image_path)) if self.meta.band_name().upper() != 'LWIR' and not self.meta.supports_radiometric_calibration(): raise ValueError('Library requires images taken with RedEdge-(3/M/MX) camera firmware v2.1.0 or later. ' + 'Upgrade your camera firmware to at least version 2.1.0 to use this library with RedEdge-(3/M/MX) cameras.') self.utc_time = self.meta.utc_time() self.latitude, self.longitude, self.altitude = self.meta.position() self.location = (self.latitude, self.longitude, self.altitude) self.dls_present = self.meta.dls_present() self.dls_yaw, self.dls_pitch, self.dls_roll = self.meta.dls_pose() self.capture_id = self.meta.capture_id() self.flight_id = self.meta.flight_id() self.band_name = self.meta.band_name() self.band_index = self.meta.band_index() self.black_level = self.meta.black_level() if self.meta.supports_radiometric_calibration(): self.radiometric_cal = self.meta.radiometric_cal() self.exposure_time = self.meta.exposure() self.gain = self.meta.gain() self.bits_per_pixel = self.meta.bits_per_pixel() self.vignette_center = self.meta.vignette_center() self.vignette_polynomial = self.meta.vignette_polynomial() self.distortion_parameters = self.meta.distortion_parameters() self.principal_point = self.meta.principal_point() self.focal_plane_resolution_px_per_mm = self.meta.focal_plane_resolution_px_per_mm() self.focal_length = self.meta.focal_length_mm() self.focal_length_35 = self.meta.focal_length_35_mm_eq() self.center_wavelength = self.meta.center_wavelength() self.bandwidth = self.meta.bandwidth() self.rig_relatives = self.meta.rig_relatives() self.spectral_irradiance = self.meta.spectral_irradiance() self.auto_calibration_image = self.meta.auto_calibration_image() self.panel_albedo = self.meta.panel_albedo() self.panel_region = self.meta.panel_region() self.panel_serial = self.meta.panel_serial() if self.dls_present: self.dls_orientation_vector = np.array([0, 0, -1]) self.sun_vector_ned, \ self.sensor_vector_ned, \ self.sun_sensor_angle, \ self.solar_elevation, \ self.solar_azimuth = dls.compute_sun_angle(self.location, self.meta.dls_pose(), self.utc_time, self.dls_orientation_vector) self.angular_correction = dls.fresnel(self.sun_sensor_angle) # when we have good horizontal irradiance the camera provides the solar az and el also if self.meta.scattered_irradiance() != 0 and self.meta.direct_irradiance() != 0: self.solar_azimuth = self.meta.solar_azimuth() self.solar_elevation = self.meta.solar_elevation() self.scattered_irradiance = self.meta.scattered_irradiance() self.direct_irradiance = self.meta.direct_irradiance() self.direct_to_diffuse_ratio = self.meta.direct_irradiance() / self.meta.scattered_irradiance() self.estimated_direct_vector = self.meta.estimated_direct_vector() if self.meta.horizontal_irradiance_valid(): self.horizontal_irradiance = self.meta.horizontal_irradiance() else: self.horizontal_irradiance = self.compute_horizontal_irradiance_dls2() else: self.direct_to_diffuse_ratio = 6.0 # assumption self.horizontal_irradiance = self.compute_horizontal_irradiance_dls1() self.spectral_irradiance = self.meta.spectral_irradiance() else: # no dls present or LWIR band: compute what we can, set the rest to 0 self.dls_orientation_vector = np.array([0, 0, -1]) self.sun_vector_ned, \ self.sensor_vector_ned, \ self.sun_sensor_angle, \ self.solar_elevation, \ self.solar_azimuth = dls.compute_sun_angle(self.location, (0, 0, 0), self.utc_time, self.dls_orientation_vector) self.angular_correction = dls.fresnel(self.sun_sensor_angle) self.horizontal_irradiance = 0 self.scattered_irradiance = 0 self.direct_irradiance = 0 self.direct_to_diffuse_ratio = 0 # Internal image containers; these can use a lot of memory, clear with Image.clear_images self.__raw_image = None # pure raw pixels self.__intensity_image = None # black level and gain-exposure/radiometric compensated self.__radiance_image = None # calibrated to radiance self.__reflectance_image = None # calibrated to reflectance (0-1) self.__reflectance_irradiance = None self.__undistorted_source = None # can be any of raw, intensity, radiance self.__undistorted_image = None # current undistorted image, depdining on source
sbr_G = 0 sbr_R = 0 sbr_E = 0 sbr_N = 0 # Num of each band's radiance nbr_B = 0 nbr_G = 0 nbr_R = 0 nbr_E = 0 nbr_N = 0 for im in imageFiles: # Read raw image DN values imageName = filePath + os.sep + "low_altitude" + os.sep + im imageRaw = plt.imread(imageName) print("Processing %s" % imageName) meta = metadata.Metadata(imageName, exiftoolPath=exiftoolPath) bandName = meta.get_item('XMP:BandName') radianceImage, L, V, R = msutils.raw_image_to_radiance(meta, imageRaw) panel_coords = panelDetect(imageName, black_th, cont_th) print('Panel Coords', panel_coords[0][0][0]) # Extract coordinates if panel_coords[0][0][0]: nw_x = int(panel_coords[0][0][0]) nw_y = int(panel_coords[0][0][1]) sw_x = int(panel_coords[1][0][0]) sw_y = int(panel_coords[1][0][1]) se_x = int(panel_coords[2][0][0]) se_y = int(panel_coords[2][0][1]) ne_x = int(panel_coords[3][0][0]) ne_y = int(panel_coords[3][0][1]) x_min = numpy.min([nw_x, sw_x, ne_x, se_x])
def get_band(image): meta = metadata.Metadata(image, exiftoolPath=exiftoolPath) band = meta.get_item('XMP:BandName') return band
#PREFLIGHT CALIBRATION IMAGES ############## #Band 1 (Blue) #Plotting imageName = os.path.join(CalibrationFolder_preflight, 'IMG_0002_1.tif') imageRaw = plt.imread( imageName).T # Read raw image DN values - 16 bit tif only plt.imshow(imageRaw.T, cmap='gray') plotutils.colormap('viridis') # Optional: pick a color map: 'gray, viridis, plasma, inferno, magma, nipy_spectral' fig = plotutils.plotwithcolorbar(imageRaw.T, title='Raw image values with colorbar') #Image metadata meta = metadata.Metadata(imageName, exiftoolPath=exiftoolPath) bandName = meta.get_item('XMP:BandName') #Converting raw images to Radiance radianceImage, L, V, R = msutils.raw_image_to_radiance(meta, imageRaw.T) plotutils.plotwithcolorbar(V, 'Vignette Factor') plotutils.plotwithcolorbar(R, 'Row Gradient Factor') plotutils.plotwithcolorbar(V * R, 'Combined Corrections') plotutils.plotwithcolorbar(L, 'Vignette and row gradient corrected raw values') plotutils.plotwithcolorbar(radianceImage, 'All factors applied and scaled to radiance') #Mask to panel and calculate radiance markedImg = radianceImage.copy() ulx = 510 # upper left column (x coordinate) of panel area uly = 350 # upper left row (y coordinate) of panel area
panelSize = 0 panelSize = panelSizeEval(imageName, black_th) if panelSize > 0: pSizeList.append(panelSize) pSizeArray = numpy.asarray(pSizeList) bn = int((pSizeArray.max() - pSizeArray.min()) / 5) hist, bin_edges = numpy.histogram(pSizeList, bins=bn, density=False) cont_th = bin_edges[numpy.argmax(hist) + 1] print("Panel contour size is close to %s" % (int)(cont_th)) # for im in imageFiles: # Read raw image DN values imageName = filePath + "\\low_altitude\\" + im imageRaw = plt.imread(imageName) print("Processing %s" % imageName) meta = metadata.Metadata(imageName, exiftoolPath=exiftoolPath) bandName = meta.get_item('XMP:BandName') radianceImage, L, V, R = msutils.raw_image_to_radiance(meta, imageRaw) panel_coords = panelDetect(imageName, black_th, (int)(cont_th)) # Extract coordinates if panel_coords[0][0][0]: nw_x = int(panel_coords[0][0][0]) nw_y = int(panel_coords[0][0][1]) sw_x = int(panel_coords[1][0][0]) sw_y = int(panel_coords[1][0][1]) se_x = int(panel_coords[2][0][0]) se_y = int(panel_coords[2][0][1]) ne_x = int(panel_coords[3][0][0]) ne_y = int(panel_coords[3][0][1]) x_min = numpy.min([nw_x, sw_x, ne_x, se_x]) x_max = numpy.max([nw_x, sw_x, ne_x, se_x])
import numpy as np import cv2 import micasense.utils as msutils import micasense.metadata as metadata import exiftool import matplotlib.pyplot as plt import os,glob import math exiftoolPath = None if os.name == 'nt': exiftoolPath = 'C:/exiftool/exiftool.exe' imageRaw = '/mnt/114e4710-77b7-4a37-a8f6-0177deea301b/Desktop/Link to Mine/MicaSense/imageprocessing-master/data/0000SET/000/IMG_0001_3.tif' meta = metadata.Metadata(imageRaw) radianceImage, _,_,_,_ = msutils.raw_image_to_radiance(meta, imageRaw) plotutils.plotwithcolorbar(V,'Vignette Factor') plotutils.plotwithcolorbar(R,'Row Gradient Factor') plotutils.plotwithcolorbar(V*R,'Combined Corrections') plotutils.plotwithcolorbar(L,'Vignette and row gradient corrected raw values') plotutils.plotwithcolorbar(radianceImage,'All factors applied and scaled to radiance')
# Define DLS sensor orientation vector relative to dls pose frame dls_orientation_vector = np.array([0, 0, -1]) # compute sun orientation and sun-sensor angles ( sun_vector_ned, # Solar vector in North-East-Down coordinates sensor_vector_ned, # DLS vector in North-East-Down coordinates sun_sensor_angle, # Angle between DLS vector and sun vector solar_elevation, # Elevation of the sun above the horizon solar_azimuth, # Azimuth (heading) of the sun ) = dls.compute_sun_angle(cap.location(), cap.dls_pose(), cap.utc_time(), dls_orientation_vector) # Get Spectral Irradiance (= Sun Sensor Irradiance) for each image from its metadata spectral_irradiances = [] meta = metadata.Metadata(raw_image, exiftoolPath=None) spectral_irradiances.append(meta.get_item('XMP:Irradiance')) # With Solar elements & Spectral Irradiance # Now we can correct the raw sun sensor irradiance value (DLS) # and compute the irradiance on level ground dls_irradiances = [] fresnel_correction = dls.fresnel(sun_sensor_angle) dir_dif_ratio = 6.0 # Default value from MicaSense percent_diffuse = 1.0 / dir_dif_ratio sensor_irradiance = spectral_irradiances / fresnel_correction untilted_direct_irr = sensor_irradiance / (percent_diffuse + np.cos(sun_sensor_angle))
def meta_bad_exposure(): image_path = os.path.join('data', '0001SET', '000') return metadata.Metadata(os.path.join(image_path, 'IMG_0003_1.tif'))
def meta_altum_dls2(altum_flight_image_name): return metadata.Metadata(altum_flight_image_name)
import micasense.plotutils as plotutils import micasense.utils as msutils import micasense.metadata as metadata sys.path.append('C:/Users/Isaac Miller/Documents/GitHub/imageprocessing') exiftoolPath = None if os.name == 'nt': exiftoolPath = 'C:/exiftool/exiftool.exe' # get calibration panelPath = os.path.join('.', 'data', '0000SET', '000') panelName = glob.glob(os.path.join(panelPath, 'IMG_0000_1.tif'))[0] panelRaw = plt.imread(panelName) panelMeta = metadata.Metadata(panelName, exiftoolPath=exiftoolPath) radianceImage, L, V, R = msutils.raw_image_to_radiance(panelMeta, panelRaw) plotutils.plotwithcolorbar(V, 'Vignette Factor') plotutils.plotwithcolorbar(R, 'Row Gradient Factor') plotutils.plotwithcolorbar(V * R, 'Combined Corrections') plotutils.plotwithcolorbar(L, 'Vignette and row gradient corrected raw values') plotutils.plotwithcolorbar(radianceImage, 'All factors applied and scaled to radiance') markedImg = radianceImage.copy() ulx = 660 # upper left column (x coordinate) of panel area uly = 490 # upper left row (y coordinate) of panel area lrx = 840 # lower right column (x coordinate) of panel area lry = 670 # lower right row (y coordinate) of panel area cv2.rectangle(markedImg, (ulx, uly), (lrx, lry), (0, 255, 0), 3) # Our panel calibration by band (from MicaSense for our specific panel)