TIFF/Multispectral support

Thanks @kikislater! You can send private messages via forum or using https://masseranolabs.com/contact/

This one seems promising: https://forum.developer.parrot.com/t/reflectance-estimation/5597/2

Seems like this might also be a process best performed outside of ODM, as different camera vendors have different procedures for calibrating their images. For example, seems like mapir offers such functionality via https://www.mapir.camera/pages/calibrating-images-in-mapir-camera-control-application

RGB sensor, it’s a git2 pro rebranded mapir. You couldn’t rely on it. True multispectral are monoband not bayer techno …

@kikislater — any favorite proper multispectral sensors?

Not really, they are all crap and certainly not as reliable as satellite data …
RGB ones are definitively not the good one to use. The only fact of why it’s expensive is they invest in spectometer to calibrate sensor.

How do you guys convert the Sequoia drone individual pictures to a geospatial format that can even be read by ODM? We have tried exporting them with the Standard version of Agrisoft but the daa are not georeferenced. Any suggestions?

Those individual photos aren’t geospatial in the typical sense: they are tifs, but they need processed together in a group to create a geotiff that can be used in other geographic software.

My understanding with Sequoia is that you need to fly with 80% or more overlap in order to process, because of the sensor and lens quality (which is poor) (see kikislater’s comments above).

Once the OpenDroneMap multispectral improvements are in place (and not before) you should be able to get geographic products from well planned sequoia flights processed in OpenDroneMap.

1 Like

Hola, ya es posible procesar imágenes de la Cámara Micasense Altum en ODM?

Gracias! Eddison

Amazing work! This is going to really help conservation organizations that struggle to justify the cost of commercial solutions for multispectral rectification.

Is there any possibility of the multispectral Phantom 4 being supported in the distant future?

Good stuff, keep it up!

@RainyRockies — if you can share a dataset from that configuration with @pierotofy, that will help make that happen (if not now, then eventually). Test datasets are needed for each case, as the formats are extremely variable.

Hi!! Are they going to perform tests with Micasense Altum?

Eddison

Only if datasets are shared. :slight_smile:

Will do! I can get access to a data-set within the coming weeks. Thanks for the info!

1 Like

ok there is a small set of Micasense Altum, there the images are the radiometric calibration panel. You have only 3 days to download.

Thank you

Eddison

I have a camera with a Sigma Foveon sensor with an easily removable IR filter and black and white mode. With it’s stacked pixels, I wonder if it would make a good sensor (recognizing the speed is a challenge).

Do you know where there are good resources for walking through the calibration process?

I know Foveon sensor :wink: But I don’t know if it’s good or know for additionnal filter.
They looks like that (for others who read this forum) :


So it’s stacked as you mentioned. Better multispectral / hyperspectral sensors have mono band sensors

To calibrate you need a Spectrometer.

RGB and NIR cameras:an empirical-line calibration was used for the reflectance factor estimation of both consumer RGB and infrared-modified cameras. Although cor-relations between the digital cameras and the high resolution spectrometers exist they must be treated with caution. This is due to the unknown radiometric response of the cameras and the inherent differences between simple digital cameras and numericalsensors.

In fact, it all depends on what you will do with your sensor. My concern was to use satellite data. Finding a corresponding sensor is pretty difficult : same value same day at same hour. If you intend to use RGB sensor, let’s take the cheaper / lighter and do it. I could mention what it’s used in Sequoia, Red edge sensor etc : mt9m021

Yes, a mono band sensor would be better for sure. (Thanks for including the figure for clarity for others!) The reality with the stacked sensor, as I understand it, is that the response functions for the different layers of silica mean that there really isn’t a red, green, and blue layer, per se, as silicon penetration depth is the filtering process, but one can think of the 3 layers in a Foveon as related to those colors, with a complicated and computationally intensive process to transform that info into color space that we understand.

Side note: this complicated process of deconvolution (?) of the data is the reason why foveon chips tend to be slow in post-processing and noise prone at higher ISO levels. In some ways they have the opposite problems introduced by the convolution / interpolation that is used to resolve samping in Bayer style sensors.

So all that to say, when you switch a Foveon chip to grayscale mode, it is producing a single integrated brightness value per pixel which strikes me as conveniently similar to mono-band sensors.

I found a bug. When running this command:
docker run -it --rm -v "$(pwd)/images:/code/images" -v "$(pwd)/odm_georeferencing:/code/odm_georeferencing" -v "$(pwd)/odm_meshing:/code/odm_meshing" -v "$(pwd)/odm_orthophoto:/code/odm_orthophoto" -v "$(pwd)/odm_texturing:/code/odm_texturing" -v "$(pwd)/opensfm:/code/opensfm" -v "$(pwd)/mve:/code/mve" multispec
on a set of all JPG images I get the following error:

