colinrmitchell.com

Blog

Dance of the Thai Giant

Posted Thursday, October 4th 2018 in Videos - Permalink

Well, I got my time lapse photography to work pretty good using my script! Here’s the final result of my Thai giant (Colocasia gigantea) as it grew a leaf over about four days.

















Time lapse photos using a webcam

Posted Monday, October 1st 2018 in Other Tech - Permalink

I’m experimenting with using a decent Logitech webcam to take time lapse pictures of my houseplant to turn into videos. I first tried using cheese to take the pictures, but it doesn’t like to listen to your requests for the burst parameters. For example, it would take pictures more often than I had specified. This led to my video being cut off short.

So I decided to just write a script using the tried-and-true ffmpeg program. It can take single pictures using a webcam as an input easily.

#!/bin/sh

f=1

if test "$1" = "test" ; then
   ffmpeg -f video4linux2 -s 1280x720 -i /dev/video$2 -vframes 1 -f mjpeg -vf "transpose=1" - | feh -
else
   while :
   do
      echo "Frame $f"

      ffmpeg -f video4linux2 -s 1280x720 -i /dev/video$2 -vframes 1 -f mjpeg $f.jpg

      sleep $1
      f=$((f+1))
   done
fi

The script does two things. The first, if you just have “test” as a parameter, is that it will just take a single picture and pipe it to the feh image viewer so you can see how the images will look.

To use it to actually take pictures,

$ ./timelapse.sh 60 1

The first parameter is how many seconds to wait between taking photos. The second parameter is the number of the video device. In this case, we will be using the device /dev/video1. If it works, you should start seeing image files like 1.jpg, 2.jpg, etc., filling up the directory.

Once you have all of your pictures, you will want to join them together into a video file. ffmpeg can easily do this:

$ ls -t -r *.jpg 
  | awk 'NR == 1 || NR % 3 == 0' 
  | xargs cat 
  | ffmpeg -f image2pipe -pix_fmt yuvj420p -c:v mjpeg -s 1280x720 -r 30 -i - -vf "transpose=2" -r 30 out.mp4

The ls is a way to get your image file names in order. In this example, it lists them by modified date in reverse, which is chronological.

The awk command was a way to only take every three image names, in case I want the time lapse to be faster.

xargs is just a way to take the file names and pipe out their content.

The ffmpeg command actually takes the pipe of input images and creates a video file from them. The transpose filter rotates the video, as I took it in portrait with my webcam rotated ninety degrees.

Here is a test with my first set of images that cheese cut off a little early, so it’s only about 10 hours of images:


Another Battlefield 4 montage, now with more TOW!

Posted Friday, July 27th 2018 in Uncategorized - Permalink

















Haskell levmar curve-fitting example

Posted Friday, May 20th 2016 in Programming - Permalink

It took me a little while to wrap my head around the levmar package from Hackage. I was mostly confused about how the independent variables were used in the types of the levmar function parameters. I was unable to find a simple example on the internet, so I want to post one here.

This is an easy-to-use function that I wrote that will do generic curve fitting for a set of data that has one independent variable. The first parameter is a list of tuples that stands for the data points. The second parameter is an integer specifying how many parameters are present in our non-linear model. The third parameter is our model: a function that takes a set of parameters and a value to a value. The function will return the best-fit set of parameters for this function.

import qualified Numeric.LinearAlgebra.Data as LA
import Numeric.LevMar

fitCurve :: [(Double, Double)] -> Int -> (LA.Vector Double -> Double -> Double) -> LA.Vector Double
fitCurve ds pc f =
   let model ps = LA.fromList $ map (\x -> f ps x) $ map fst ds :: LA.Vector Double
       results = 
         levmar 
            model 
            Nothing 
            (LA.fromList . take pc $ cycle [1.0]) 
            (LA.fromList $ map snd ds) 
            1000 
            defaultOpts 
            mempty
   in case results of
      Left err -> error $ show err
      Right (params, _, _) -> params


List Posts Newest Posts Page 1Next Page