Radeon LoomShell reference#
LoomShell is an interpreter that enables stitching 360 degree videos using a script. It provides direct access to Live Stitch API by encapsulating the calls to enable rapid prototyping.
Command-line Usage#
% loom_shell.exe [-v] [-help] [script.lss]
Available Commands#
~ context creation
    ls_context context;
    context = lsCreateContext();
    lsReleaseContext(&context);
~ rig and image configuration
    rig_params rig_par = {yaw,pitch,roll,d};
    camera_params cam_par = { {yaw,pitch,roll,tx,ty,tz},{hfov,haw,r_crop,du0,dv0,lens_type,k1,k2,k3} };
    lsSetOutputConfig(context,format,width,height);
    lsSetCameraConfig(context,rows,columns,format,width,height);
    lsSetOverlayConfig(context,rows,columns,format,width,height);
    lsSetCameraParams(context,index,&cam_par);
    lsSetOverlayParams(context,index,&cam_par);
    lsSetRigParams(context,&rig_par);
    showOutputConfig(context);
    showCameraConfig(context);
    showOverlayConfig(context);
    showRigParams(context);
~ import/export configuration
    showConfiguration(context,"exportType");
    lsExportConfiguration(context,"exportType","fileName");
    lsImportConfiguration(context,"importType","fileName");
~ LoomIO configuration
    lsSetCameraModule(context,"module","kernelName","kernelArguments");
    lsSetOutputModule(context,"module","kernelName","kernelArguments");
    lsSetOverlayModule(context,"module","kernelName","kernelArguments");
    lsSetViewingModule(context,"module","kernelName","kernelArguments");
    showCameraModule(context);
    showOutputModule(context);
    showOverlayModule(context);
    showViewingModule(context);
~ initialize and schedule
    lsInitialize(context);
    lsScheduleFrame(context);
    lsWaitForCompletion(context);
    run(context,frameCount);
    runParallel(contextArray,contextCount,frameCount);
