micasense / imageprocessing

MicaSense RedEdge and Altum image processing tutorials
https://www.micasense.com
MIT License
253 stars 151 forks source link

stacked geotiffs: Adding Filename to a nested list, aligning #109

Open swawa opened 4 years ago

swawa commented 4 years ago

Hi Poynting, few questions: (I am using an Altum, firmware version 1.3.6)

The challenge might be that the new tif does not contain the band name. But that would not be so important. The stacked image can also be named like "IMG_0023_0.tif". I tried it with the exiff-data but wasn't successful.

Healthy regards, Swawa

poynting commented 4 years ago

With respect to the capture ID as the filename. It's a little disorienting, I know, but I use this script regularly to process multiple flights worth of data where there are multiple sets of data with the same filenames and UUID ensures there are no name collisions while still putting all the stacks

a) Yeah, you'll need to the capture.image[0].path to the list. You want the full path though, due to the same reason as above. I had this in one version of the code but I don't think I ever committed it.

b) You need to run alignment first, then copy-paste the warp_matrices to the batch processing code. If you want to skip this step you can set warp_matrices to None and I believe it will just use the rig relatives, but the alignment won't be as good. https://micasense.github.io/imageprocessing/Batch%20Processing.html#Define-which-warp-method-to-use

c) The Batch processing notebook, when run to completion, results in a set of gps-tagged tiff files which are cropped. I then load them into Agisoft or Pix4D to create geotiffs.

swawa commented 4 years ago

..With respect to the capture ID as the filename... yes. I agree. The complete idea is creating a file name like IMG_0023_UUID. So I just need to attach the filename to the UUID rename. I will try to modify my output today with your proposal for solution in a)

Thanks a lot so far.

swawa commented 4 years ago

I added to my main script filename = capture.image[0].path, df = pd.DataFrame.from_records(filename, data, index='timestamp', columns=columns)

But the response is TypeError: 'module' object is not subscriptable Did I missunderstood the position to call and add the filename to the list? Or do I have to add this line to the imageset.py script?

swawa commented 4 years ago

Hi, maybe there is an alignment bug..? in the alignment tutorial are the code lines:

[...]

Alignment settings

match_index = 1 # Index of the band max_alignment_iterations = 10 warp_mode = cv2.HOMOGRAPHY # MOTION_HOMOGRAPHY or MOTION_AFFINE. For # Altum images only use HOMOGRAPHY [...]

Last line says, that I have to use only HOMOGRAPHY for Altum but python tells: AttributeError: module 'cv2' has no attribute 'HOMOGRAPHY'

So what to use for Altum images?

poynting commented 4 years ago

cv2.MOTION_HOMOGRAPHY

The example uses this setting to process altum images.

https://micasense.github.io/imageprocessing/Alignment.html

On Mon, Apr 27, 2020, 4:18 AM swawa notifications@github.com wrote:

Hi, maybe there is an alignment bug..? in the alignment tutorial are the code lines:

[...] Alignment settings

match_index = 1 # Index of the band max_alignment_iterations = 10 warp_mode = cv2.HOMOGRAPHY # MOTION_HOMOGRAPHY or MOTION_AFFINE. For # Altum images only use HOMOGRAPHY [...]

Last line says, that I have to use only HOMOGRAPHY for Altum but python tells: AttributeError: module 'cv2' has no attribute 'HOMOGRAPHY'

So what to use for Altum images?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/micasense/imageprocessing/issues/109#issuecomment-619916049, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSNZU4FAO2UCNUM4O5CBRDROVSXNANCNFSM4MIRJBLQ .

swawa commented 4 years ago

ok, thanks. This was a missunderstanding. cv2 does not even provide just "HOMOGRAPHY"... I could have known...

The problem of adding the file names to the UUID renaming process persists: I added to my main script your proposal and the part out of the ImageSets-tutorial:

filename = capture.image[0].path, df = pd.DataFrame.from_records(filename, data, index='timestamp', columns=columns)

