Version 1 of How to make anaglyph using v4l2 loopback

Updated 2021-07-31 18:56:07 by chw

Anaglyph is a rather old mechanism to make a 3D stereoscopic effect using color filters for the left and right eyes, e.g. red and cyan. Given two video cameras with proper eye distance which are two distinct v4l2 devices, the v4l2 extension can be used with its support of loopback devices to make another third virtual anaglyph 3d camera which delivers the red/cyan mixture of the two real cameras. If you use red/cyan glasses when viewing that device's output, you'll see a stereoscopic image. Here is the script which only needs a tclsh (no Tk required):

# Make anaglyph of a stereo camera and send
# resulting frames into v4l2 loopback device

package require v4l2

# Setup loopback device, use YUV here since
# jitsi.org in FireFox does not support RGB.
v4l2 loopback /dev/video2 YUYV 640 480 25

# Open loopback device for later writes
set loop [v4l2 open /dev/video2 #no-image-callback]

# Callback: image ready or error
proc image_callback {dev ind} {
    if {$ind eq "error"} {
        puts stderr "acquisition error, exiting"
        set ::forever 0
    }
    # Fetch image
    set n $::devs($dev)
    set ::imgs($n) [v4l2 image $dev]
    # When both images available, combine to anaglyph
    # and output on loopback device
    catch {
        lassign $::imgs(0) width0 height0 bpp0 img0
        lassign $::imgs(1) width1 height1 bpp1 img1
        v4l2 mbcopy $img1 $img0 0x00ff0000
        if {$n == 1} {
            v4l2 write $::loop $img1
        }
    }
}

# Initialize cameras
proc init_cameras {} {
    set count 0
    # Find cameras by friendly name
    foreach name [glob -nocomplain /dev/v4l/by-id/*Stereo_Vision*] {
        set dev [v4l2 open $name image_callback]
        # Use MJPEG, otherwise USB 2.0 bandwidth is insufficient
        v4l2 parameters $dev frame-rate 25 frame-size [email protected]
        set ::devs($dev) $count
        incr count
        if {$count > 1} {
            break
        }
    }
    if {$count != 2} {
        puts stderr "need two cameras"
        exit 1
    }
    # Start both cameras
    foreach dev [array names ::devs] {
        v4l2 start $dev
    }
}

init_cameras

# Need an event loop for operation
vwait forever

What is it good for? By using the loopback device, I will hopefully be 3-dimensional in the next virtual TUGM meeting for which we use Jitsi .