~ image I/O configuration (not supported with LoomIO)
    lsSetCameraBufferStride(context,stride);
    lsSetOutputBufferStride(context,stride);
    lsSetOverlayBufferStride(context,stride);
    lsSetCameraBuffer(context,&buf[#]|NULL);
    lsSetOutputBuffer(context,&buf[#]|NULL);
    lsSetOverlayBuffer(context,&buf[#]|NULL);
    showCameraBufferStride(context);
    showOutputBufferStride(context);
    showOverlayBufferStride(context);
~ OpenCL/OpenVX contexts
    cl_context opencl_context;
    vx_context openvx_context;
    lsGetOpenCLContext(context,&opencl_context);
    lsGetOpenVXContext(context,&openvx_context);
~ OpenCL buffers
    cl_mem buf[count];
    createBuffer(opencl_context,size,&buf[#]);
    releaseBuffer(&buf[#]);
~ load/save OpenCL buffers
    saveBufferToImage(buf[#],"image.bmp",format,width,height,stride);
    loadBufferFromImage(buf[#],"image.bmp",format,width,height,stride);
    saveBufferToMultipleImages(buf[#],"image%02d.bmp",rows,columns,format,width,height,stride);
    loadBufferFromMultipleImages(buf[#],"image%02d.bmp",rows,columns,format,width,height,stride);
    loadBuffer(buf[#],"image.bin"[,offset]); // default: 0
    saveBuffer(buf[#],"image.bin"[,flags]); // flags: 0:write 1:append, deault: 0
~ OpenVX/OpenVX contexts (advanced)
    createOpenCLContext("platform","device",&opencl_context);
    createOpenVXContext(&openvx_context);
    lsSetOpenCLContext(context,opencl_context);
    lsSetOpenVXContext(context,openvx_context);
    releaseOpenCLContext(&opencl_context);
    releaseOpenVXContext(&openvx_context);
~ attributes (advanced)
    setGlobalAttribute(offset,value);
    showGlobalAttributes(offset,count);
    saveGlobalAttributes(offset,count,"attr.txt");
    loadGlobalAttributes(offset,count,"attr.txt");
    setAttribute(context,offset,value);
    showAttributes(context,offset,count);
    saveAttributes(context,offset,count,"attr.txt");
    loadAttributes(context,offset,count,"attr.txt");
~ components (advanced)
    showExpCompGains(context,num_entries);
    loadExpCompGains(context,num_entries,\"gains.txt\");
    saveExpCompGains(context,num_entries,\"gains.txt\");
~ miscellaneous
    help
    include "script.lss"
    exit
    quit
Parameter  | 
Description  | 
|---|---|
format  | 
buffer format: VX_DF_IMAGE_RGB, VX_DF_IMAGE_UYVY, VX_DF_IMAGE_YUYV, VX_DF_IMAGE_RGBX  | 
width  | 
buffer width in pixel units  | 
height  | 
buffer height in pixel units  | 
rows  | 
number of image tile rows inside the buffer (veritical direction)  | 
columns  | 
number of image tile columns inside the buffer (horizontal direction)  | 
index  | 
camera or overlay index  | 
yaw  | 
yaw in degrees  | 
pitch  | 
pitch in degrees  | 
roll  | 
roll in degrees  | 
d  | 
reserved (should be zero)  | 
tx  | 
reserved (should be zero)  | 
ty  | 
reserved (should be zero)  | 
tz  | 
reserved (should be zero)  | 
lens_type  | 
ptgui_lens_rectilinear, ptgui_lens_fisheye_ff, ptgui_lens_fisheye_circ, adobe_lens_rectilinear, or adobe_lens_fisheye  | 
haw  | 
horizontal active pixel count  | 
hfov  | 
horizontal field of view in degrees  | 
k1,k2,k3  | 
lens distortion correction parameters  | 
du0,dv0  | 
optical center correction in pixel units  | 
r_crop  | 
crop radius in pixel units  | 
importType  | 
supported values: pts  | 
exportType  | 
supported values: pts, loom_shell  | 
frameCount  | 
number of frames to process (for live capture, use 0)  | 
size  | 
size of a buffer in bytes  | 
stride  | 
stride of an image inside buffer in bytes  | 
platform  | 
OpenCL platform name or platform index (default: 0)  | 
device  | 
OpenCL device name or device index (default: 0)  | 
module  | 
LoomIO plug-in: OpenVX module name  | 
kernelName  | 
LoomIO plug-in: OpenVX kernel name  | 
kernelArguments  | 
LoomIO plug-in: custom kernel arguments  | 
offset  | 
start index of an attribute  | 
count  | 
number of attributes  | 
value  | 
value of attribute  | 
contextCount  | 
number of stitch instances in context[] allocated using   | 
Example #1: Simple Example#
Let’s consider a 360 rig that has three 1080p cameras with circular fishEye lenses. The following example demonstrates how to stitch images from these cameras into a 4K equi-rectangular buffer.
# define camera orientation and lens parameters
camera_params cam1_par = { { 120,0,90,0,0,0},{176,1094,547,0,-37,ptgui_lens_fisheye_circ,-0.1719,0.1539,1.0177} };
camera_params cam2_par = { {   0,0,90,0,0,0},{176,1094,547,0,-37,ptgui_lens_fisheye_circ,-0.1719,0.1539,1.0177} };
camera_params cam3_par = { {-120,0,90,0,0,0},{176,1094,547,0,-37,ptgui_lens_fisheye_circ,-0.1719,0.1539,1.0177} };
# create a live stitch instance and initialize
ls_context context;
context = lsCreateContext();
lsSetOutputConfig(context,VX_DF_IMAGE_RGB,3840,1920);
lsSetCameraConfig(context,3,1,VX_DF_IMAGE_RGB,1920,1080*3);
lsSetCameraParams(context, 0, &cam1_par);
lsSetCameraParams(context, 1, &cam2_par);
lsSetCameraParams(context, 2, &cam3_par);
lsInitialize(context);
# Get OpenCL context and create OpenCL buffers for input and output
cl_context opencl_context;
cl_mem buf[2];
lsGetOpenCLContext(context,&opencl_context);
createBuffer(opencl_context,3*1920*1080*3, &buf[0]);
createBuffer(opencl_context,3*3840*1920  , &buf[1]);
# load CAM00.bmp, CAM01.bmp, and CAM02.bmp (1920x1080 each) into buf[0]
loadBufferFromMultipleImages(buf[0],"CAM%02d.bmp",3,1,VX_DF_IMAGE_RGB,1920,1080*3);
# set input and output buffers and stitch a frame
lsSetCameraBuffer(context, &buf[0]);
lsSetOutputBuffer(context, &buf[1]);
run(context, 1);
# save the stitched output into "output.bmp"
saveBufferToImage(buf[1],"output.bmp",VX_DF_IMAGE_RGB,3840,1920);
# release resources
releaseBuffer(&buf[0]);
releaseBuffer(&buf[1]);
lsReleaseContext(&context);
Example #2: Stitching Workflow using PTGui Pro Tool for Camera Calibration#
It is easy to import camera parameters from PTGui Pro project file (.pts) into loom_shell.
In this example, let’s consider a 360 rig that has sixteen 1080p cameras.
Step 1: Calibrate cameras
Save test input images from all cameras into BMP files: CAM00.bmp, CAM01.bmp, CAM02.bmp, …, and CAM15.bmp.
Align these test input images using PTGui Pro and save the project into myrig.pts (it should be in ASCII text format).
Step 2: Use the following script to generate stitched 4K output:
# create context, configure, and initialize
ls_context context;
context = lsCreateContext();
lsSetOutputConfig(context, VX_DF_IMAGE_RGB, 3840, 1920);
lsSetCameraConfig(context, 16, 1, VX_DF_IMAGE_RGB, 1920, 1080*16);
lsImportConfiguration(context, "pts", "myrig.pts");
showConfiguration(context, "loom_shell");
lsInitialize(context);
# create buffers for input and output
cl_context opencl_context;
cl_mem mem[2];
lsGetOpenCLContext(context, &opencl_context);
createBuffer(opencl_context, 3*1920*1080*16, &buf[0]);
createBuffer(opencl_context, 3*3840*1920, &buf[1]);
# load input images into buf[0]
loadBufferFromMultipleImages(buf[0], "CAM%02d.bmp", 16, 1, VX_DF_IMAGE_RGB, 1920, 1080*16);
# process camera inputs from buf[0] into stitched output in buf[1]
lsSetCameraBuffer(context, &buf[0]);
lsSetCameraBuffer(context, &buf[1]);
run(context, 1);
# save the output
saveBufferToImage(buf[1], "output.bmp", VX_DF_IMAGE_RGB, 3840, 1920);
# release all resources
releaseBuffer(&buf[0]);
releaseBuffer(&buf[1]);
lsReleaseContext(&context);
Example #3: Real-time Live Stitch using LoomIO#
This example makes use of a 3rd party LoomIO plug-ins for live camera capture and display.
# create context, configure, and initialize
ls_context context;
context = lsCreateContext();
lsSetOutputConfig(context, VX_DF_IMAGE_RGB, 3840, 1920);
lsSetCameraConfig(context, 16, 1, VX_DF_IMAGE_RGB, 1920, 1080*16);
lsImportConfiguration(context, "pts", "myrig.pts");
lsSetCameraModule(context, "vx_loomio_bm", "com.amd.loomio_bm.capture", "30,0,0,16");
lsSetOutputModule(context, "vx_loomio_bm", "com.amd.loomio_bm.display", "30,0,0");
lsInitialize(context);
# process live from camera until aborted by input capture plug-in
run(context, 0);
# release the context
lsReleaseContext(&context);
Example #4: Converting script into standalone C application#
It is easy to convert a well written LoomShell script into a standalone C application using the following steps :
Convert the shell script comments into C - style inline comments and keep them inside main() function
Use “amdovx-modules/utils/loom_shell/loom_shell_util.h” for wrapper utility functions, such as, loadBuffer()
Add “amdovx-modules/utils/loom_shell/loom_shell_util.cpp” to project for wrapper utility function implementations
Below is the C code generated from script in Example#3.
#include "loom_shell_util.h"
int main()
{
    // create context, configure, and initialize
    ls_context context;
    context = lsCreateContext();
    lsSetOutputConfig(context, VX_DF_IMAGE_RGB, 3840, 1920);
    lsSetCameraConfig(context, 16, 1, VX_DF_IMAGE_RGB, 1920, 1080 * 16);
    lsImportConfiguration(context, "pts", "myrig.pts");
    lsSetCameraModule(context, "vx_loomio_bm", "com.amd.loomio_bm.capture", "30,0,0,16");
    lsSetOutputModule(context, "vx_loomio_bm", "com.amd.loomio_bm.display", "30,0,0");
    lsInitialize(context);
    // process live from camera until aborted by input capture plug-in
    run(context, 0);
    // release the context
    lsReleaseContext(&context);
    return 0;
}