Giter Club home page Giter Club logo

webmorphr's Introduction

webmorphR

DOI Lifecycle: experimental Codecov test coverage R-CMD-check

The goal of webmorphR is to make the construction of image stimuli more reproducible, with a focus on face stimuli. While face stimuli used in research can often not be shared for ethical reasons, webmorphR allows you to share recipes for creating stimuli with code, increasing reproducibility and encouraging generalisability to new faces.

This development of this package was funded by ERC grant #647910 (KINSHIP).

Installation

You can install webmorphR from CRAN with:

install.packages("webmorphR")

You can install the development version from GitHub with:

# install.packages("devtools")
devtools::install_github("debruine/webmorphR")

Helper packages

There are also two helper packages that contain large demo stimulus files or functions that require python and dlib.

devtools::install_github("debruine/webmorphR.stim")
devtools::install_github("debruine/webmorphR.dlib")

Use

The code below produces the following figure reproducibly, and can be applied to any set of original images.

Load images with psychomorph/webmorph templates or automatically delineate them. Use functions like resize(), align() and crop() to process the images reproducibly. Use webmorph functions to create composite or transformed faces. Use the plotting and labelling functions to create figures.

library(webmorphR)

# load 6 images from the smiling demo set
# devtools::install_github("debruine/webmorphR.stim")
original <- webmorphR.stim::load_stim_smiling("002|013|030|064|094|099") 

# resize and delineate the images (using Face++)
# procrustes align and crop them to 80% size
processed <- original |>
  resize(0.5) |>
  auto_delin(smiling, model = "fpp106") |>
  align(procrustes = TRUE) |>
  crop(width = 0.8, height = 0.8, y_off = 0)

# rename and save individual images
processed |>
  rename_stim(prefix = "aligned_") |>
  write_stim(dir = "stimuli/smiling")

# average faces (using webmorph.org)
avg <- avg(processed)

# combine individual faces in a grid the same height as the average face
grid <- plot(processed, 
             ncol = 2, 
             external_pad = FALSE,
             maxheight = height(avg))

# draw template on the average face and add a label
tem_viz <- avg |>
  draw_tem() |>
  label(text = "Composite with Template",
        size = 30, location = "+0+10")

# combine the grid and tem_viz images and plot
c(grid, tem_viz) |> 
  plot(nrow = 1, maxwidth = 1500)

webmorphr's People

Contributors

debruine avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

webmorphr's Issues

dlib vignette

Write a vignette explaining how to use facetrain, with specifics on setting up python and dlib with reticulate

rotate origin

Add rotate_origin argument to rotate() to allow the rotation origin to be customised. It's currently the centre of the image, or the centre of the delineation points if there is no image and no width/height in the stim object.

  • default: centre of image
  • centre of template
  • specified template point
  • specified x/y coords

Would need to work out the maths for the image rotation, as magick doesn't take an origin -- add padding until new origin is the centre of the image, then remove padding.

align ref_img

Add ability to include a length-1 stimlist or stim as a ref_img in align function

Release webmorphR 0.1.0

First release:

Prepare for release:

  • devtools::build_readme()
  • urlchecker::url_check()
  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • rhub::check_for_cran()
  • Review pkgdown reference index for, e.g., missing topics
  • Push to github
  • Make sure all CI pass
  • Create Zenodo release
  • Update CITATION

Submit to CRAN:

  • usethis::use_version('minor')
  • devtools::submit_cran()
  • Approve email

Resubmit to CRAN:

  • devtools::check(remote = TRUE, manual = TRUE)
  • devtools::check_win_devel()
  • Push to github
  • Make sure all CI pass
  • devtools::submit_cran()
  • Approve email

Wait for CRAN...

  • Accepted 🎉
  • usethis::use_github_release()
  • usethis::use_dev_version()
  • Finish blog post
  • Tweet
  • Add link to blog post in pkgdown news menu

subset_tem no tem

If there are images with no tem to subset, you get the confusing error of

Error in 1:dim(oldpts)[[2]] : argument of length 0