[INFO] running /usr/bin/env python2 /code/SuperBuild/src/opensfm/bin/opensfm extract_metadata "/code/opensfm" 2020-01-28 17:23:51,768 INFO: Extracting EXIF for IMG_190227_221550_0239_RGB.JPG Traceback (most recent call last): File "/code/SuperBuild/src/opensfm/bin/opensfm", line 34, in <module> command.run(args) File "/code/SuperBuild/src/opensfm/opensfm/commands/extract_metadata.py", line 35, in run d = self._extract_exif(image, data) File "/code/SuperBuild/src/opensfm/opensfm/commands/extract_metadata.py", line 64, in _extract_exif d = exif.extract_exif_from_file(data.open_image_file(image)) File "/code/SuperBuild/src/opensfm/opensfm/exif.py", line 98, in extract_exif_from_file d = exif_data.extract_exif() File "/code/SuperBuild/src/opensfm/opensfm/exif.py", line 361, in extract_exif band_name = self.extract_band_name() File "/code/SuperBuild/src/opensfm/opensfm/exif.py", line 351, in extract_band_name return band_name.replace(" ", "") AttributeError: 'list' object has no attribute 'replace' Traceback (most recent call last): File "/code/run.py", line 57, in <module> app.execute() File "/code/stages/odm_app.py", line 92, in execute self.first_stage.run() File "/code/opendm/types.py", line 447, in run self.next_stage.run(outputs) File "/code/opendm/types.py", line 447, in run self.next_stage.run(outputs) File "/code/opendm/types.py", line 447, in run self.next_stage.run(outputs) File "/code/opendm/types.py", line 428, in run self.process(self.args, outputs) File "/code/stages/run_opensfm.py", line 25, in process octx.extract_metadata(self.rerun()) File "/code/opendm/osfm.py", line 179, in extract_metadata self.run('extract_metadata') File "/code/opendm/osfm.py", line 22, in run (context.opensfm_path, command, self.opensfm_project_path)) File "/code/opendm/system.py", line 76, in run raise Exception("Child returned {}".format(retcode)) Exception: Child returned 1

When running the same command on a mix of JPGS and TIFs I get this error:
[INFO] ['use_exif_size: no', 'feature_process_size: 2048', 'feature_min_frames: 8000', 'processes: 10', 'matching_gps_neighbors: 40', 'matching_gps_distance: 0', 'depthmap_method: PATCH_MATCH', 'depthmap_resolution: 640', 'depthmap_min_patch_sd: 1', 'depthmap_min_consistent_views: 3', 'optimize_camera_parameters: yes', 'undistorted_image_format: tif', 'bundle_outlier_filtering_type: AUTO', 'align_orientation_prior: vertical', 'matcher_type: WORDS', 'align_method: orientation_prior', 'local_bundle_radius: 0'] [INFO] running /usr/bin/env python2 /code/SuperBuild/src/opensfm/bin/opensfm extract_metadata "/code/opensfm" 2020-01-28 18:04:07,504 INFO: Extracting EXIF for IMG_190227_221556_0242_GRE.TIF 2020-01-28 18:04:07,514 INFO: Extracting EXIF for IMG_190227_221350_0179_GRE.TIF 2020-01-28 18:04:07,519 INFO: Extracting EXIF for IMG_190227_221752_0300_NIR.TIF 2020-01-28 18:04:07,526 INFO: Extracting EXIF for IMG_190227_221746_0297_RED.TIF 2020-01-28 18:04:07,531 INFO: Extracting EXIF for IMG_190227_221104_0096_REG.TIF 2020-01-28 18:04:07,535 INFO: Extracting EXIF for IMG_190227_221550_0239_RGB.JPG Traceback (most recent call last): File "/code/SuperBuild/src/opensfm/bin/opensfm", line 34, in <module> command.run(args) File "/code/SuperBuild/src/opensfm/opensfm/commands/extract_metadata.py", line 35, in run d = self._extract_exif(image, data) File "/code/SuperBuild/src/opensfm/opensfm/commands/extract_metadata.py", line 64, in _extract_exif d = exif.extract_exif_from_file(data.open_image_file(image)) File "/code/SuperBuild/src/opensfm/opensfm/exif.py", line 98, in extract_exif_from_file d = exif_data.extract_exif() File "/code/SuperBuild/src/opensfm/opensfm/exif.py", line 361, in extract_exif band_name = self.extract_band_name() File "/code/SuperBuild/src/opensfm/opensfm/exif.py", line 351, in extract_band_name return band_name.replace(" ", "") AttributeError: 'list' object has no attribute 'replace' Traceback (most recent call last): File "/code/run.py", line 57, in <module> app.execute() File "/code/stages/odm_app.py", line 92, in execute self.first_stage.run() File "/code/opendm/types.py", line 447, in run self.next_stage.run(outputs) File "/code/opendm/types.py", line 447, in run self.next_stage.run(outputs) File "/code/opendm/types.py", line 447, in run self.next_stage.run(outputs) File "/code/opendm/types.py", line 428, in run self.process(self.args, outputs) File "/code/stages/run_opensfm.py", line 25, in process octx.extract_metadata(self.rerun()) File "/code/opendm/osfm.py", line 179, in extract_metadata self.run('extract_metadata') File "/code/opendm/osfm.py", line 22, in run (context.opensfm_path, command, self.opensfm_project_path)) File "/code/opendm/system.py", line 76, in run raise Exception("Child returned {}".format(retcode)) Exception: Child returned 1

1 Like

@DroneDragon can you share a small subset of the images?