reading images in r program - r

I want to read 12 images at a time in R.
I don't know how to do it. I am complete new to working on images in R.
How can I read couple of images from a folder in my system?
I am using windows10 operating system. RAM 8 gb. CORE i5 processor.
GPU is Intel(R) HD Graphics 620.
I am able to read only single image in R and that image is displaying as numeric values. I tried to convert it into raster format and then tried to print image to view the image. But I am still finding the color codes in values but not the image in print.
Can anyone help me on this?
Thanks a lot.
install.packages("magick")
library(magick)
install.packages("rsvg")
install.packages("jpeg")
library(jpeg)
img <- readJPEG("C:/Users/folder/Abc.jpg", native = FALSE)
img1 <- as.raster(img, interpolate = F)
print(img1)
I want to read couple of images at a time into R console and want to view or print images.

The suggested duplicate gives you the basics for how to read in a number of files at once, but there are a few potential gotchas, and it won't help you with displaying the images.
This first bit is purely to set up the example
library(jpeg)
library(grid)
# Create a new directory and move to it
tdir <- "jpgtest"
dir.create(tdir)
setwd(tdir)
# Copy the package:jpeg test image twice, once as .jpg and once as .jpeg
# to the present working directory
file.copy(system.file("img", "Rlogo.jpg", package="jpeg"),
to=c(file.path(getwd(), "test.jpg"), file.path(getwd(), "test.jpeg")))
Then we can list the files, either using a regex match, or choose them interactively, then read and store the images in a list.
# Matches any file ending in .jpg or .jpeg
(flist <- list.files(pattern="*\\.jp[e]?g$"))
# Interactive selection
flist <- file.choose()
jpglist <- lapply(flist, readJPEG)
To display the images I tend to use grid, but there are a number of alternatives.
grid.raster(jpglist[[1]], interpolate=FALSE)
Remove temporary directory
setwd("..")
unlink(tdir)

Related

Create document with images from different folders?

Lets say I carried out an experiment that produces lots of microscope images. I have multiple samples: Sample1, Sample2, etc. and each sample has varying amounts of images and divided into different folders.
I want to create a document which contains all images of each sample arranged neatly (ideally 1 page for every sample) so I can have an overview of my experiment. I usually do this manually on PowerPoint, but now Im producing overwhelming amounts of data and it would take too long. PPT is useful because it compresses my large image files very well, otherwise my images are over 5 GB in total.
The R packages I found that create PPT, however, only allow you to add images that have been produced in R. I could create a PDF document but then i would need to compress the images (either at the end or as i add them).
I know R isn't the ideal language for these kind of things, but its the one I know best and would appreciate any sort of suggestions/packages. Thanks!
Edit: The images are tiff files.
You can try the following:
library(officer)
library(rvg)
library(png)
doc <- officer::read_pptx()
doc <- officer::add_slide(doc,"Title and Content","Office Theme")
Picture<-readPNG(system.file("img","Rlogo.png",package="png"))
grid::grid.raster(Picture)
ggdml <- dml(grid::grid.raster(Picture))
doc <- officer::ph_with(doc, ggdml, location = officer::ph_location_type(type="body",position_right = FALSE))
print(doc, target = "test.pptx")

How to batch edit a field in a jpg EXIF header?

