LiDAR Data – Adding NIR Information to ALS Point Cloud

lidrrgb

I need to merge Red-Green-Blue_NearInfrared (RGBI) information to pointclouds and I am doint it in R with the package lidR version 4.0.2.

I made this small example case to show my error and questions:

# Read las
LASfile <- system.file("extdata", "Megaplot.laz", package="lidR")
las = readLAS(LASfile)

# Generate dataframe with random RGBI values
rgbi=data.frame(Red=  as.integer(sample(seq(from=0,to=100,by=5),size=nrow(las@data),replace=TRUE)),
                Green=  as.integer(sample(seq(from=0,to=100,by=5),size=nrow(las@data),replace=TRUE)),
                Blue=  as.integer(sample(seq(from=0,to=100,by=5),size=nrow(las@data),replace=TRUE)),
                IR=as.integer(sample(seq(from=0,to=100,by=5),size=nrow(las@data),replace=TRUE)))

# First add rgb values with the existing command 
las = add_lasrgb(las, rgbi$Red, rgbi$Green, rgbi$Blue)
las$B[1:6]
rgbi$Blue[1:6]
# > las$B[1:6]
# [1] 14135     0 20560 14135 20560 16705
# > rgbi$Blue[1:6]
# [1] 55  0 80 55 80 65

# Add NIR values
las = add_lasattribute_manual(las.rgb, rgbi$IR, name="NIR", desc="NIR",type="float")
# Error: NIR is part of the core attributes and is a forbidden name.

In the description for add_attribute() it says "These functions are dedicated to adding data that are not part of the LAS specification. For example, add_lasattribute(las, x, "R") will fail because R is a name reserved for the red channel of a .las file that contains RGB attributes. Use add_lasrgb instead."

However, there is not a function to add NIR information as there is for RGB. Is there another way of storing this information? I tried add_lasattribute_manual() as suggested here but it retrieves the error that says NIR is a forbidden name.

Also, RGB values are not stored as they are indicated. I guess it has to do with some scaling but I dont understand what is being done and how to avoid it.

Best Answer

There is indeed no add_nir. This could be added. You can simply force the addition of the column by by-passing control implemented in lidR

las@data$NIR = IR

One reason there is a function add_lasrgb in mainly because the point cloud format must updated if you want to write it in a LAS file. Your point format is 1 at the begining. Then you used add_rgb so the format becomes 3. To write a valid LAS file with RGB and NIR the format must be 8 (no other option)

las@header@PHB[["Point Data Format ID"]] <- 8L

add_nir() would look like (with some extra control to ensure the validity of the data)

add_lasnir <- function(las, NIR)
{
  las@data$NIR <- NIR
  las@header@PHB[["Point Data Format ID"]] <- 8L
  return(las)
}

Also, RGB values are not stored as they are indicated. I guess it has to do with some scaling but I dont understand what is being done and how to avoid it.

RGB are scaled and recorded on 16 bits as required by the specifications. This is what is written in the LAS specifications

Note that Red, Green, Blue and NIR values should always be normalized to 16 bit values. For example, when encoding an 8 bit per channel pixel, multiply each channel value by 256 prior to storage in these fields. This normalization allows color values from different camera bit depths to be accurately merged


Edit: I added a function add_lasnir() in v4.0.3

Related Question