Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with single bands of a multiband image? #626

Closed
gilbertocamara opened this issue Apr 25, 2023 · 7 comments
Closed

How to work with single bands of a multiband image? #626

gilbertocamara opened this issue Apr 25, 2023 · 7 comments

Comments

@gilbertocamara
Copy link

Hi @edzer

I have a multiband image and I am trying to process each band independently. However, I am at a loss to find out how to do so.
Please see the following MWE

image_path <- "https://www.dropbox.com/s/az9oxl1tcw1mz84/SENTINEL-2_MSI_20LLQ_2020-06-04_2021-08-26_variance_v1.tif?dl=1"

# read image using stars
image_st <- stars::read_stars( image_path, proxy = FALSE)
# set the labels
labels <- c("Water", "ClearCut_Burn", "ClearCut_Soil", "ClearCut_Veg",
            "Forest", "Wetlands")
names(labels) <- seq_along(labels)

# rename stars object dimensions to labels
image_st <- stars::st_set_dimensions(image_st, "band", values = labels)

The following command, which processes all pixels of all bands, works fine.

scale <- 0.01
image_st <- image_st * scale

I can acess the an image subset, but not process it. The following commands work.

image_st[,,,"Water"] 
image_st[,,,"Water"] > 5.0

My problem is that I want to process each band independently and the following command does not work.

scale <- 0.01
image_st[,,,"Water"] <- image_st[,,,"Water"]  * scale

What is the correct way to process individual bands in a stars image?

Many thanks,
Gilberto

@kadyb
Copy link
Contributor

kadyb commented Apr 25, 2023

How about this way?

idx = which(labels == "Water")
image_st[[1]][,,idx] = image_st[[1]][,,idx] * scale

@edzer
Copy link
Member

edzer commented Apr 25, 2023

Yes, that was also my first thought: use the fact that image_st[[1]] is an R array. The alternative (using labels) could split the array into a set of 6 2-dimensional arrays:

image_spl = split(image_st)
image_spl[["Water"]] = image_spl[["Water"]] * scale                                   

and if needed merge again by

merge(image_spl)

This works at the same level: [[ extracts the array, [[<- replaces it.

@edzer
Copy link
Member

edzer commented Apr 25, 2023

But I'd agree it would be nice if this would work with single brackets!

@gilbertocamara
Copy link
Author

Thanks, @edzer, works!

@edzer
Copy link
Member

edzer commented Apr 25, 2023

But I'd agree it would be nice if this would work with single brackets!

This allows for

image_spl["Water"] = image_spl["Water"] * scale                                   

and does some checking of the dimensions.

@gilbertocamara
Copy link
Author

Hi @edzer, the quandary between [ ] and [[ ]] is an inherent problem in R. Maybe the only suggestion I would give is to provide some examples in the documentation.

edzer added a commit that referenced this issue Apr 25, 2023
@edzer
Copy link
Member

edzer commented Apr 25, 2023

Great idea!

@edzer edzer closed this as completed Jun 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants