【问题标题】:How to rotate an image R raster如何旋转图像 R 光栅
【发布时间】:2015-09-03 08:00:34
【问题描述】:

我有下面的代码,可以将图像保存到我的电脑。我想将该图像围绕其中心(或左下角)旋转 45,90 和 135 度,然后另存为 3 个不同的图像。我怎么能这样做?

library(raster)
r1 <- brick(system.file("external/rlogo.grd", package="raster"))
x <- crop(r1, extent(0,50,0,50))
plotRGB(x)
png(width=50, height=50)
par(mai=c(0,0,0,0))
image(x)
dev.off()

---------update1-------------

根据接受的答案,工作代码如下

library(raster)
r1 <- brick(system.file("external/rlogo.grd", package="raster"))
r1
x <- crop(r1, extent(0,ncol(r1),0,nrow(r1)))
plotRGB(x)

x1 <- 0:ncol(x)
y1 <- 0:nrow(x)
z <- matrix(1, nrow=length(x1), ncol=length(y1))

col.mat <- t(apply(matrix(rgb(getValues(x)/255), nrow=nrow(x), byrow=TRUE), 2, rev))

# Rotate 45 degrees
persp(x1, y1, z, zlim=c(0,2), theta = 20, phi = 90, 
      col = col.mat, scale=FALSE, border=NA, box=FALSE)
png("SaveThisPlot.png")
persp(x1, y1, z, zlim=c(0,2), theta = 20, phi = 90, 
      col = col.mat, scale=FALSE, border=NA, box=FALSE)
dev.off()

【问题讨论】:

  • rotate 之类的东西在 raster 包中?
  • 你有什么例子吗?我试过了,我得到了如上所示的错误
  • @Frank 有没有办法进行 45 度旋转?你的命令有效!
  • @AlexA。光栅包中的旋转仅更改坐标系。 OP 要求的是对图像本身进行真正的旋转。

标签: r plot rotation raster


【解决方案1】:

对于 90 度旋转,这是一个简单的解决方案:

image(t(flip(x, 1)))
image(t(flip(x, 2)))
plotRGB(t(flip(x, 1)))
plotRGB(t(flip(x, 2)))

对于 45 度和 135 度旋转,会有点棘手。可能还有其他方法,但我将使用persp 函数并为theta 参数提供不同的角度。

只需正确设置对persp 的调用即可。 x1y1z 只是 persp 函数的输入(有关该函数参数的更多信息,请参阅 ?persp)。 col.mat 是一个保存颜色值的矩阵。

x1 <- 0:ncol(x)
y1 <- 0:nrow(x)
z <- matrix(1, nrow=length(x1), ncol=length(y1))
col.mat <- t(apply(matrix(rgb(getValues(x)/255), nrow=nrow(x), byrow=TRUE), 2, rev))
# the transposing and reversing are just to get the colors in the same 
# spots as they're in when viewing plotRGB(x).
#
# getValues(x) is how you get the rgb colors, in the form of a 3-column matrix.
# rgb(getValues(x)/255) converts them into hex code, which is convenient enough here.

如果您发现这是您正在寻找的镜像,请尝试以不同的方式填充颜色矩阵。例如:

col.mat <- matrix(rgb(getValues(x)/255), nrow=nrow(x))

如您所知,正确填充颜色矩阵是使这种方法适合您的关键。我将把它作为练习留给读者,以了解如何对颜色矩阵进行任何其他操作。

现在,致电persp。在这里,我设置了zlim的值,所以有一个包括1的范围。因为我把所有的z值都设置为1,所以你需要设置一个有效的范围,否则persp会抛出一个关于无效限制的错误。它不喜欢从 1 到 1 的范围。

# Rotate 45 degrees
persp(x1, y1, z, zlim=c(0,2), theta = 45, phi = 90, 
    col = col.mat, scale=FALSE, border=NA, box=FALSE)

这里是 135 度:

# Rotate 135 degrees
persp(x1, y1, z, zlim=c(0,2), theta = 135, phi = 90, 
    col = col.mat, scale=FALSE, border=NA, box=FALSE)

可以按照您在问题中显示的相同方式保存图:

png("SaveThisPlot.png")
persp(x1, y1, z, zlim=c(0,2), theta = 135, phi = 90, 
    col = col.mat, scale=FALSE, border=NA, box=FALSE)
dev.off()

【讨论】:

【解决方案2】:

不抛出错误或警告消息的方法(在阅读帮助页面并使用示例后:)

extent(x) <- extent(0, 360, -90, 90)
rr <- rotate(x)
 png()
 plotRGB(x)
dev.off()

但您可能不喜欢它,因为它假定了一个您可能不喜欢的特定坐标系。如果要提取数据元素,请使用@ 运算符:

str(x)  The slots are named 'data' and 'values'
image(x)
image(matrix(x@data@values[,1], 50, byrow=TRUE)) # rotate one layer

【讨论】:

  • 我不认为它在旋转我的图像。相反,它似乎是沿着 x 轴拉伸我的图像:(
  • 实际上它正在旋转并变形,但在分成两半之后(因为假设坐标系为 -180 到 +180)。我警告过你不会喜欢的。
  • rotate 用于单个特殊情况。将全球经度/纬度数据从 0..360 度“旋转”到 -180..180 度经度。这(直接使用 S4 插槽,您不知道它们的用途)image(matrix(x@data@values[,1], 50, byrow=TRUE)) 是一个糟糕的建议。
  • 是的,rotate 是针对特定情况的。这我的观点。同意“直接使用”“值”矩阵对于永远不想深入了解的用户来说可能是一个“可怕的建议”,但我反驳说,你经常确实想了解你正在工作的数据对象的性质与。
  • 我同意“想要理解”,但我认为在这种情况下,你正在以错误的方式引导人们。 'raster' 包具有获取值的方法(getValues、as.matrix、values() 等等)。如果一个对象是从一个文件派生的,那么你引用的槽中就不会有任何值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 2020-12-27
  • 2020-03-27
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多