webmorphR.dlib auto_delin() crashes

Hello, and thank you for this amazing package!

I am using webmorphR.dlib's wrapper function with the dlib70 model, to get a face model & later do some additional processing of a series of faces, saved as a stimlist.
My code worked fine for the last few months, but now for some reason it crashes.
The error I'm getting is that the function cannot open the file, but for some reason the path it tries to use to access the files is a temp dir (e.g., 'C:\Users\MAYANN~1\AppData\Local\Temp\RtmpWs7Ene\file2658bc84683/anger/edited/IMG_3679.jpg', in the last session). In the traceback, I see that the crash happened while calling magick::image_write):

`

Error in mutate(., params = purrr::map(.x = data, .f = ~get_individually_aligned_faces(.x))) :

i The error occurred in group 1: image_id = "36".
Caused by error in purrr::map():
i In index: 1.
Caused by error in file():
! cannot open the connection

  1. | stop(fallback)
    -- | --
`

Here is my code:
`get_individually_aligned_faces <- function(x)
{
stimuli <- read_stim(x$path)
face_model <- auto_delin(stimuli, "dlib70", replace = T) # get faces dlib70 model
dtmp <- draw_tem(face_model) |> plot() # draw face template from model
patch_fill <- patch(face_model, width = 1, height = 10) # get the background color of the face image, to be used when adjusting the face location
horized <- face_model |> horiz_eyes(fill = patch_fill) # align by eyes
horized_plot <- horized |> plot()
aligned <- face_model |> horiz_eyes(fill = patch_fill) |> align(procrustes = TRUE, fill = patch_fill) # align using procrustes (average location of all images)
aligned_plot <- aligned |> plot()
stim_list <- list(fm = face_model,tmp = dtmp,hrz = horized,hrzplot = horized_plot,alg = aligned,algplot = aligned_plot) # save everything
}

aligned_df <- conditions_list %>% mutate(params = purrr::map(.x = data, .f = ~get_individually_aligned_faces(.x))) %>% unnest_wider(params) `

An example path from conditions_list (a nested list) is:
`

C:/Users/Mayan Navon/Google Drive/School/postdoc/niv reggev/face_stims_morphing/stims_to_check_alignment/eng/36/anger/edited

 


`

Any ideas why this happens and how to fix this issue?

Thanks!!
Mayan

write_stim with same names

If stim in a stimlist have the same name, they will overwrite each other on write_stim.

Add a check or auto-handling.

alt text

Add alt text to all documentation on the website

"# install.packages" ?

