kopia lustrzana https://github.com/OpenDroneMap/ODM
				
				
				
			
							rodzic
							
								
									a61b5b308a
								
							
						
					
					
						commit
						309c7751b3
					
				|  | @ -65,8 +65,6 @@ def dn_to_radiance(photo, image): | ||||||
|         R = 1.0 / (1.0 + a2 * y / exposure_time - a3 * y) |         R = 1.0 / (1.0 + a2 * y / exposure_time - a3 * y) | ||||||
|         image *= R |         image *= R | ||||||
| 
 | 
 | ||||||
|         cv2.imwrite("/datasets/mica/R.tif", R) |  | ||||||
| 
 |  | ||||||
|         print("Row gradient") |         print("Row gradient") | ||||||
|      |      | ||||||
|     # Floor any negative radiances to zero (can happend due to noise around blackLevel) |     # Floor any negative radiances to zero (can happend due to noise around blackLevel) | ||||||
|  | @ -114,19 +112,28 @@ def vignette_map(photo): | ||||||
| 
 | 
 | ||||||
| def dn_to_reflectance(photo, image, use_sun_sensor=True): | def dn_to_reflectance(photo, image, use_sun_sensor=True): | ||||||
|     radiance = dn_to_radiance(photo, image) |     radiance = dn_to_radiance(photo, image) | ||||||
|     irradiance_scale = compute_irradiance_scale_factor(photo, use_sun_sensor=use_sun_sensor) |  | ||||||
|     return radiance * irradiance_scale |  | ||||||
| 
 | 
 | ||||||
| def compute_irradiance_scale_factor(photo, use_sun_sensor=True): |     # TODO REMOVE | ||||||
|  |     cv2.imwrite("/datasets/sentera-6x/radiance.tif", radiance) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     irradiance = compute_irradiance(photo, use_sun_sensor=use_sun_sensor) | ||||||
|  |     print(irradiance) | ||||||
|  |     return radiance * math.pi / irradiance | ||||||
|  | 
 | ||||||
|  | def compute_irradiance(photo, use_sun_sensor=True): | ||||||
|     # Thermal? |     # Thermal? | ||||||
|     if photo.band_name == "LWIR": |     if photo.band_name == "LWIR": | ||||||
|         return 1.0 |         return 1.0 | ||||||
| 
 | 
 | ||||||
|     if photo.irradiance is not None: |     # Some cameras (Micasense) store the value (nice! just return) | ||||||
|         horizontal_irradiance = photo.irradiance |     hirradiance = photo.get_horizontal_irradiance() | ||||||
|         return math.pi / horizontal_irradiance |     if hirradiance is not None: | ||||||
|      |         return hirradiance | ||||||
|     if use_sun_sensor: | 
 | ||||||
|  |     # TODO: support for calibration panels | ||||||
|  | 
 | ||||||
|  |     if use_sun_sensor and photo.sun_sensor: | ||||||
|         # Estimate it |         # Estimate it | ||||||
|         dls_orientation_vector = np.array([0,0,-1]) |         dls_orientation_vector = np.array([0,0,-1]) | ||||||
|         sun_vector_ned, sensor_vector_ned, sun_sensor_angle, \ |         sun_vector_ned, sensor_vector_ned, sun_sensor_angle, \ | ||||||
|  | @ -137,21 +144,25 @@ def compute_irradiance_scale_factor(photo, use_sun_sensor=True): | ||||||
| 
 | 
 | ||||||
|         angular_correction = dls.fresnel(sun_sensor_angle) |         angular_correction = dls.fresnel(sun_sensor_angle) | ||||||
| 
 | 
 | ||||||
|  |         print("Sun sensor") | ||||||
|  | 
 | ||||||
|         # TODO: support for direct and scattered irradiance |         # TODO: support for direct and scattered irradiance | ||||||
| 
 | 
 | ||||||
|         direct_to_diffuse_ratio = 6.0 # Assumption |         direct_to_diffuse_ratio = 6.0 # Assumption | ||||||
|         spectral_irradiance = photo.sun_sensor # TODO: support for XMP:SpectralIrradiance |         spectral_irradiance = photo.sun_sensor | ||||||
| 
 | 
 | ||||||
|         percent_diffuse = 1.0 / direct_to_diffuse_ratio |         percent_diffuse = 1.0 / direct_to_diffuse_ratio | ||||||
|         sensor_irradiance = spectral_irradiance / angular_correction |         sensor_irradiance = spectral_irradiance / angular_correction | ||||||
| 
 | 
 | ||||||
|         # find direct irradiance in the plane normal to the sun |         # Find direct irradiance in the plane normal to the sun | ||||||
|         untilted_direct_irr = sensor_irradiance / (percent_diffuse + np.cos(sun_sensor_angle)) |         untilted_direct_irr = sensor_irradiance / (percent_diffuse + np.cos(sun_sensor_angle)) | ||||||
|         direct_irradiance = untilted_direct_irr |         direct_irradiance = untilted_direct_irr | ||||||
|         scattered_irradiance = untilted_direct_irr*percent_diffuse |         scattered_irradiance = untilted_direct_irr * percent_diffuse | ||||||
| 
 | 
 | ||||||
