R光栅绘制图像,绘制圆圈并遮盖圆圈外的像素
R raster plotting an image, draw a circle and mask pixels outside circle
下面的代码绘制一个图像,然后在该图像上绘制圆圈。我想让所有落在该圆圈之外的像素变黑。我该怎么做?
library(raster)
library(plotrix)
r1 <- brick(system.file("external/rlogo.grd", package="raster"))
width=50
height=40
x <- crop(r1, extent(0,width,0,height))
plotRGB(x)
circlex=20
circley=15
radius=10
draw.circle(circlex,circley,radius,border="blue")
使用 str() 查看 'x'-对象,您会看到:
..@ data :Formal class '.MultipleRasterData' [package "raster"] with 14 slots
.. .. ..@ values : num [1:2500, 1:3] 255 248 221 199 198 210 221 190 104 79 ...
.. .. .. ..- attr(*, "dimnames")=List of 2
.. .. .. .. ..$ : NULL
.. .. .. .. ..$ : chr [1:3] "red" "green" "blue"
...因此 1:50 by 1:50 值映射到三列。 X 值可能是 0:2500 %% 50
,y 值可能是 0:2500 %/% 50
因此请记住,"origin" 如果光栅对象的左上角是绘图函数的左下角,因此 20 的 y 值变为 50-20 或 30,这使您接近您的要求(抱歉将 y 序列放在首位):
x@data@values[( ((1:2500 %/% 50 )- 30)^2 + ((1:2500 %% 50) - 20)^2 ) >=100, 1] <- 0
x@data@values[( ((1:2500 %/% 50 )- 30)^2 + ((1:2500 %% 50) - 20)^2 ) >=100, 2] <- 0
x@data@values[( ((1:2500 %/% 50 )- 30)^2 + ((1:2500 %% 50) - 20)^2 ) >=100, 3] <- 0
plotRGB(x)
draw.circle(20,20,10,border="blue")
逻辑是标准的形式为 (x-dx)^2+(y-dy)^2 > r^2 其中 dx 和 dy 是圆的中心坐标,r 是半径== 10.
问题更改后的编辑:
对于每个颜色层,具有命名参数的代码将类似于制作最暗层的代码 "red"。这给出了一个大致圆形的蒙版,尽管没有正确处理使中心对齐:
x@data@values[( ((1:(height*width) %/% (height*5/4) )- (height-circley*5/4) )^2 +
((1:(height*width) %% width) - circlex )^2 ) >= radius^2, 1] <- 0
进一步的实验表明这看起来非常接近:
x@data@values[( ((1:(height*width) %/% (height) )- (height-circley) *5/4)^2 +
((1:(height*width) %% width) - circlex )^2 ) >= radius^2, 1] <- 0
plotRGB(x, asp=5/4, addfun=function() draw.circle(circlex,circley,radius,border="blue") )
显然,您可以在出现 5/4 的任何地方用 width/height
比例因子替换新的纵横比。
这是一个更通用的解决方案,也适用于具有不同坐标系的栅格。
函数rasterToPoints()
将栅格转换为点。按照您的示例,head(rasterToPoints(x))
returns 以下内容:
> head(rasterToPoints(x))
x y red green blue
[1,] 0.5 39.5 255 255 251
[2,] 1.5 39.5 204 205 199
[3,] 2.5 39.5 171 172 164
[4,] 3.5 39.5 157 159 148
[5,] 4.5 39.5 162 164 151
[6,] 5.5 39.5 187 189 176
然后我们需要找到落在圆圈外的点并将它们的值设置为零:
is_outside_circ = (rasterToPoints(x)[,1] - circlex)^2 + (rasterToPoints(x)[,2] - circley)^2 >= radius^2
x@data@values[ is_outside_circ,] <- 0
plotRGB(x)
draw.circle(circlex,circley,radius,border="blue")
Result: black points outside circle
下面的代码绘制一个图像,然后在该图像上绘制圆圈。我想让所有落在该圆圈之外的像素变黑。我该怎么做?
library(raster)
library(plotrix)
r1 <- brick(system.file("external/rlogo.grd", package="raster"))
width=50
height=40
x <- crop(r1, extent(0,width,0,height))
plotRGB(x)
circlex=20
circley=15
radius=10
draw.circle(circlex,circley,radius,border="blue")
使用 str() 查看 'x'-对象,您会看到:
..@ data :Formal class '.MultipleRasterData' [package "raster"] with 14 slots
.. .. ..@ values : num [1:2500, 1:3] 255 248 221 199 198 210 221 190 104 79 ...
.. .. .. ..- attr(*, "dimnames")=List of 2
.. .. .. .. ..$ : NULL
.. .. .. .. ..$ : chr [1:3] "red" "green" "blue"
...因此 1:50 by 1:50 值映射到三列。 X 值可能是 0:2500 %% 50
,y 值可能是 0:2500 %/% 50
因此请记住,"origin" 如果光栅对象的左上角是绘图函数的左下角,因此 20 的 y 值变为 50-20 或 30,这使您接近您的要求(抱歉将 y 序列放在首位):
x@data@values[( ((1:2500 %/% 50 )- 30)^2 + ((1:2500 %% 50) - 20)^2 ) >=100, 1] <- 0
x@data@values[( ((1:2500 %/% 50 )- 30)^2 + ((1:2500 %% 50) - 20)^2 ) >=100, 2] <- 0
x@data@values[( ((1:2500 %/% 50 )- 30)^2 + ((1:2500 %% 50) - 20)^2 ) >=100, 3] <- 0
plotRGB(x)
draw.circle(20,20,10,border="blue")
逻辑是标准的形式为 (x-dx)^2+(y-dy)^2 > r^2 其中 dx 和 dy 是圆的中心坐标,r 是半径== 10.
问题更改后的编辑:
对于每个颜色层,具有命名参数的代码将类似于制作最暗层的代码 "red"。这给出了一个大致圆形的蒙版,尽管没有正确处理使中心对齐:
x@data@values[( ((1:(height*width) %/% (height*5/4) )- (height-circley*5/4) )^2 +
((1:(height*width) %% width) - circlex )^2 ) >= radius^2, 1] <- 0
进一步的实验表明这看起来非常接近:
x@data@values[( ((1:(height*width) %/% (height) )- (height-circley) *5/4)^2 +
((1:(height*width) %% width) - circlex )^2 ) >= radius^2, 1] <- 0
plotRGB(x, asp=5/4, addfun=function() draw.circle(circlex,circley,radius,border="blue") )
显然,您可以在出现 5/4 的任何地方用 width/height
比例因子替换新的纵横比。
这是一个更通用的解决方案,也适用于具有不同坐标系的栅格。
函数rasterToPoints()
将栅格转换为点。按照您的示例,head(rasterToPoints(x))
returns 以下内容:
> head(rasterToPoints(x))
x y red green blue
[1,] 0.5 39.5 255 255 251
[2,] 1.5 39.5 204 205 199
[3,] 2.5 39.5 171 172 164
[4,] 3.5 39.5 157 159 148
[5,] 4.5 39.5 162 164 151
[6,] 5.5 39.5 187 189 176
然后我们需要找到落在圆圈外的点并将它们的值设置为零:
is_outside_circ = (rasterToPoints(x)[,1] - circlex)^2 + (rasterToPoints(x)[,2] - circley)^2 >= radius^2
x@data@values[ is_outside_circ,] <- 0
plotRGB(x)
draw.circle(circlex,circley,radius,border="blue")
Result: black points outside circle