-
Notifications
You must be signed in to change notification settings - Fork 5
/
README.Rmd
224 lines (165 loc) · 8.46 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
---
output:
github_document:
html_preview: false
editor_options:
chunk_output_type: console
---
rayimage
=========================================================
<!-- badges: start -->
[![R build status](https://github.com/tylermorganwall/rayimage/workflows/R-CMD-check/badge.svg)](https://github.com/tylermorganwall/rayimage/actions)
[![:name status badge](https://tylermorganwall.r-universe.dev/badges/:name)](https://tylermorganwall.r-universe.dev/)
[![rayrender status badge](https://tylermorganwall.r-universe.dev/badges/rayimage)](https://tylermorganwall.r-universe.dev/rayimage)
![cran-badge rayrender package](http://www.r-pkg.org/badges/version/rayimage)
[![Codecov test coverage](https://codecov.io/gh/tylermorganwall/rayimage/graph/badge.svg)](https://app.codecov.io/gh/tylermorganwall/rayimage)
<!-- badges: end -->
<img src="man/figures/githubdemo.gif" ></img>
Overview
--------
**rayimage** is an open source R package for image manipulation and simulated camera effects. **rayfocus** uses convolution-based techniques to generate simulated camera bokeh, depth of field, and other camera effects, using an image and an optional depth map. It includes functions to perform 2D convolutions, add image overlays, generate camera vignette effects, and add titles to images.
Installation
------------
``` r
# To install the latest version from Github:
# install.packages("remotes")
remotes::install_github("tylermorganwall/rayimage")
```
Functions
---------
* `render_bokeh()` takes two images as an input: an in-focus image, and a depth map for that image. These can either be in-memory representations of the image, or file paths to the images. The user can also specify various camera settings, including: focal length, f-stop, aperture shape (including custom aperture shapes passed by the user), aperture rotation, bokeh intensity, bokeh intensity limit. The output is either plotted to the current device, or save to a file (if a filename is passed to the function).
* `render_convolution()`/`render_convolution_fft()` performs a convolution with a user-supplied kernel (either custom, or using one of the built-in functions to generate a kernel: `generate_2d_gaussian()`, `generate_2d_exponential()`, and `generate_2d_disk()`). This function can be applied to either images represented by RGB arrays/file-names, or 2D matrices.
* `render_resized()` resizes an image or a matrix using a magnification factor or the dimensions of the desired object. This function interpolates between points using bilinear interpolation.
* `render_reorient()` reorients an image, either flipping horizontally, vertically, or with a transpose operation.
* `render_text_image()` generates a tightly bounded image containing text, with custom font support and emoji support if the `ragg` package is installed.
* `render_title()` adds titles to images, with an optional title bar. User can specify opacity, color, and font properties.
* `render_vignette()` adds a camera vignette effect, which is a slight darkening by the edges of an image.
* `render_image_overlay()` adds overlays to images.
* `plot_image()` plots an RGB array to the current device.
* `plot_image_grid()` plots a list of RGB arrays in a user-specified grid to the current device.
Usage
-----
```{r setup, include = FALSE}
library(knitr)
library(rgl)
knit_hooks$set(rgl = hook_rgl)
knitr::opts_chunk$set(
fig.path = "man/figures/",
cache = TRUE,
fig.width = 8,
fig.height = 4
)
set.seed(1001)
```
The package comes with a sample image and depth map derived from Stanford "Chinese Dragon" 3D model. The image is included in rayimage as `dragon` and the depthmap is `dragondepth`. We plot these 3D image arrays simply by calling `plot_image()`.
```{r basic}
library(rayimage)
library(grid)
plot_image(dragon)
plot_image(dragondepth/2000)
```
You can also easily plot a grid of images.
```{r grid}
plot_image_grid(list(dragon, dragondepth/2000),
dim = c(2,1))
```
Preview the focal plane.
```{r focal, fig.width=8, fig.height=4}
render_bokeh(dragon,dragondepth,focus=930,preview_focus = TRUE)
render_bokeh(dragon,dragondepth,focus=930,focallength=250)
render_bokeh(dragon,dragondepth,focus=1300,preview_focus = TRUE)
render_bokeh(dragon,dragondepth,focus=1300,focallength=250)
```
We can also adjust the focal point, shape of the aperture, f-stop, focal length, as well as the bokeh intensity.
```{r manyimages, fig.width=8, fig.height=8}
image_list = list()
image_list[[1]] = render_bokeh(dragon,dragondepth,focus=1100,focallength = 400,
bokehshape = "hex", bokehintensity = 1, preview = FALSE)
image_list[[2]] = render_bokeh(dragon,dragondepth,focus=900,focallength = 400,
bokehshape = "hex", bokehintensity = 1, preview = FALSE)
image_list[[3]] = render_bokeh(dragon,dragondepth,focus=900,focallength = 400,
fstop = 16, bokehshape = "hex", preview = FALSE)
image_list[[4]] = render_bokeh(dragon,dragondepth,focus=900,focallength = 300,
bokehshape = "hex", bokehintensity = 5, preview = FALSE)
plot_image_grid(image_list, dim = c(2,2))
```
We can add a camera vignette effect, titles, and add overlays (not shown here):
```{r vignettetitle, fig.width=8, fig.height=4}
image1 = dragon |>
render_title("Dragon", title_size = 20, title_bar_color = "red",
title_bar_alpha=0.8, title_color="white", title_offset = c(12,12))
image2 = dragon |>
render_vignette(vignette=0.8)
plot_image_grid(list(image1,image2), dim = c(2,1))
```
We can generate images with custom fonts and emojis:
```{r emoji}
#Use a custom font.
render_text_image("AVATAR", font = "Papyrus", size=100,
color = "#aaddff",
background_color = "black",
preview = TRUE)
#Plot an emoji with the agg device and increase resolution.
render_text_image("😀🚀", size = 500,
background_alpha = 0,
preview = TRUE)
```
We can also resize images and matrices with `render_resize()`. We can do this before adding text to make the resulting text smoother.
```{r resize, fig.width=8, fig.height=8}
#Double the input size to make the resulting text smoother.
image3 = dragon |>
render_resized(mag = 2) |>
render_title("Dragon", title_size = 20, title_bar_color = "red",
title_bar_alpha=0.8, title_color="white", title_offset = c(12,12))
#Specify resulting dimensions directly.
image4 = dragon |>
render_resized(dim = c(600,300)) |>
render_title("Dragon", title_size = 20, title_bar_color = "red",
title_bar_alpha=0.8, title_color="white", title_offset = c(12,12))
plot_image_grid(list(image3,image4), dim = c(2,1))
```
Reorienting images and matrices can be done with `render_reorient()`:
```{r fig.width=4, fig.height=4}
render_reorient(dragon, preview = TRUE)
render_reorient(dragon, flipx = TRUE, preview = TRUE)
render_reorient(dragon, flipy = TRUE, preview = TRUE)
render_reorient(dragon, transpose = TRUE, preview = TRUE)
```
We can also use the `render_convolution()` directly to perform a convolution with a user-defined (or built-in) kernel.
```{r generated, fig.width=8, fig.height=4}
#Default gaussian kernel
plot_image_grid(list(render_convolution(dragon, kernel = "gaussian"),
generate_2d_gaussian(1,1,11,3, rescale_unity = TRUE)),
dim = c(2,1))
#Custom gaussian kernel
plot_image_grid(list(render_convolution(dragon, kernel = generate_2d_gaussian(10,1,31,21)),
generate_2d_gaussian(10,1,31,21, rescale_unity = TRUE)),
dim = c(2,1))
#Custom exponential kernel
plot_image_grid(list(render_convolution(dragon, kernel = generate_2d_exponential(3,31,21)),
generate_2d_exponential(3,31,21, rescale_unity = TRUE)),
dim = c(2,1))
#Custom disk kernel
plot_image_grid(list(render_convolution(dragon, kernel = generate_2d_disk(31)),
generate_2d_disk(31, rescale_unity = TRUE)),
dim = c(2,1))
```
We can also use this to perform generate discrete 2D convolutions with matrices:
```{r}
par(mfrow = c(1,2))
volcano |> image()
volcano |>
render_convolution(kernel=generate_2d_gaussian(sd=1,dim=31)) |>
image()
```
And here we use a user-defined kernel, in the shape of a cross.
```{r fig.width=8, fig.height=8}
custom1 = matrix(0, nrow=11,ncol=11)
custom1[6,] = 1
custom1[,6] = 1
custom2 = diag(10) + (diag(10)[,10:1])
plot_image_grid(list(custom1,custom2,
render_convolution(dragon, kernel = custom1),
render_convolution(dragon, kernel = custom2)),
dim = c(2,2))
```