It is here: Under the Magical Sky

It is here…

After a year of hard work and dedication, we are pleased to announce the launch of our first book and brand new website! Under the magical is finally here!

We are very proud of the result, excited about the future and so grateful for the opportunity to make a difference.

We are deeply passionate about creativity and arts, but can’t ignore the fact that millions of children face the least stable living and learning circumstances every day. That’s why we have decided that every time you purchase at Under the Magical Sky, we will donate to those in need.

Now, we invite you all to visit our site: https://underthemagicalsky.com/

Under The Magical Sky. By Valeria Bressan and Tauno Erik

Long-exposure photography in another way

The traditional way to make long-exposure photography is to take photos with a long-duration shutter speed to sharply capture the stationary elements of images while blurring, smearing, or obscuring the moving elements. Long-exposure photography captures one element that conventional photography does not: an extended period of time. (1)

One day I watched Scott Manley video where he showed how he used video to produce long-exposure rocket launch photos. So I experimented with the code and random videos that I already had on my phone. Video is a sequence of photos and when we take the lightest part of every frame and merge it together into one image we get a result that is very similar to the traditional long-exposure technique.

One of my favourite photographers who use long-exposure photography and produces photos that look like paintings is Chris Friel. His works inspired me to make my MOVE photo series. Although I could not discover his technique secrets.

But I think using videos and OpenCV is a new way for me to experiment with ideas. For example, videos let you combine not only the lightest areas but also the darkest areas from frames. What is impossible with the traditional way.

One thing that I quickly learned is that the video should be short or your final image is completely white or black.

It’s definitely fun to make them and the result is often unpredictable.

Some quick experiments:

Gode on GitHub.

  1. Long-exposure photography
  2. https://taunoerik.art/project-type/move/
  3. https://www.cfriel.com/home
  4. https://opencv.org/
  5. https://github.com/taunoe/Valgusmaal

Continuous image capture from webcam

As part of an online course, I currently take “Computer Vision with Embedded Machine Learning” where is need to collect images to make the dataset. I modified the original code so I can use my regular Linux box and webcam, not Raspberry Pi. The programme counts down and saves images every 7 seconds. That is enough time to change the object position. It also crops and resizes images to 96×96 px size as needed.

This is my setup:

My setup

Example images from created dataset:

Dataset

And my code:

#!/usr/bin/env python3
"""
Image Capture

Displays image preview on screen.
Counts down and saves image 96*96px.
Restarts count down.
To exit press "q".

06.09.2021 Tauno Erik
"""

import cv2
import numpy as np

# Settings
file_num = 0
save_path = "./"      # Save images to current directory
file_suffix = ".png"  # Extension for image file
SECONDS_TO_COUNTDOWN = 7


def file_exists(filepath):
    """
    Returns true if file exists, false otherwise.
    """
    try:
        f = open(filepath, 'r')
        exists = True
        f.close()
    except:
        exists = False
    return exists

def get_filepath():
    """
    Returns the next available full path to image file
    """
    global file_num
    # Loop through possible file numbers to see if that file already exists
    filepath = save_path + str(file_num) + file_suffix
    while file_exists(filepath):
        file_num += 1
        filepath = save_path + str(file_num) + file_suffix

    return filepath

def main():
    countdown = SECONDS_TO_COUNTDOWN

    # Figure out the name of the output image filename
    filepath = get_filepath()

    cam = cv2.VideoCapture(0)

    # Set smaller resolution
    #cam.set(cv2.CAP_PROP_FRAME_WIDTH, 160) # 640
    #cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 120) # 480

    # Initial countdown timestamp
    countdown_timestamp = cv2.getTickCount()

    while cam.isOpened():
        # Read camera
        ret, frame = cam.read()

        # Get timestamp for calculating actual framerate
        timestamp = cv2.getTickCount()

        # Each second, decrement countdown
        if (timestamp - countdown_timestamp) / cv2.getTickFrequency() > 1.0:
            countdown_timestamp = cv2.getTickCount()
            countdown -= 1
            
            # When countdown reaches 0, break out of loop to save image
            if countdown <= 0:
                # Get new image file name
                filepath = get_filepath()
                # Save image
                cv2.imwrite(filepath, resized)
                # Start new count down
                countdown = SECONDS_TO_COUNTDOWN
                #break

        # Frame resolution
        frame_height = frame.shape[0]
        frame_width = frame.shape[1]

        # Crop center of image
        new_size = 98
        start_y = int(frame_height/2 - new_size/2)
        end_y = int(frame_height/2 + new_size/2)
        start_x = int(frame_width/2 - new_size/2)
        end_x = int(frame_width/2 + new_size/2)
        # Crop
        cropped = frame[start_y:end_y, start_x:end_x]

        # Rezise to 96*96
        resized = cv2.resize(cropped, (96,96), interpolation=cv2.INTER_CUBIC)

        # Put text only on copied image
        copy = resized.copy()
        # Draw countdown on image
        cv2.putText(copy, 
                    str(countdown),
                    (round(resized.shape[1] / 2) - 15, round(resized.shape[0] / 2)+10),
                    cv2.FONT_HERSHEY_PLAIN,
                    4,
                    (255, 255, 255))

        # Display raw camera image
        cv2.imshow('Kaamera', copy)

        # Press 'q' to exit
        if cv2.waitKey(10) == ord('q'):
            break

    # Clean up
    cam.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    print('To exit press "q"')
    main()

Original code: https://github.com/ShawnHymel/computer-vision-with-embedded-machine-learning/blob/master/1.1.3%20-%20Data%20Collection/Raspberry%20Pi/pi-cam-capture.py