Search code examples
rimagergbraster

Modify range of color of raster image in R


I take photo with a black background but due to the light, it can have some reflect. In R I would like to change the background to black one (RGB = 0). I would like to select the color with RGB values lower than 80 and change to 0.

enter image description here

I use this code in R:

 library(raster)
    folder <- "C:/Users/PC/Pictures/"
    img <- list.files(folder) 
    img.raster<-stack(img)
    names(img.raster) <- c('r','g','b')
    color <- 80
    img.black<-img.raster[[1]]
    img.black[img.raster$r<color & img.raster$g<color & img.raster$b<color] <- 0

I rebuilt my image using stack

image = stack(img.black, img.black, img.black)

But by doing this I lose information as I have the same layer for R,G and B. If I tried:

image = stack(img.black, img.raster, img.raster)

by this way the dimension of the image is 7 !!

How to select a range of color and change it without modifying the dimension of the image and the other colors. Do I need to use raster or is there another solution ?


Solution

  • Here is how you could do that. Note that I update the color to 255 rather than 0 to be able to see the effect in this example. Also, you used the first layer of RGB as black. I assume you wanted the third.

    Example data

    library(raster)
    img <- stack(system.file("external/rlogo.grd", package="raster"))
    plotRGB(img)
    

    Solution

    color_threshold <- 80
    update_value <- 255 # 0 in your case
    black <- 3 
    i <- all(img < color_threshold)
    img[[black]] <- mask(img[[black]], i, maskvalue=1, updatevalue=update_value)
    plotRGB(img)
    

    Or perhaps this is what you are after --- update all cells to zero, not just the black channel:

    img <- brick(system.file("external/rlogo.grd", package="raster"))
    img2 <- mask(img, all(img < 80), maskvalue=1, updatevalue=0)
    plotRGB(img2)