store a user-defined RGB vegetation index in the intensity field

138 views
Skip to first unread message

Guillermo Castilla

unread,
Jan 15, 2021, 11:22:08 AM1/15/21
to LAStools - efficient tools for LiDAR processing
Hi Martin (happy New Year!),

This follows from a question I  asked a few months ago about  creating a raster with the proportion of 'green' points in each cell (https://groups.google.com/g/lastools/c/rXB9WlyQkEw/m/uAzBPx7cBwAJ). 

So I have a drone-based image point cloud in las 1.2  format where the intensity field is empty, and I want to populate it with a vegetation index of my choice (e.g.,  intensity = 100*G/(R+G+B+1); but could be other combination).

Is it possible to do this with lastools, and if so how?

Thanks!

Guillermo

Alessandro Montaghi

unread,
Jan 15, 2021, 12:45:09 PM1/15/21
to last...@googlegroups.com
Hey Guillermo Castilla,

If you wish you can do it easily with Python+LibLAS (it's very slow compared with LAStools). Open the file, read the file inside a for and change point-by-point the intensity value.

https://liblas.org/tutorial/python.html

Cheers,
Alessandro

--
Download LAStools at
http://lastools.org
http://rapidlasso.com
Be social with LAStools at
http://facebook.com/LAStools
http://twitter.com/LAStools
http://linkedin.com/groups/LAStools-4408378
Manage your settings at
http://groups.google.com/group/lastools/subscribe
---
You received this message because you are subscribed to the Google Groups "LAStools - efficient tools for LiDAR processing" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lastools+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lastools/1d253474-fc48-4acd-9326-bcdcc76dce1dn%40googlegroups.com.

Martin Isenburg

unread,
Jan 15, 2021, 12:45:15 PM1/15/21
to LAStools - efficient command line tools for LIDAR processing
Hello,

yes. That is possible with the LASregister functionality but please use this latest version:

https://www.dropbox.com/s/ere9wpz87rkirmx/las2las.exe

It should work as follows:

las2las -i TEST_1_col.laz ^
-copy_G_into_register 0 ^
-scale_register 0 100.0 ^
-copy_R_into_register 1 ^
-copy_G_into_register 2 ^
-add_registers 1 2 1 ^
-copy_B_into_register 2 ^
-add_registers 1 2 1 ^
-translate_register 1 1.0 ^
-divide_registers 0 1 2 ^
-copy_register_into_intensity 2 ^
-odix _mist -olaz

For my test case that gave this intensity histogram:

intensity histogram with bin size 1.000000
  bin 30 has 1
  bin 31 has 33
  bin 32 has 994
  bin 33 has 280757
  bin 34 has 8478973
  bin 35 has 111787
  bin 36 has 3291
  bin 37 has 126
  average intensity 33.981511750500957 for 8875962 element(s)

And that looks okay for this intensity modifiction:

lasview -i TEST_1_col_mist.laz -translate_intensity -30 -scale_intensity 30

image.png

Regards,

Martin

--

Guillermo Castilla

unread,
Jan 17, 2021, 7:32:27 PM1/17/21
to LAStools - efficient tools for LiDAR processing
Thanks so much Martin, that is neat and will work for my purposes (grazie anche a te Alessandro, ti ho risposto da email),

I tried to find more info on the usage of the new (June 2020?) 'register' functionality in las2las, and saw you posted some examples here:

From those examples, I gather the registers are a set of internal variables that temporarily store (in the RAM memory?) the content of some specified fields in the las file. These variables can in turn be altered  (e.g., multiplied by, or added to, a scalar using '-scale_register', or ' -translate_register' respectively). Registers can also be added, multiplied, or divided to each other in pairs. Did I get this right?

I have an additional question: the line "-translate_register 1 1.0" above adds 1.0 to register 1, which at that point was containing the sum of the R, G and B fields . Does 'translate' also change the data type from 16 bit integer (the native type of the RGB fields) to 32 bit floating (assuming '1.0' is interpreted as a single precision float)? If so, shouldn't the RGB fields be converted to floating point before they are added (some points could have a value of 65535 in one of the colors, and the result from the integer sum would be wrong)? That will probably more than double the memory usage, but wouldn't it be safer?

Thanks again

Guillermo

Martin Isenburg

unread,
Jan 18, 2021, 6:44:50 AM1/18/21
to LAStools - efficient command line tools for LIDAR processing
Hello,

yes. LASregsters give you 16 registers that are available *on read* and *per point* to copy point attributes into and then apply various arithmetic operations on them and then copy them back into a point attribute. All values are copied from their native unit8, uint16, ... data type to double-precision floating point. The registers are double-precision floating point and all operations that place with that precision. A standard rounding and clamping takes place when copying back to the LAS point field. You need to make sure your arithmetic does not leave the range (too much).

https://github.com/LAStools/LAStools/blob/master/LASlib/inc/lastransform.hpp#L79

Regards,

Martin

Gregor Schmucki

unread,
Mar 9, 2021, 9:59:54 AM3/9/21
to LAStools - efficient tools for LiDAR processing
Hi,

I would like to implement something similar.
I want to implement the following vegetation index: 2*G - R - B

Now I have a view questions:
- Is there a possibility to do substractions from one register to another? For the first try I made a workaround with -scale_register 1 -1. Which I understand means multiply register 1 with -1, right?
- In the end I will bring all three registers together into one. How can I do that? I did not yet understand what the three numbers for add_registers 1 2 1 stand for. Does that mean add register 1 to the register 2 and save it in register 1?
- In the end I can save one register as intensity, which I can use for further calculations, right?

Many thanks for your help.
I'm looking forward hearing from you.
All the best,
Gregor

Martin Isenburg

unread,
Mar 9, 2021, 3:43:31 PM3/9/21
to LAStools - efficient command line tools for LIDAR processing
Hello,

here an example. First let's make some fake colored LAZ point cloud:

lasgrid ^
-i ..\data\zurich.laz ^
-density -step 0.5 ^
-false -set_min_max 20 100 ^
-odix _density -opng

lascolor ^
-i ..\data\zurich.laz ^
-image ..\data\zurich_density.png ^
-odix _col -olaz

lasview -i ..\data\zurich_col.laz -color_by_rgb

Now let's do some register math:

las2las ^
-i ..\data\zurich_col.laz ^
-copy_G_into_register 0 ^
-scale_register 0 2.0 ^
-copy_R_into_register 1 ^
-subtract_registers 0 1 0 ^
-copy_B_into_register 1 ^
-subtract_registers 0 1 0 ^
-copy_register_into_intensity 0 ^
-odix _mist -olaz

lasview -i ..\data\zurich_col.laz -color_by_intensity  

I have not verified whether the math works out correctly, but unless there is a bug this should do it. Also careful with overflow handling.

Martin

Gregor Schmucki

unread,
Mar 10, 2021, 3:16:41 PM3/10/21
to LAStools - efficient tools for LiDAR processing
Hello Martin,

Many thanks for your help!
I tested it out and it worked out nicely.
Unfortunately it did not work out for the 64 Run.

Is it possible that there is a bug?

Many thanks and all the best,
Gregor

PS:  Is it correct that the three number 0 1 0 mean  add register 0 to the register 1 and save it in register 0?

Martin Isenburg

unread,
Mar 21, 2021, 11:24:30 PM3/21/21
to LAStools - efficient command line tools for LIDAR processing
Hello,

Unfortunately it did not work out for the 64 Run.
Is it possible that there is a bug?

I do not know exactly what you mean here. You are saying that the 64 bit executables are behaving differently? For a bug report I need repeatable command lines plus test data.
 
PS:  Is it correct that the three number 0 1 0 mean  add register 0 to the register 1 and save it in register 0?

-add_registers 0 1 0  
-subtract_registers 0 1 0 
 
means add/subtract 1 to/from 0 and store the result to 0. here are the code fragments:

https://github.com/LAStools/LAStools/blob/master/LASlib/src/lastransform.cpp#L802

class LASoperationAddRegisters : public LASoperation
{
public:
  inline const CHAR* name() const { return "add_registers"; };
  inline I32 get_command(CHAR* string) const { return sprintf(string, "-%s %u %u %u ", name(), input1, input2, output); };
  inline void transform(LASpoint* point) {
    F64 result = registers[input1] + registers[input2];  
    registers[output] = result;
  };
  LASoperationAddRegisters(F64* registers, U32 input1, U32 input2, U32 output) { this->registers = registers; this->input1 = input1; this->input2 = input2; this->output = output; };
private:
  F64* registers;
  U32 input1;
  U32 input2;
  U32 output;
};

class LASoperationSubtractRegisters : public LASoperation
{
public:
  inline const CHAR* name() const { return "subtract_registers"; };
  inline I32 get_command(CHAR* string) const { return sprintf(string, "-%s %u %u %u ", name(), input1, input2, output); };
  inline void transform(LASpoint* point) {
    F64 result = registers[input1] - registers[input2];  
    registers[output] = result;
  };
  LASoperationSubtractRegisters(F64* registers, U32 input1, U32 input2, U32 output) { this->registers = registers; this->input1 = input1; this->input2 = input2; this->output = output; };
private:
  F64* registers;
  U32 input1;
  U32 input2;
  U32 output;
};


Gregor Schmucki

unread,
Mar 25, 2021, 8:53:50 AM3/25/21
to LAStools - efficient tools for LiDAR processing
Dear Martin,

Many thanks for your answer and explanation to the register functionality.
I'm now using a python script and there the las2las64 is running smoothly. 
When I first try to run the 64 version, I pressed the run64 button in the 32-Bit GUI.
May this just doesn't work?

I hope you understand now what did not work out... 

Many thanks and all the best,
Gregor
las2las_error.PNG
Reply all
Reply to author
Forward
0 new messages