But the response is TypeError: 'module' object is not subscriptable Did I missunderstood the position to call and add the filename to the list? Or do I have to add this line to the imageset.py script?

swawa commented 4 years ago

just found that it must be capture.images[0].path instead of capture.image[0].path to get the file name ... at least it once worked.... but does not work anymore must be still the wrong place to call it

poynting commented 4 years ago

Image.path is defined in the Image object at https://github.com/micasense/imageprocessing/blob/master/micasense/image.py#L68

Capture.images is a list of Image objects within a capture.

So if you have a Capture object called cap you should be able to call

cap.images[0].path

to get the fully resolved path of the first image file backing that Image object.

Bartoszko commented 3 years ago

For me, this solution does not work. I get the message:

AttributeError Traceback (most recent call last)

in 74 75 data, columns = imgset.as_nested_lists() ---> 76 filename = capture.images[0].path 77 df = pd.DataFrame.from_records(filename, data, index='timestamp', columns=columns) 78 AttributeError: module 'micasense.capture' has no attribute 'images' also the above-mentioned solutions too. Justin do you have any other suggestions to solve this ORIGINAL-FILE NAMES problem?
Bartoszko commented 3 years ago

It is important for my, and i suppose others user's, because with original names we have opportunity to use for example PPK/RTK data in external application. Of course after processing whit micasen imageprocessing libary we can use spatial join function but it can do some unnesesary distorsions in processing of remotesensing data and add exta work. It's much easier to keep the original filenames, although using UUID is a great idea.

Bartoszko commented 3 years ago

I forgot to mention that I am editing a script that is posted on the site

https://micasense.github.io/imageprocessing/Batch%20Processing.html

MarioCruz22 commented 1 year ago

@Bartoszko Having the same error here… "AttributeError: module 'micasense.capture' has no attribute 'images'" Found some fix?

swawa commented 1 year ago

Sorry, we don't use the camera anymore as the picture results were not computable for us regarding our needs.

poynting commented 1 year ago

@Bartoszko filenames should not be necessary to align PPK/RTK data. The images have timestamps, which are in order of time even if the camera didn't have GPS data, and should be very close to the PPK timestamps if the camera had GPS data and a PPS pulse (which would always be the case if using DLS2). If there is ever a need to process multiple flights of data together it is best not to use filenames.

The only thing I used filenames for was to look up a specific capture to open the file if I needed to look at the image.

In any case I suspect in the code error above the error message is pointing to the problem: when writing capture.images[0].path in your code, "capture" is being interpreted as the module micasense.capture not the capture object you are trying to reference.

Note that I don't work at MicaSense any more since March, and I don't have commit privileges to this repository or access to any data other than what's here already, so it's pretty unlikely I'll be able to help much.

This code adds filename as a property in the list (replace at https://github.com/micasense/imageprocessing/blob/master/micasense/imageset.py#L189). Works for me, YMMV, best of luck!

    def as_nested_lists(self):
        columns = [
            'timestamp',
            'latitude','longitude','altitude',
            'capture_id',
            'dls-yaw','dls-pitch','dls-roll','filename'
        ]
        irr = ["irr-{}".format(wve) for wve in self.captures[0].center_wavelengths()]
        columns += irr
        data = [] 
        for cap in self.captures:
            dat = cap.utc_time()
            loc = list(cap.location())
            uuid = cap.uuid
            dls_pose = list(cap.dls_pose())
            irr = cap.dls_irradiance()
            filename = cap.images[0].path
            row = [dat]+loc+[uuid]+dls_pose+[filename]+irr
            data.append(row)
        return data, columns

image

MarioCruz22 commented 1 year ago

I was trying to get the alignment script running but it ends up that it doesnt support RedEdge P.. wich is the model i am working with.. Are there some version of RedEdge P i can safely allow to continue the horizontal irradiance valid "test" described in the image? For now I´m allowing any version of RedEdge-P.. image