Use Your 3D-Capable TV to View 3D Stills of Your Own Making

by TFE Guy (a.k.a. The Man)

I bought my Samsung TV because the price was right for the plasma technology and size I was looking for.

It came 3D-capable but, since taking advantage of this required extra "smart" glasses, I didn't bother using the 3D mode for a long time.  Eventually, I did buy my first 3D movie and the Samsung glasses.  I pressed the "3D" button of the TV remote for the first time and, for a few hours, I was a little boy again.

Here is how 3D works: in all cases where 3D is shown in the TV, two similar-but-not-identical frames are shown on the screen almost simultaneously; the left and right channels actually alternate at a frequency of 60 Hz.

When the viewer wears the specially-designed glasses and turns them on, the glasses synchronize with the TV (through an IR link) and - magically - perspective appears out of the flat screen.  What happens is that by blocking the light going to the right eye and then left eye, successively, the glasses trick the brain into merging the two channels in one 3D scene.

There are a few ways to get 3D content out of the TV set.  An appropriate HDMI cable, for one, has enough bandwidth to carry Blu-ray content at full-resolution (1920x1080, times two channels) between two compatible units, exempli gratia a disc player and a TV.  The technology behind this is proprietary.

In another mode, the TV can transform 2D content to an "apparent 3D" in real time.

It does this by using an impressive set of (proprietary again) algorithms.  The illusion from this mode is nice, particularly for watching sports, but it does not equal the pleasure of watching something filmed with two actual viewpoints.

Spending a little more time with the "3D" button on the remote, I saw that there was yet another way to produce 3D scenes.

This mode is called "side-by-side."  In this mode, the two halves of a specially-crafted 2D image are made from two slightly different camera angles.  The picture can be from a regular AVI where the left-half shows the left channel, and the right-half shows the right channel.

When such an image is displayed and the side-by-side 3D is activated, the TV separates the picture, stretches each half to full-width and shows the two channels alternatively in fullscreen.  Voilá;, 3D content with the glasses from a generic AVI!

I now wanted to take further advantage of my 3D TV.

As it can be based on regular file formats, I realized that Side-by-Side (SBS) content would no doubt be more accessible from the Internets than something based, for example, on Blu-ray support.

A search through torrent sites using the keyword "SBS" proved this theory right.  Most results, however, revolved around one particular area of artistic expression: pr0n.  Nothing much to show off 3D capabilities with, especially to friends and family!

Being an amateur photographer, I immediately saw the potential for showing my own still photographs, in 3D, by using the side-by-side mode of the TV.  I could become a 3D artist!

So I grabbed the camera and took a few shots of my first subject: my desk chair.

I tried as best I could to simulate left eye and right eye viewpoints.  With the files were transferred to the computer, I opened two instances of the excellent JPEGView in "Windowed mode" and put them side-by-side on the TV.

With a little tweaking of the windows' positions, I managed to get a decent scene in 3D!  Happy to have proved that this scheme could work, I next tried to make the image perfectly fit the standard, in extenso by displaying in two equal halves of the screen based on a single JPEG file.

Back to photography, it took a few rounds of trial-and-error to realize that if I used too much distance between the two camera positions, the end effect in 3D was really bad.  Also, you will want to avoid the camera's on-board flash for lighting, as otherwise you will confuse your brain with inappropriate shadows for objects (namely).

What was most time consuming was that each time I took a pair of pictures, I had to assemble them manually using GIMP to get a 1920x1080 SBS picture, stretch and all.

Sometimes the work could be all for nothing but proving the source files produce a disappointing result when combined.  It became obvious that if the picture assembly work could be automated, there would be huge benefits in ease of production and eventually faster, better results.

Eventually I achieved a result that I was really proud of.

It was quite a feeling to turn the glasses on, flip the TV mode to 3D, and see my own multi-depth photographic creation.  My first impressive result was a portrait of my oldest son, 12 years old - what a precious binary file I had just made, for the ages!

I wanted more of these kinds of pictures, so I figured GIMP scripting could come in the picture (pun intended).

GIMP is a fabulously powerful image editor, and it's free.  It supports scripting in Scheme and Python, and this is what was used to make the rest of this project possible.

GIMP has been around for almost 20 years.  As such, it benefits from a large enthusiasts' base and a strong support community.  With information available on gimpforums.com and the help of some folks there, I got basic knowledge of GIMP scripting and produced the script below.

The script asks for two file names and joins the pictures in a perfect 3D SBS format.

