What Tcl-opencv
Description Tcl-opencv is a Tcl extension for OpenCV (Open Source Computer Vision Library). It is a library of programming functions mainly aimed at real-time computer vision. This extension requires OpenCV 4.5.0 or newer.
Current Release 0.13
License MIT License
Who Danilo Chang

tcl-opencv is available with the undroid distribution.

Here is a little snippet using the v4l2 (Video For Linux 2) extension with both a webcam and a loopback device and the tcl-opencv extension for image processing. The example is a rough translation of the "Cartoonifier" in chapter 1 of the book "Mastering OpenCV with Practical Computer Vision Projects". The resulting image is output into a photo image and label widget and written to a v4l2 loopback device in order to allow Firefox to use the processed image stream in video conferencing.

# Cartoonifier with OpenCV and v4l2 loopback device

package require v4l2
package require opencv

# "cv::matvar" is like set but with implicit cleanup using traces.
namespace eval cv {
    namespace export matvar
namespace import cv::matvar

# Labels with images to see what's going on.
image create photo CAM
label .img -image CAM
pack .img -side left
image create photo OUT
label .out -image OUT
pack .out -side left

# Some controls for the Cartoonifier.
scale .blur -orient vertical -from 1 -to 17 -resolution 2 -variable BLUR
pack .blur -side left
scale .lap1 -orient vertical -from 1 -to 9 -resolution 2 -variable LAP1
pack .lap1 -side left
scale .lap2 -orient vertical -from 1 -to 9 -resolution 2 -variable LAP2
pack .lap2 -side left
scale .bf1 -orient vertical -from 1 -to 10 -resolution 1 -variable BF1
pack .bf1 -side left
scale .bf2 -orient vertical -from 1 -to 10 -resolution 1 -variable BF2
pack .bf2 -side left
scale .bf3 -orient vertical -from 1 -to 10 -resolution 1 -variable BF3
pack .bf3 -side left

set BLUR 9
set LAP1 5
set LAP2 1
set BF1 9
set BF2 9
set BF3 7

# Setup loopback device, use YUV here since in FireFox does not support RGB.
v4l2 loopback /dev/video2 YUYV 320 240 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"
    if {[catch {v4l2 image $dev CAM} err]} {
        puts stderr $err
    } else {
        after cancel image_processing
        after idle image_processing

# For original camera image and processed (output) image.
matvar matcam [cv::Mat::Mat 320 240 $::cv::CV_8UC3]
matvar matout [cv::Mat::Mat 320 240 $::cv::CV_8UC3]

# Cartoonifier from chapter 1 of "Mastering OpenCV with Practical Computer Vision Projects"
proc image_processing {} {
    $::matcam fromPhoto CAM
    matvar mat1 [cv::cvtColor $::matcam $::cv::COLOR_BGR2GRAY]

    matvar mat0 [cv::medianBlur $mat1 $::BLUR]
    matvar mat1 [cv::Laplacian $mat0 $::LAP1 $::LAP2 0 $::cv::BORDER_DEFAULT]
    matvar matmask [cv::threshold $mat1 80 255 $::cv::THRESH_BINARY_INV]

    matvar mat0 [cv::resize $::matcam 160 120]
    for {set i 0} {$i < 5} {incr i} {
        matvar mat1 [cv::bilateralFilter $mat0 $::BF1 $::BF2 $::BF3]
        matvar mat0 [cv::bilateralFilter $mat1 $::BF1 $::BF2 $::BF3]
    matvar mat1 [cv::resize $mat0 320 240]

    $::matout setTo {0 0 0 0}
    $mat1 copyTo $::matout $matmask
    $::matout toPhoto OUT
    v4l2 writephoto $::LOOP OUT

# Initialize camera using 320x240 which makes enough load on my core i5.
proc init_camera {} {
    set name /dev/video0
    set dev [v4l2 open $name image_callback]
    v4l2 parameters $dev frame-rate 10 frame-size [email protected]
    v4l2 parameters $dev saturation 100
    v4l2 start $dev