Installation
You can install the development version from [GitHub](https://github.com/) with:
# install.packages("devtools")

Yes, I'm ignorant about R, and I've jumped into the thick of it as I often do. To me, the '#' before that command means it needs to be entered at the Linux prompt with sudo... Does it mean something else to R fans? I don't see it in other instructions...

Quickly learned that didn't work. But I got confusing messages entering the command in R as well. Turns out devtools is not installed with R, and after hours of trying to install it showed:

ERROR: dependencies ‘usethis’, ‘httr’, ‘rcmdcheck’, ‘roxygen2’, ‘rversions’ are not available for package ‘devtools’
* removing ‘/home/pi/R/arm-unknown-linux-gnueabihf-library/4.0/devtools’
There were 12 warnings (use warnings() to see them)

I then found the remotes package, which installed relatively quickly and downloaded webmorphR, but it choked compiling Rcpp. Maybe we just can't do this on a Raspberry Pi?

(I love learning new things...)

Hmmm... Still building webmorphR, and getting lots of reports like:

/usr/include/c++/10/bits/vector.tcc:426:7: note: parameter passing for argument of type ‘std::vector<Catch::SectionEndInfo>::iterator’ changed in GCC 7.1
  426 |       vector<_Tp, _Alloc>::
      |       ^~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/vector:67,
                 from testthat/vendor/catch.h:671,
                 from testthat/testthat.h:65,
                 from test-runner.cpp:8:

Do those mean this isn't going to work even if it does eventually finish? Does it require some specific version of GCC that isn't automatically selected?

webmorphR.dlib auto_delin() error in matrix dimensions

Hi,
I'm using the auto_delin function with the dlib70 model.
I wrote this wrapper function:

get_individually_aligned_faces <- function(x)
{
  stimuli <- read_stim(path = x$path, pattern = c("-A\\.","-HC\\.","-HO\\.","-N\\.","-S\\.")) # filter out "NM" (neutral with covid mask) images, by providing specific patterns
  face_model <- auto_delin(stimuli, "dlib70", replace = F) # get faces dlib70 model 
  dtmp <- draw_tem(face_model) |> plot() # draw face template from model
  patch_fill <- patch(face_model, width = 1, height = 10) # get the background color of the face image, to be used when adjusting the face location
  horized <- face_model |> horiz_eyes(fill = patch_fill) # align by eyes
  horized_plot <- horized |> plot()
  aligned <- face_model |> horiz_eyes(fill = patch_fill) |> align(procrustes = TRUE, fill = patch_fill) # align using procrustes (average location of all images)
  aligned_plot <- aligned |> plot()
  stim_list <- list(fm = face_model,tmp = dtmp,hrz = horized,hrzplot = horized_plot,alg = aligned,algplot = aligned_plot) # save everything
}

And I'm calling it for different subsets of images using purrr::map (actually, within each subset, I have 4 or 5 images for each face identify that are saved in the same directory and are called from the same path on each run of my function).

For some reason, the auto_delin function runs fine for some subsets of images, but not for others. I'm getting the following error, suggesting there's a problem with creating a matrix for some of the images (in this case, image F-061):
Error in mutate():
! Problem while computing params = purrr::map(.x = data, .f = ~get_individually_aligned_faces(.x)).
ℹ The error occurred in group 10: image_id = "F-061".
Caused by error in purrr::map():
ℹ In index: 1.
Caused by error in matrix():
! length of 'dimnames' [2] not equal to array extent
Backtrace:

  1. ... %>% unnest_wider(params)
  2. purrr::map(.x = data, .f = ~get_individually_aligned_faces(.x))
  3. purrr:::map_("list", .x, .f, ..., .progress = .progress)
  4. .f(.x[[i]], ...)
  5. global get_individually_aligned_faces(.x)
  6. webmorphR.dlib::auto_delin(stimuli, "dlib70", replace = F)
  7. webmorphR.dlib::dlib_auto_delin(stimuli, model, replace, model_path)
  8. base::matrix(...)

All images come from the same database (the subsetting is just for easier debugging) and are of the same file type (JPG). Within each subset, there are the same number of files (either 4 or 5) per face identity.

Any suggestions?
Thanks.

"Webmorph.org can't be reached" error when using functions like avg()

Hi,

I can't run functions listed under "Webmorph" in the documentation like avg() - I get the following error:

Error in avg(processed) : 
  Webmorph.org can't be reached. Check if you are connected to the internet.

I'm guessing this is because webmorph.org is down as I can't access the website. Is there a workaround for being able to these functions until the website is back up?
Any help is appreciated!

The code I'm using is the one provided in the README.md file - so this is what I have:

```{r}
library(webmorphR)
# load 6 images from the smiling demo set
# devtools::install_github("debruine/webmorphR.stim")
original <- webmorphR.stim::load_stim_smiling("002|013|030|064|094|099") 
# resize and delineate the images (using Face++)
# procrustes align and crop them to 80% size
processed <- original |>
  resize(0.5) |>
  auto_delin(original, model = "fpp106") |>
  align(procrustes = TRUE) |>
  crop(width = 0.8, height = 0.8, y_off = 0)

# rename and save individual images
processed |>
  rename_stim(prefix = "aligned_") |>
  write_stim(dir = "stimuli/smiling")

# average faces (using webmorph.org)
avg <- avg(processed)

speed tests

benchmark speed of functions for stimlists of different image sizes and lengths

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.