Obviously, there is lots of other fun to be had with this new way of doing photography!

Viva 3D SBS!

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# File name: 3DMaker.py

# Produce a 3D SBS image from two stills
# WARNING: This script is written for Windoze
#          and needs adaptation for Linux, see below.

from gimpfu import *
import os

# Function to crop to 16:9 if necessary, centered
def cropper( image ):
# Record original dimensions
    w_orig = image.width
    h_orig = image.height
   
# Target ratio
    ratio = 16.0 / 9.0

# Compare picture to target ratio
# If image is too high or too wide, need to crop (centered)
# If ratio is ok, keep all pixels
    if (w_orig / h_orig) < (ratio - 0.00001):
        w_new = w_orig
        h_new = int(w_orig / ratio)
        offx = 0
        offy = int((h_orig - h_new) / 2)
    elif (w_orig / h_orig) > (ratio + 0.00001):
        w_new = int(h_orig * ratio)
        h_new = h_orig
        offx = int((w_orig - w_new) / 2)
        offy = 0
    else:
        w_new = w_orig
        h_new = h_orig
        offx = 0
        offy = 0
   
    pdb.gimp_image_crop( image, w_new, h_new, offx, offy )
   
    return

# Function to rescale to half-width of 1920 x 1080, distorting image
def resizer( image ):
    pdb.gimp_image_scale( image, 960, 1080 )
   
    return
   
# The registered script called by main()
# Sorry it's not more Pythonic
def threedmaker( full_filename_left, full_filename_right ) :

# Left image load
    image_left = pdb.gimp_file_load( full_filename_left, full_filename_left )
    display_left = gimp.Display( image_left )

# Record path information, compute new file's filename
    folder_left = os.path.dirname( os.path.abspath( full_filename_left ) )
    filename_left_new = "3D SBS_" + pdb.gimp_image_get_name( image_left )

# Right image load
    image_right = pdb.gimp_file_load( full_filename_right, full_filename_right )
    display_right = gimp.Display( image_right )

# Prepend "3D SBS_" to left image filename, this is how the final file will be saved
    pdb.gimp_image_set_filename( image_left, filename_left_new )

# Crop the images if necessary
    cropper( image_left )
    cropper( image_right )

# Resize (reduce dimensions) each image to 1080p
    resizer( image_left )
    resizer( image_right )

# We will work from the left image; we will copy to right image in the left image's container
# Copy right image to memory and paste in left image's container
    pdb.gimp_edit_copy( pdb.gimp_image_get_active_drawable( image_right ) )

# Increase canvas size and paste in data from right image
    pdb.gimp_image_resize( image_left, 1920, 1080, 0, 0 )
    layer_work = pdb.gimp_image_get_active_layer( image_left )
    floating_sel = pdb.gimp_edit_paste( pdb.gimp_image_get_active_drawable( image_left ), TRUE )

# Move right image pixels to appropriate position
    pdb.gimp_layer_resize( layer_work, 1920, 1080, 0, 0 )
    pdb.gimp_layer_translate( floating_sel, 960, 0 )

# Merge layers
    pdb.gimp_image_flatten( image_left )

# Save new picture in left image's original folder
# WARNING: For Linux, the directory separator is written with a single forward slash '/'
    pdb.gimp_file_save( image_left, pdb.gimp_image_get_active_drawable( image_left ), folder_left + "\\" + filename_left_new,  folder_left + "\\" + filename_left_new )

# End of script, free memory
    pdb.gimp_display_delete( display_right )
    pdb.gimp_image_delete( image_right )
    pdb.gimp_display_delete( display_left )
    pdb.gimp_image_delete( image_left )

    return

# This is the plugin registration function
register(
    "threedmaker_script",
    "Merges two images into one fitting 3D SBS standard",
    "Merges two images (left eye and right eye views) in one 3D side-by-side image",
    "TFE Guy a.k.a. The Man",
    "TFE Guy a.k.a. The Man a la maison",
    "Aout 2014",
    "<Toolbox>/MyScripts/3D Maker...",
    "",
    [
# WARNING: For Linux, the directory separator is written with a single forward slash '/'
      (PF_FILENAME, 'string_left', 'Path\\image for left eye', 'C:\\Photos\\left.JPG'),
      (PF_FILENAME, 'string_right', 'Path\\image for right eye', 'C:\\Photos\\right.JPG')
    ],
    [],
    threedmaker,
    )

main()

Code: 3DMaker.py

Return to $2600 Index