I'm trying to create a series of black and white images of visual noise, in which each image is identical to the previous one except for a proportion of random pixels which have swapped colours (black pixels turn white, and white pixels turn black).
I can generate the images individually, but now I want to put the code in a loop so I can generate and save a sequence of 300 images. However, I am having some trouble. There are multiple problems with my loop as I've tried to cobble it together from a combination of other questions and answers on stack overflow, and I don't fully understand what I'm doing (I'm new to programming).
Here's my code:
file_names <- c("VN1", "VN2", "VN3", "VN4", "VN5")
next_image <- c()
for (i in 1:5) {
im <- if (i == 1) {
load.image("C:/Users/Ali/Desktop/VN_images/VN.png")
} else {
load.image(next_image)
}
df <- as.data.frame(im) %>%
mutate(colour = case_when(value == 0 ~ "black", TRUE ~ "white")) %>%
group_by(colour) %>%
mutate(value = replace(value, sample(row_number(), size = ceiling(0.05 * n()), replace = FALSE), 3))
df$value[df$value == 3 & df$colour == "black"] <- 1
df$value[df$value == 3 & df$colour == "white"] <- 0
df1 <- df[, -4]
new_image <- as.cimg(df1, dims = c(150,100))
save.image(new_image, "C:/Users/Ali/Desktop/VN_images/", file_names[i], ".png")
next_image <- c(next_image, new_image)
}
EDIT: question edited to fix error highlighted by @nrennie below
My main problem at the moment appears to be saving the new image that is generated by the code - I need each new file to have a different name and for the names to preserve the sequence in which they were generated - and then loading the new image in the next iteration of the loop.
With the code as above I get the error message "Error in save.image(new_image, "C:/Users/Ali/Desktop/VN_images/", : unused argument (".png")"
If I change the file path to "C:/Users/Ali/Desktop/VN_images/A.png" the code will run once and save an image named "A.png", but also return the error "Error in if (is.url) { : the condition has length > 1" so there also appears to be a problem loading the new image in the second iteration.
I've looked at several previous answers to similar questions (e.g., here, here, here,here, and here, but I'm struggling to apply the answers to my own problem.
I managed to get this to work through trial and error and a bit of help offline. Posting the code below in case it helps anyone else in future
library(imager)
library(dplyr)
file_names <- c("VN1", "VN2", "VN3", "VN4", "VN5")
next_image <- NULL
for (i in 1:5) {
if (i == 1) {
im <- load.image("C:/Users/Ali/Desktop/VN_images/VN.png")
} else {
im <- next_image
}
df <- as.data.frame(im) %>%
mutate(colour = case_when(value == 0 ~ "black", TRUE ~ "white")) %>%
group_by(colour) %>%
mutate(value = replace(value, sample(row_number(), size = ceiling(0.05 * n()), replace = FALSE), 3))
df$value[df$value == 3 & df$colour == "black"] <- 1
df$value[df$value == 3 & df$colour == "white"] <- 0
df1 <- df[, -4]
new_image <- as.cimg(df1, dims = c(150, 100))
save.image(new_image, paste0("C:/Users/Ali/Desktop/VN_images/", file_names[i], ".png"))
next_image <- new_image
}