Home

Search John Harvey Photo for...
Advanced Search...
Photo Search Returned 1 to 3 of 3
Restrict search - ferry AND time lapse AND: Hong Kong 1 sunset 1
New search - Related Tags: Hong Kong 527 sunset 177

Central
The time lapse started at 5:50pm at f8, 1/640th of a second ISO 100 and ended at 8:13pm at f8, 4 seconds per exposure at ISO 110. The interval was six seconds and there are 1436 images. This was shot at 14mm (as wide as it goes).
John Harvey Photo > Trips out of the Country > Hong Kong 14 > Central

Sunset Ferry Trip Stabilized
I've been trying to do this for a while - take a timelapse from the front of a ferry near sunset. While I shoot on a tripod, the resulting sequence still needs a lot of stabilization because we are on a boat!

This sequence started at 5:00pm and ended 2076 frames later at 6:43pm. Exposure went from f6.3 at 1/125th of a second to f6.3 at 1/2 of a second. The interval is 3 seconds because I learned from an earlier trip you need more intermediate frames if you want any chance to align between frames.

The script to stabilize is in python and uses OpenCV and the SIFT algorithm to do the image alignment. I use a variety of alignment masks through the sequence so I can exclude things like the clouds and ocean but also other ships moving side to side. This script writes a transforms.trf that ffmpeg can use for stabilization.

Back in Decemeber 2021, I took a ferry trip but hadn't yet figured out how to stabilize it.

import cv2 
import numpy as np
import matplotlib.pyplot as plt
import pprint
import math

f = open("transforms.trf", "w")
f.write("VID.STAB 1
")
f.write("#      accuracy = 15
")
f.write("#     shakiness = 3
")
f.write("#      stepsize = 4
")
f.write("#   mincontrast = 0.200000
")
f.write("Frame 1 (List 0 [])
")

img1 = cv2.imread('DSC_4877_FerryHg.jpg')  
mask = cv2.imread('mask2.png', cv2.IMREAD_GRAYSCALE)
Mask_5182 = cv2.imread('Mask_5182.png', cv2.IMREAD_GRAYSCALE)
mask_5725 = cv2.imread('mask_5725.png', cv2.IMREAD_GRAYSCALE)
mask_5885 = cv2.imread('mask_5885.png', cv2.IMREAD_GRAYSCALE)
mask_6670 = cv2.imread('mask_6670.png', cv2.IMREAD_GRAYSCALE)


currentMask = mask

img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

#sift
sift = cv2.SIFT_create()

keypoints_1, descriptors_1 = sift.detectAndCompute(img1,mask)

for n in range(2,2064):
    print("Frame " + str(n))
    img2 = cv2.imread("DSC_{:04d}_FerryHg.jpg".format(4876 + n)) 
    img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

    if ( (4876 + n) == 5182 ):
        currentMask = Mask_5182

    if ( (4876 + n) == 5725 ):
        currentMask = mask_5725
    
    if ( (4876 + n) == 5885 ):
        currentMask = mask_5885

    if ( (4876 + n) == 6670 ):
        currentMask = mask_6670

    keypoints_2, descriptors_2 = sift.detectAndCompute(img2,currentMask)

    #feature matching
    bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)

    matches = bf.match(descriptors_1,descriptors_2)
    matches = sorted(matches, key = lambda x:x.distance)

    countPositions = 0
    listOfPoints = ""
    for idx, val in enumerate(matches):
        distance = math.sqrt( (keypoints_2[val.trainIdx].pt[0]-keypoints_1[val.queryIdx].pt[0]) *
                         (keypoints_2[val.trainIdx].pt[0]-keypoints_1[val.queryIdx].pt[0]) + 
                        ( keypoints_2[val.trainIdx].pt[1]-keypoints_1[val.queryIdx].pt[1]) *
                         (keypoints_2[val.trainIdx].pt[1]-keypoints_1[val.queryIdx].pt[1] ) )

        if ( val.distance > 299 and idx > 10 ):
            continue
    
        print("    " + str(idx) + " " + str(distance) + " " + str(val.distance) +" (" +
                 str(keypoints_1[val.queryIdx].pt[0]) + "," + str(keypoints_1[val.queryIdx].pt[1]) +
                 ") -> (" + str(keypoints_2[val.trainIdx].pt[0]) + "," +
                 str(keypoints_2[val.trainIdx].pt[1]) + ")" )
        if( countPositions > 0 ):
            listOfPoints = listOfPoints + ","

        # https://github.com/georgmartius/vid.stab/blob/master/src/serialize.c
        #   if(fscanf(f,"(LM %hi %hi %hi %hi %hi %lf %lf", &lm.v.x,&lm.v.y,&lm.f.x,&lm.f.y,&lm.f.size,
        #    &lm.contrast, &lm.match) != 7) {
        # LM = Local Motion
        # Sample: (LM 0 0 922 424 224 0.507735 0.263512)

        listOfPoints = listOfPoints + "(LM {:0.0f} {:0.0f} {:0.0f} {:0.0f} {:0.0f} {:5.3f} {:5.3f})".format(
                -(keypoints_2[val.trainIdx].pt[0]-keypoints_1[val.queryIdx].pt[0]),
                -(keypoints_2[val.trainIdx].pt[1]-keypoints_1[val.queryIdx].pt[1]),
                keypoints_1[val.queryIdx].pt[0], keypoints_1[val.queryIdx].pt[1], 
                48,
                (300.0 - val.distance) / 300.0 , 0.6 - (300.0 - val.distance) / 1000.0)
        countPositions = countPositions + 1


    f.write("Frame {:d} (List {:d} [{}])".format(n,countPositions,listOfPoints))
    img1 = img2
    keypoints_1 = keypoints_2
    descriptors_1 = descriptors_2


f.close()


John Harvey Photo > Blogs for 2024 to 2005 > February 2023 > Sunset Ferry Trip Stabilized

Ferry To Victoria
I had a tripod, my camera bag and a whole ferry ride to wait so why not try a time lapse off the front of the ferry?

A lot of things went wrong or were hard. The sun was in the image for most of the sailing which makes the exposure a pain. The ferry is vibrating I never got a sharp image out of the sequence. Shutter speed was between 1/125 and 1/640th so I think it was the VR elements in the lens that were shaking.

The ferry is not a stable platform but the bright moving water was very attractive to the ffmpeg image stabilization. I was un-unable to stabilize past the opening sequence.

This is 962 images, all shot at f8 with an interval of 6 seconds. I started taking photos at 2:00:37pm and finished at 3:36:43pm. Sunset was probably 4:15.

To demonstrate I can learn, here is a similar ferry trip with Image stabilization working.
John Harvey Photo > Blogs for 2024 to 2005 > December 2021 > Ferry To Victoria