I am busy with some drone mapping. However, the altitude value in the images are very inconsistent between repeating flight missions (up to 120m). The program I use to stitch my drone images into a orthomosaic thinks the drone is flying underground as the image altitude is lower than the actual ground elevation.
To rectify this issue, I want to batch edit the altitude values of all my images by adding the difference between actual ground elevation and the drone altitude directly into the EXIF of the images.
e.g.
Original image altitude = 250m. Edited image altitude = 250m+x
I have found the exiftoolr R packages which allows you to read and write EXIF data through using the standalone ExifTool and Perl programs (see here: https://github.com/JoshOBrien/exiftoolr)
This is my code so far:
library(exiftoolr)
#Object containing images in directory
image_files <-dir("D:/....../R/EXIF_Header_Editing/Imagery",full.names=TRUE)
#Reading info
exif_read(image_files, tags = c("filename", "AbsoluteAltitude")) #Only interested in "filename" and "AbsoluteAltitude"
#Saving to new variable
altitude<-list(exif_read(image_files, tags=c("filename","AbsoluteAltitude")))
This is how some of the output looks like:
FileName AbsoluteAltitude
1 DJI_0331.JPG +262.67
2 DJI_0332.JPG +262.37
3 DJI_0333.JPG +262.47
4 DJI_0334.JPG +262.57
5 DJI_0335.JPG +262.47
6 DJI_0336.JPG +262.57
ext.
I know need to add x to every "AbsoluteAltitude" entry in the list, and then overwrite the existing image altitude value with this new adjusted altitude value, without editing any other important EXIF information.
Any ideas?
I have a program that allows me to batch edit EXIF Altitude, but this makes all the vales the same, and I need to keep the variation between the values.
Thanks in advance
Just a follow up from #StarGeek answer. I managed to figure out the R equivalent. Here is my solution:
#Installing package from GitHub
if(!require(devtools)) {install.packages("devtools")}
devtools::install_github("JoshOBrien/exiftoolr",force = TRUE)
#Installing/updating ExifTool program into exiftoolr directory
exiftoolr::install_exiftool()
#Loading packages
library(exiftoolr)
#Set working directory
setwd("D:/..../R/EXIF_Header_Editing")
#Object containing images
image_files <- dir("D:/..../R/EXIF_Header_Editing/Imagery",full.names = TRUE)
#Editing "GPSAltitude" by adding 500m to Altitude value
exif_call(args = "-GPSAltitude+=500", path = image_files)
And when opening the .jpg properties, the adjusted Altitude shows.
Thanks StarGeek
If you're willing to try to just use exiftool, you could try this command:
exiftool -AbsoluteAltitude+=250 <DIRECTORY>
I'd first test it on a few copies of your files to see if it works to your needs.

Create GIF or video from external jpg in R

I wanted to do something I thought simple, but... well, I failed repetitively.
I want to create a gif or a video (.avi) from pictures in a folder with R.
I can list the path and the names of the pictures (e.g. "./folder/1.jpg" "./folder/2.jpg" "./folder/3.jpg" "./folder/4.jpg" )
I just wanted to put them the one after the other and create a video or gif file (I will treat them frame by frame later, so the speed is not important)
I found a solution with SaveGIF, it works with plots in R but I didn't find the way to use it with external jpg.
Otherwise, there was this solution with image_animate "Animated graphics", but again, I didn't manage.
Do somebody already have a solution to do that?
Thank you very much for your help!
You can do it with the magick package, which gives you access to ImageMagick functions. For example, if the frames of your movie are in files named
frames <- paste0("folder/", 1:100, ".jpg")
then you would create a movie using
library(magick)
m <- image_read(frames)
m <- image_animate(m)
image_write(m, "movie.gif")
You could choose to write to other formats as well, just by changing the filename, or using other arguments to image_write().
A better solution in my oppinion is using the av package.
example:
list_of_frames <- list.files("your/path/to/directory", full.names=T)
av::av_encode_video(list_of_frames, framerate = 30,
output = "output_animation.mp4")

Save all plots already present in the panel of Rstudio

I've made different plots (more than a hundred) for a project and I haven't capture them on the way (yes it's bad , i know). Now, I need to save them all at once but without running again my script (which takes hours). Is there a way to do so within Rstudio ?
Edit: All the plot are already there and I don't want to run them again.
In RStudio, every session has a temporary directory that can be obtained using tempdir(). Inside that temporary directory, there is another directory that always starts with "rs-graphics" and contains all the plots saved as ".png" files. Therefore, to get the list of ".png" files you can do the following:
plots.dir.path <- list.files(tempdir(), pattern="rs-graphics", full.names = TRUE);
plots.png.paths <- list.files(plots.dir.path, pattern=".png", full.names = TRUE)
Now, you can copy these files to your desired directory, as follows:
file.copy(from=plots.png.paths, to="path_to_your_dir")
Additional feature:
As you will notice, the .png file names are automatically generated (e.g., 0078cb77-02f2-4a16-bf02-0c5c6d8cc8d8.png). So if you want to number the .png files according to their plotting order in RStudio, you may do so as follows:
plots.png.detials <- file.info(plots.png.paths)
plots.png.detials <- plots.png.detials[order(plots.png.detials$mtime),]
sorted.png.names <- gsub(plots.dir.path, "path_to_your_dir", row.names(plots.png.detials), fixed=TRUE)
numbered.png.names <- paste0("path_to_your_dir/", 1:length(sorted.png.names), ".png")
# Rename all the .png files as: 1.png, 2.png, 3.png, and so on.
file.rename(from=sorted.png.names, to=numbered.png.names)
Hope it helps.
Although this discussion has been inactive for a while, there are some persons, like myself, who still come across the same problem, and the other solutions don't really seem to even get what the actual question is.
So, hands on. Your plot history gets saved in a variable called .SavedPlots. You can either access it directly, assign it to another variable in code or do the latter from the plots window.
# ph for plot history
ph <- .SavedPlots
In R 3.4.2, I could index ph to reproduce the corresponding plot in a device. What follows is rather straightforward:
Open a new device (png, jpeg, pdf...).
Reproduce your plot ph[index_of_plot_in_history].
Close the device (or keep plotting if it is a pdf with multiple pages).
Example:
for(i in 1:lastplot) {
png('plotname.png')
print(ph[i])
dev.off()
}
Note: Sometimes this doesn't happen because of poor programming. For instance, I was using the MICE package to impute many datasets with a large number of variables, and plotting as shown in section 4.3 of this paper. Problem was, that only three variables per plot were displayed, and if I used a png device in my code, only the last plot of each dataset would be saved. However, if the plots were printed to a window, all the plots of each dataset would be recorded.
If your plots are 3d, you can take a snapshot of all your plots and save them as a .png file format.
snapshot3d(filename = '../Plots/SnapshotPlots.png', fmt = 'png')
Or else, the best way is to create a multi-paneled plotting window using the par(mfrow) function. Try the following
plotsPath = "../Plots/allPlots.pdf"
pdf(file=plotsPath)
for (x in seq(1,100))
{
par(mfrow = c(2,1))
p1=rnorm(x)
p2=rnorm(x)
plot(p1,p2)
}
dev.off()
You can also use png, bmp, tiff, and jpeg functions instead of pdf. You can read their advantages and disadvantages and choose the one you think is good for your needs.
I am not sure how Rstudio opens the device where the plot are drawn, but I guess it uses dev.new(). In that case one quick way to save all opened graphs is to loop through all the devices and write them using dev.print.
Something like :
lapply(dev.list(),function(d){dev.set(d);dev.print(pdf,file=file.path(folder,paste0("graph_",d,".pdf"))})
where folder is the path of the folder where you want to store your graph (could be for example folder="~" if you are in linux and want to store all your graph in your home folder).
If you enter the following function all that will follow will be save in a document:
pdf("nameofthedocument.pdf")
plot(x~y)
plot(...
dev.off()
You can also use tiff(), jpg()... see ?pdf

Create a gif from a series of Leaflet maps in R

I am looking for an automated method to convert leaflet R Studio plots into image files.
Seems like exporting a leaflet widget to HTML is straightforward (Saving leaflet output as html). However I cannot find any answers or docs about how to save the image produced by a leaflet widget as an image. It seems strange that I can do this manually in R Studio but that there isn't some function within R Studio that can be called to do the same thing.
I've tried the usual suspects, variations on the following:
png("test_png.png")
map
dev.off()
But these all just print white or print a file that can't even be opened. IF I understand this Git discussion correctly, seems like something in leaflet is not available but is desired by users.
In the meantime, R Studio clearly has a way to render this image into an image file, making me press a button to do it. Is there a way to automate this? How can I export the images plotted in R Studio to image files? I need image files and I need this to be programmatic because I want to make a gif out of a few hundred maps.
Alternately, I'd welcome suggestions for a workaround. I might try this: Python - render HTML content to GIF image but if someone has alternatibve suggestions, please share.
I've been trying to do this with a combination of the webshot package and saveWidget from htmltools, although it's pretty slow. For a few hundred maps, it's probably not too bad if you're only doing it here and there. But, for real-time application it is too slow.
There are two external applications you need for this workflow. webshot takes screenshots of webpages and requires you to install PhantomJS first (it's tiny and easy). I also use ImageMagick (and needs to be accessible from the command line) to create the .gif files, but I'm sure there many other programs you could use to make gifs.
The idea is just to create the maps in a loop, save them to a temporary html file with saveWidget and use webshot to turn it into a png (slow). Then, once you have all the pngs, use ImageMagick to convert them to a gif (fast).
Here is an example, I also load ggmap, but only to get a location to zoom in on.
library(webshot)
library(leaflet)
library(htmlwidgets)
library(ggmap)
loc <- geocode('mt everest') # zoom in everest
zooms <- seq(2,14,3) # some zoom levels to animate
## Make the maps, this will make some pngs called 'Rplot%02d.png'
## in your current directory
for (i in seq_along(zooms)) {
m <- leaflet(data=loc) %>%
addProviderTiles('Esri.WorldImagery') %>%
setView(lng=loc$lon, lat=loc$lat, zoom=zooms[i])
if (i==1)
m <- m %>% addPopups(popup="Going to see Mt Everest")
if (i==length(zooms))
m <- m %>%
addCircleMarkers(radius=90, opacity = 0.5) %>%
addPopups(popup = 'Mt Everest')
## This is the png creation part
saveWidget(m, 'temp.html', selfcontained = FALSE)
webshot('temp.html', file=sprintf('Rplot%02d.png', i),
cliprect = 'viewport')
}
Then, it is just converting pngs to gif. I did this on a Windows, so command might be slightly different on a mac/linux (I think just single quotes instead of double quotes or something). These commands are from a command line/shell, but you could also use system/system2 to call from R or try the animation package that has some wrapper functions for ImageMagick. To make a simle gif with nothing fancy is simply, convert *.png animation.gif. I used a slightly longer code to make the pngs smaller/add some delays/and have the sequence go in and out.
convert Rplot%02d.png[1-5] -duplicate 1,-2-1, -resize "%50" gif:- | convert - -set delay "%[fx:(t==0||t==4)?240:40]" -quiet -layers OptimizePlus -loop 0 cycle.gif
You can create a series of PNG files as answered by jenesaisquoi (first answer). Then create gif with the png files using the below code with magick package.
library(magick)
png.files <- sprintf("Rplot%02d.png", 1:20) #Mention the number of files to read
GIF.convert <- function(x, output = "animation.gif")#Create a function to read, animate and convert the files to gif
{
image_read(x) %>%
image_animate(fps = 1) %>%
image_write(output)
}
GIF.convert(png.files)
You don't require to install ImageMagick software on PC.
Code Link: Animation.R
I have table with 3 columns: lat,lon,day (376 days).
The process is: create the map -> save the map as HTML -> save the map as PNG -> import the pic -> plot it (with plot + ggimage)
All this process, will be in a loop
library(leaflet)
library(animation)
library(png)
library(htmlwidgets)
library(webshot)
library(ggmap)
saveGIF({
for (i in 1:376) {
map = leaflet() %>%
addTiles() %>%
setView(lng = lon_lat[1,2], lat = lon_lat[1,1], zoom = 5)%>%
addMarkers(lng = lon_lat[lon_lat$day == i,2],lat = lon_lat[lon_lat$day == i,1])
saveWidget(map, 'temp.html', selfcontained = FALSE) ## save the html
webshot('temp.html', file=sprintf('Rplot%02d.png', 1),cliprect = 'viewport') ## save as png
img = readPNG("Rplot01.png") ### read the png
plot(ggimage(img)) ###reading png file
}
})

Resources