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)),

# First add rgb values with the existing command 
las = add_lasrgb(las, rgbi$Red, rgbi$Green, rgbi$Blue)
# > 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.

1 Answer 1


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

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

  • When running the new add_lasnir() function on the example I see that it does not make any changes to the NIR values as add__lasrgb() does to RGB values. Shouldn't they be normalized as well? Commented Feb 2, 2023 at 9:44
  • Also, as it says in the LAS specifications to multiply by 256 each of the RGB channels, if I multiply for example rgbi$Blue values by 256, they are not equal to las$B. Shouldn't they be the equal? I havelook into the add_lasrgb funtion and I think it multiplies by 257, is this correct? Commented Feb 2, 2023 at 9:48
  • This is correct, lidR multiplies by 257 such as 255 <-> 65535. The function add_nir() in my example does not scale. The new function in 4.0.3 does it.
    – JRR
    Commented Feb 2, 2023 at 10:30
  • I can confirm it is working in lidR 4.0.3, thanks. I still dont understand why is multiplying by 257 and not 256 though. Commented Feb 2, 2023 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.