Thursday, November 30, 2017

v1.6: New video tools added to StereoMorph

StereoMorph version 1.6 is now available on CRAN! It actually first became available back in March of this year...but I have been busy and fallen behind on updates - my sincerest apologies! With version 1.6 I have started to incorporate features to make it easier to use StereoMorph with video, particularly from GoPro cameras. This came about through a collaborative project just published this past summer with Caine Delacy, Mark Bond, and others in which we used StereoMorph to collect 3D length data from free-swimming oceanic whitetip sharks. It was a fantastic collaboration and I'm very grateful to Caine for reaching out to include me in the study. You can find our paper here!

Identifying landmarks in a frame from a GoPro video of a free-swimming oceanic whitetip shark. StereoMorph v1.6.1 includes functions to extract video frames and use these to calibrate video cameras for 3D measurements of moving objects.
Here are the key updates with version 1.6:


I have edited previous posts of this blog to point users to the new corresponding tutorial webpages. I want to make sure anyone that ends up on this site has access to the most up-to-date instructions. From now on I will use this site to announce StereoMorph updates and answer user questions (using the comments below). I'll use my github site to host tutorial pages so that I can keep them updated.

Wednesday, March 16, 2016

v1.5: New tutorial and updates to digitizing app, stereo calibration, and reconstruction

StereoMorph version 1.5 is now available on CRAN! Version 1.5 comes with a brand new PDF tutorial (3 MB), example project (download; 18 MB), and includes several major updates to streamline the stereo digitization and reconstruction workflow and improve function performance. The tutorial steps laid out in early posts to this blog have been updated in the new tutorial so please refer to the new tutorial linked above. This version should also be entirely back compatible with previous versions; most of the new features are available as new functions.

New drop-down navigation and 'settings' options in StereoMorph v1.5
General updates in v1.5:

  • Faster and more robust checkerboard corner detection
  • Shortcuts to facilitate manual digitization of consecutive video frames
  • New digitizing interface with a dropdown menu to easily move among photographs
  • Improved cross-browser compatibility

Updates in v1.5 for stereo digitizing and reconstruction:

  • New digitizing interface that allows easy navigation among different aspects and views
  • The ability to project the epipolar line in the digitizing app
  • Faster and more robust curve reconstruction
  • A simpler workflow overall
  • A single function (calibrateCameras) for stereo camera calibration, including checkerboard corner detection and error assessment
  • A single function (digitizeImages) for digitizing stereo image sets, including multiple specimens
  • A single function (reconstructStereoSets) that reconstructs landmarks and curves, places a specified number of evenly spaced points on each curve, and unifies landmarks/curves
  • A single function (reflectMissingShapes) to reflect missing bilateral landmarks/curves in a series of shape sets
  • A single function (alignShapesToMidline) to align a set or sets of bilateral landmarks/curves to the midline plane
  • A single function (testCalibration) to test stereo calibration accuracy
Many thanks to the community for your feedback! Comments/questions/complaints welcome!

Wednesday, April 8, 2015

v1.4: Updates to Digitizing Application, Scaling for 2D morphometrics

StereoMorph version 1.4 just became available today on CRAN! I've made several improvements to the digitizing application based on user suggestions, particularly for 2D morphometrics.

New options in the 'Settings' panel in StereoMorph v1.4.
Users can now copy landmarks and curves from the current image to the next one, which makes it easier to digitize consecutive image frames from a video. Users can apply scaling directly in the app by digitizing points on a ruler or having the app automatically detect a checkerboard.

New 'Scaling' panel available in StereoMorph v1.4
Lastly, all of the shape and scaling data for an image can now be saved in a single text file and read into R using a single function (readShapes).

To demonstrate how to use the app, including these new features, I've made a new tutorial using different coffee mugs as an example. The tutorial is available as a PDF and you can download the example folder here (300KB).

The next updates will be to streamline 3D data collection using this same single file format. This should reduce the number of different folders that have to be created.

Saturday, April 5, 2014

Auto-detecting checkerboard corners

This is step 2 of 10 in the tutorial Collecting 3D shape data using StereoMorph

Given a photograph of a checkerboard pattern,


the findCheckerboardCorners() function in the StereoMorph package (v1.2 and higher) can automatically detect the internal corners of the checkerboard


and return these as a series of pixel coordinates to sub-pixel resolution (currently, this function only works with JPEG images).

              [,1]     [,2]
    [1,]  575.1566 387.9233
    [2,]  755.2105 395.1164
    [3,]  935.8325 402.5703
    [4,] 1115.8718 411.0474
    ...

