rescaleImage ignoring ymin and ymax?
Opened this issue · 7 comments
Doing:
> ima <- raster(matrix(rnorm(n=10^4,m=0,sd=2)))
> cellStats(ima,range)
[1] -7.437958 7.845097
> q <- quantile(ima,probs=c(0.02,0.98))
> q
2% 98%
-4.168026 4.168633
> ima2 <- rescaleImage(ima,xmin=q[1],xmax=q[2],ymin=0,ymax=255,forceMinMax = TRUE)
> cellStats(ima2,range)
[1] -100.0200 367.4549
I was expecting ima2 to be rescaled from range -7.437958 , 7.845097 -4.168026, 4.168633 to 0, 255
Am I misunderstanding the doc or is there an error?
rescaleImage
is working correctly.
xmin
and xmax
are only needed if the values in the input raster do not contain the theoretical min and max values. As documented, this could be the case if you have NDVI values ranging from -0.2 to 0.6, for example, but the theoretical value range is -1 to 1. In this case you would want to specify xmin and xmax.
In your example, the data values exceed the theoretical min and max you provide and the rescaling is ill-defined and will inevitably result in values outside of the specified ymin:ymax range.
I guess what you actually wanted to accomplish is this:
imc <- clamp(ima, lower=q[1],upper=q[2]) # check ?raster::clamp for the useValues argument
ima2 <- rescaleImage(imc, xmin=q[1], xmax=q[2], ymin=0, ymax=255, forceMinMax = TRUE)
cellStats(ima2,range)
#> 0 255
It is not inevitable, it just needs to clamp the output to conform to the specified ymin, ymax range.
In effect, what I want to do is what you do in the 2 commands: I expected the clamp was done by default to conform to the specified ymin, ymax range.
I understand the same result can be obtained with
clamp(rescaleImage(ima, xmin=q[1], xmax=q[2], ymin=0, ymax=255, forceMinMax = TRUE), lower=0,upper=255)
but including the clamp as an option within rescaleImage() would be more efficient for large raster brick objects and certainly easier for the user.
That is correct of course. Yet, if you clamp beforehand, you have the choice to set all values exceeding the quantiles to NA, if you so wish. But I agree, that option can be added to rescaleImage.
Good we finally agree! Should I fill another ticket with that request or is this one sufficient?
Agus
No, this one is sufficient.
I've deleted my last comment, I was mixing things up with raster::stretch()
(which works now, see
rspatial/raster#70 )
Thanks to a recent improvemnt of raster::clamp(),
rspatial/raster#120
r <- raster(ncols=12, nrows=12)
values(r) <- 1:ncell(r)
b <- brick(r,r*2,r/2)
q <- quantile(b,probs=c(0.02,0.98))
> q
2% 98%
layer.1 3.86 141.14
layer.2 7.72 282.28
layer.3 1.93 70.57
b2 <- clamp(b,lower=q[,1], upper=q[,2],useValue=TRUE)
cellStats(b2,range)
layer.1 layer.2 layer.3
[1,] 3.86 7.72 1.93
[2,] 141.14 282.28 70.57
b4 <- rescaleImage(clamp(b,lower=q[,1], upper=q[,2],useValue=TRUE),
+ xmin=q[,1], xmax=q[,2], ymin=1, ymax=255, forceMinMax = TRUE)
cellStats(b4,range)
layer.1 layer.2 layer.3
[1,] 1 1 1
[2,] 255 255 255