以下代码生成一些在白色背景上带有蓝色圆圈的图像,圆圈内有一些白色多边形。圆圈的颜色围绕蓝色变化。我想添加某种噪音,如下图蓝色圆圈内所示。我假设它必须创建一个随机噪声矩阵,然后将该层合并到图像顶部或在蓝色圆圈和白色多边形层之间合并。我不知道如何实现这一目标。
library(plotrix)
library(grDevices)
library(doParallel)
library(foreach)
# Function to add noise to the circle
shape_noise <- function(x, y, radius, noise_level = 0.025) {
angles <- seq(0, 2 * pi, length.out = 100)
radii <- radius + rnorm(100, mean = 0, sd = noise_level)
x_noise <- x + radii * cos(angles)
y_noise <- y + radii * sin(angles)
list(x = x_noise, y = y_noise)
}
# Function to generate noise texture
generate_noise <- function(width, height) {
matrix(runif(width * height), nrow = width, ncol = height)
}
# Set the number of cores for parallel processing
num.cores <- detectCores() - 1
registerDoParallel(cores = num.cores)
num.sample <- 10 # Number of images to generate
min_plaque.count <- 5
max_plaque.count <- 20
circle_results <- foreach(i = 1:num.sample, .packages = c("plotrix", "grDevices")) %dopar% {
num.spots <- sample(min_plaque.count:max_plaque.count, 1)
file_name <- paste0("./data_raw/image_id_", i, "_", num.spots, ".png")
mask_file_name <- paste0("./data_mask/image_id_", i, "_", num.spots, "_mask.png")
area <- c()
circumference <- c()
polygons <- list()
# Generate the raw image
png(file_name, width = 1024, height = 1024, res = 200, type = "cairo-png")
par(mar = c(0, 0, 0, 0)) # Remove margins
plot(0:10, 0:10, type = "n", asp = 1, xlab = "", ylab = "", xaxt = 'n', yaxt = 'n', bty = 'n')
blue_start <- rgb(0, 0, runif(1, 0.4, 1))
blue_end <- rgb(0, 0, runif(1, 0.4, 1))
gradient_col <- colorRampPalette(c(blue_start, blue_end))(100)
# Add noise to the circle
circle_noise <- shape_noise(5, 5, 5)
polygon(circle_noise$x, circle_noise$y, col = gradient_col, border = NA)
# Generate and overlay noise texture
noise_texture <- generate_noise(1024, 1024)
noise_texture_scaled <- (noise_texture - min(noise_texture)) / (max(noise_texture) - min(noise_texture))
noise_col <- rgb(0, 0, 1, alpha = noise_texture_scaled)
for (k in 1:length(circle_noise$x)) {
polygon(circle_noise$x, circle_noise$y, col = noise_col[k], border = NA)
}
num_faded <- sample(num.spots, 1) # Number of spots to have fading effect, randomly chosen
fade_indices <- sample(num.spots, num_faded) # Randomly choose which spots will fade
for (k in 1:num.spots) {
plot <- 0
while (plot == 0) {
x <- runif(1, 0, 10)
y <- runif(1, 0, 10)
d <- runif(1, 0.1, 0.3) # diameter of the spot
if ((x + d - 5)^2 + (y + d - 5)^2 < 4.5^2) { # Check if inside the larger circle
plot <- 1
}
}
# Create random vertices for irregular shape
vertices <- 10
angles <- sort(runif(vertices, 0, 2 * pi))
radii <- rnorm(vertices, mean = d, sd = 0.03)
x_vertices <- x + radii * cos(angles)
y_vertices <- y + radii * sin(angles)
# Applying fading effect conditionally
if (k %in% fade_indices) {
distances <- sqrt((x_vertices - x)^2 + (y_vertices - y)^2)
fade_factors <- 1 - (0.9 * distances / max(distances)) # normalize and invert to fade from center to edge
col <- rgb(1, 1, 1, fade_factors) # apply fade based on distance
} else {
col <- "white"
}
polygon(x_vertices, y_vertices, col = col, border = NA)
}
dev.off()
}
# Stop parallel backend
stopImplicitCluster()
虽然这个参考图像是黑白的,但这正是我在蓝色圆圈中寻找的效果。
这是一种不同的方法,但也许您可以利用它来获得您想要的效果。我将噪声层、聚光灯“焦点”层和圆形蒙版组合起来,以获得与参考类似的效果。也许有一种方法可以重新表述这一点,使旋转调整更加直观......
library(tidyverse)
expand_grid(x = seq(0, 1, length.out = 700), y = seq(0, 1, length.out = 500)) |>
mutate(noise = runif(n(), min = 0, max = 1),
focus = ((x - 0.5)^2 + (y - 0.7)^2)^0.5,
in_circle = ((x - 0.5)^2 + (y - 0.5)^2)^0.5 < 0.4,
value = pmin(0.2, pmax(0, (noise - 0.2) * (1-focus)^4 * in_circle))) |>
ggplot(aes(x, y, fill = value)) +
geom_raster() +
scale_fill_gradient2(low = "black", midpoint = 0.2, high = "white") +
coord_fixed() +
theme_void()