|         # compute irradiance on the ground using the solar altitude angle |         # compute irradiance on the ground using the solar altitude angle | ||||||
|         horizontal_irradiance = direct_irradiance * np.sin(solar_elevation) + scattered_irradiance |         horizontal_irradiance = direct_irradiance * np.sin(solar_elevation) + scattered_irradiance | ||||||
|         return math.pi / horizontal_irradiance |         return horizontal_irradiance | ||||||
|  |     elif use_sun_sensor: | ||||||
|  |         log.ODM_WARNING("No sun sensor values found for %s" % photo.filename) | ||||||
|      |      | ||||||
|     return 1.0 |     return 1.0 | ||||||
|  | @ -46,7 +46,9 @@ class ODM_Photo: | ||||||
|         self.bits_per_sample = None |         self.bits_per_sample = None | ||||||
|         self.vignetting_center = None |         self.vignetting_center = None | ||||||
|         self.vignetting_polynomial = None |         self.vignetting_polynomial = None | ||||||
|         self.irradiance = None |         # self.irradiance = None | ||||||
|  |         self.horizontal_irradiance = None | ||||||
|  |         self.irradiance_scale_to_si = None | ||||||
|         self.sun_sensor = None |         self.sun_sensor = None | ||||||
|         self.utc_time = None |         self.utc_time = None | ||||||
| 
 | 
 | ||||||
|  | @ -155,12 +157,17 @@ class ODM_Photo: | ||||||
|                     'Sentera:VignettingPolynomial', |                     'Sentera:VignettingPolynomial', | ||||||
|                 ]) |                 ]) | ||||||
|                  |                  | ||||||
|                 self.set_attr_from_xmp_tag('irradiance', tags, [ |                 self.set_attr_from_xmp_tag('horizontal_irradiance', tags, [ | ||||||
|                     'Camera:Irradiance' |                     'Camera:HorizontalIrradiance' | ||||||
|  |                 ], float) | ||||||
|  | 
 | ||||||
|  |                 self.set_attr_from_xmp_tag('irradiance_scale_to_si', tags, [ | ||||||
|  |                     'Camera:IrradianceScaleToSIUnits' | ||||||
|                 ], float) |                 ], float) | ||||||
| 
 | 
 | ||||||
|                 self.set_attr_from_xmp_tag('sun_sensor', tags, [ |                 self.set_attr_from_xmp_tag('sun_sensor', tags, [ | ||||||
|                     'Camera:SunSensor' |                     'Camera:SunSensor', | ||||||
|  |                     'Camera:Irradiance', | ||||||
|                 ], float) |                 ], float) | ||||||
| 
 | 
 | ||||||
|                 # self.set_attr_from_xmp_tag('center_wavelength', tags, [ |                 # self.set_attr_from_xmp_tag('center_wavelength', tags, [ | ||||||
|  | @ -181,7 +188,7 @@ class ODM_Photo: | ||||||
|             # print(self.vignetting_center) |             # print(self.vignetting_center) | ||||||
|             # print(self.sun_sensor) |             # print(self.sun_sensor) | ||||||
|             #print(self.get_vignetting_polynomial()) |             #print(self.get_vignetting_polynomial()) | ||||||
|             #exit(1) |             # exit(1) | ||||||
|         self.width, self.height = get_image_size.get_image_size(_path_file) |         self.width, self.height = get_image_size.get_image_size(_path_file) | ||||||
|          |          | ||||||
|         # Sanitize band name since we use it in folder paths |         # Sanitize band name since we use it in folder paths | ||||||
|  | @ -312,4 +319,12 @@ class ODM_Photo: | ||||||
|     def get_photometric_exposure(self): |     def get_photometric_exposure(self): | ||||||
|         # H ~= (exposure_time) / (f_number^2) |         # H ~= (exposure_time) / (f_number^2) | ||||||
|         if self.fnumber is not None and self.exposure_time > 0: |         if self.fnumber is not None and self.exposure_time > 0: | ||||||
|             return self.exposure_time / (self.fnumber * self.fnumber) |             return self.exposure_time / (self.fnumber * self.fnumber) | ||||||
|  | 
 | ||||||
|  |     def get_horizontal_irradiance(self): | ||||||
|  |         if self.horizontal_irradiance is not None: | ||||||
|  |             scale = 1.0 # Assumed | ||||||
|  |             if self.irradiance_scale_to_si is not None: | ||||||
|  |                 scale = self.irradiance_scale_to_si | ||||||
|  |              | ||||||
|  |             return self.horizontal_irradiance * scale | ||||||
|  |  | ||||||
|  | @ -61,6 +61,9 @@ class ODMOpenSfMStage(types.ODM_Stage): | ||||||
|         if args.radiometric_calibration == "none": |         if args.radiometric_calibration == "none": | ||||||
|             octx.convert_and_undistort(self.rerun()) |             octx.convert_and_undistort(self.rerun()) | ||||||
|         else: |         else: | ||||||
|  | 
 | ||||||
|  |             # TODO: does this work for multi-band RGB images? | ||||||
|  |              | ||||||
|             def radiometric_calibrate(shot_id, image): |             def radiometric_calibrate(shot_id, image): | ||||||
|                 photo = reconstruction.get_photo(shot_id) |                 photo = reconstruction.get_photo(shot_id) | ||||||
|                 return multispectral.dn_to_reflectance(photo, image, use_sun_sensor=args.radiometric_calibration=="camera+sun") |                 return multispectral.dn_to_reflectance(photo, image, use_sun_sensor=args.radiometric_calibration=="camera+sun") | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Piero Toffanin
						Piero Toffanin