Automated detection of the corners of a checkerboard pattern in a photograph will be used multiple times in this tutorial: to measure the size of checkerboard squares in real-world coordinates, to calibrate a set of cameras in stereo and to test the calibration accuracy. Automated corner detection can also be used to scale photographs for tasks such as 2D morphometrics, eliminating the need to manually digitize a series of points along a ruler.

1. Start by specifying the number of internal corners in the checkerboard. Note that the number of internal corners is not the number of squares but rather the number of corners where black squares adjoin one another. All the checkerboards used in this tutorial have 294 internal corners arranged in a 21 x 14 grid.

> nx <- 21
> ny <- 14

Which number you assign to nx versus ny is arbitrary, so long as you are consistent throughout.

2. Specify the location of the image to be read, the location where the corners should be saved and where to save a “verify image”. The verify image is a copy of the input image with the corners drawn in so that you can check that the correct corners were found and determine in what order they were read (the corner.file and verify.file arguments are optional).

> image.file <- 'Calibration images/v1/DSC_0002.JPG'
> corner.file <- 'Calibration corners/v1/DSC_0002.txt'
> verify.file <- 'Calibration images verify/v1/DSC_0002.JPG'

3. Call findCheckerboardCorners().

> corners <- findCheckerboardCorners(image.file=image.file, nx=nx, ny=ny, corner.file=corner.file, verify.file=verify.file)

Since print.progress argument to findCheckerboardCorners() is TRUE by default, the progress of the function will be returned to the R console. Since corner detection can take several seconds per image, this allows users to track the progress of the function. Whether the expected number of internal corners were found will also be reported to the R console.

You might have images for which findCheckerboardCorners() was unable to find the corners either because of lighting issues or because the checkerboard was at a very oblique orientation. If these are the calibration images, don’t worry – the corners do not have to be found in every image pair for an accurate calibration (at least five images should provide a good calibration). The unsuccessful images will be ignored in subsequent steps. Note that the function assumes, by default, that the checkerboard squares in the image have a perimeter of at least 140 pixels (35 x 35 pixels).

The corners are returned and saved into the variable corners as a matrix with 294 rows and 2 columns. The corners are found to sub-pixel resolution by using information from a 23 x 23 square surrounding each corner to find a more exact corner point.

> corners
          [,1]     [,2]
[1,]  575.1566 387.9233
[2,]  755.2105 395.1164
[3,]  935.8325 402.5703
[4,] 1115.8718 411.0474
...


The order of the returned corners is important for calibrating cameras in stereo and for testing their accuracy. Between the two views and from photo to photo, the corners must be found in the same order. In this way, a corner in a particular row of the matrix will always correspond to the same corner on the checkerboard.

findCheckerboardCorners() will nearly always return the corners in the same order from photo to photo as long as the checkerboard is imaged in a similar orientation. The function looks for the top-left corner relative to the center of the checkerboard. The corners are then ordered first along the nx dimension and secondly along the ny dimension (this is why it is important that nx differs from ny ). This can be verified by checking the verification image (example below) in which the first corner is indicated by a red circle, the last by a blue circle and all intermediate corners are connected by a green line (easy to remember as RGB).
The verification image indicating the found corners and the order in which they were found. The first corner is circled in red, the last in blue with intermediate points connected by green lines.
4. To find the checkerboard corners in multiple images, specify either a folder or a vector of files for image.file, corner.file and verify.file.

> image.file <- 'Calibration images/v1'
> corner.file <- 'Calibration corners/v1'
> verify.file <- 'Calibration images verify/v1'


The function will read all of the images in the folder(s) specified by image.file and the names of the images will be used to name the corner and verification images (with the proper file extensions). In this case, all files in the image.file folder(s) must be images.

5. Then call findCheckerboardCorners() just as before.

> corners <- findCheckerboardCorners(image.file=image.file, nx=nx, ny=ny, corner.file=corner.file, verify.file=verify.file)

Since 8 images are in the image.file folder, the function outputs an array of corners with the dimensions 294 x 2 x 8. The first matrix of corners can be obtained as follows.

> corners[, , 1]
          [,1]     [,2]
[1,]  575.1566 387.9233
[2,]  755.2105 395.1164
[3,]  935.8325 402.5703
[4,] 1115.8718 411.0474
...


In the next step we’ll use findCheckerboardCorners() to measure the printed size of the squares in a checkerboard pattern.

Go to the next step: Measuring checkerboard square size
Go back to the previous step: Creating a checkerboard pattern