Python and C++ toolkit that pulls together computer vision algorithms into highly modular run time configurable systems


License
BSD-3-Clause
Install
pip install kwiver==1.4.6

Documentation

KWIVER

Kitware Image and Video Exploitation and Retrieval


The KWIVER toolkit is a collection of software tools designed to tackle challenging image and video analysis problems and other related challenges. Recently started by Kitware’s Computer Vision and Scientific Visualization teams, KWIVER is an ongoing effort to transition technology developed over multiple years to the open source domain to further research, collaboration, and product development.

The project is structured with the parent kwiver repository working as CMake "super-build" that pulls in a number of KWIVER and other open source projects.

Building KWIVER

Fletch

KWIVER has (and will have more) a number of dependencies on 3rd party Open Source libraries. To make it easier to build KWIVER, especially on systems like Microsoft Windows that don't have package manager, Fletch was developed to gather, configure and build those packages for use with KWIVER. Fletch is a CMake based "super-build" that takes care of most of the build details for you.

To build Fletch, clone the Fletch repository:

git clone https://github.com/Kitware/fletch.git

Then, create a build directory and run the following cmake command:

cmake -DFLETCH_BUILD_WITH_PYTHON=TRUE -DCMAKE_BUILD_TYPE=Release -Dfletch_ENABLE_Boost=TRUE -Dfletch_ENABLE_OpenCV=TRUE  /path/to/fletch/source/directory

If you have more than one version of Python installed on your system and you want to be sure to use a particular one (for example we here at KWIVER development central use Anaconda fairly frequently) you'll want to add the following arguments to the cmake command:

  • -DPYTHON_INCLUDE_DIR=/path/to/python/include/directory For example, for a default Python 2.7 Anaconda install on Linux this would be ${HOME}/anaconda/include/python2.7
  • -DPYTHON_EXECUTABLE=/path/to/executable/python For example, for a default Python 2.7 Anaconda install on Linux this would ${HOME}/anaconda/bin/python
  • -DPYTHON_LIBRARY=/path/to/python/library For example, for a default Python 2.7 Anaconda install on Linux, this would be ${HOME}/anaconda/lib/libpython2.7.so

Once your cmake command has completed, you can build with the following command

make

kwiver

Once Fletch has been built, it's possible to build the kwiver repository as well. This repo is also a CMake super-build and can be fetched with this command:

git clone https://github.com/Kitware/kwiver.git

The build can be configured with this command:

cmake -DKWIVER_ENABLE_PYTHON -Dfletch_DIR=/path/to/fletch/build/directory /path/to/kwiver/source/directory

As with Fletch, if you want to specify a particular Python installation (such as Anaconda) use the the -DPYTHON... command arguments as outlined in the Fletch section.

Once your cmake command has completed, use make (on Linux) to build it.

Running KWIVER

Once you've built KWIVER, you'll want to test that it's working on your system. From a command prompt execute the following command:

source </path/to/kwiver/build>/install/setup_KWIVER.sh

Where </path/to/kwiver/build> is the actual path of your KWIVER CMake build directory.

This will set up your PATH, PYTHONPATH and other environment variables to allow KWIVER to work conveniently.

The central component of KWIVER is Sprokit. We use Sprokit's pipelining facilities to manage, integrate and run many of KWIVER's modules and capabilities. To see what modules (called processes in Sprocket) are available, issue the processopedia command. Here's a typical list of modules (note that as KWIVER expands, this list is likely to grow):

any_source: A process which creates arbitrary data
collate: Collates data from multiple worker processes
const: A process with the const flag
const_number: Outputs a constant number
data_dependent: A process with a data dependent type
distribute: Distributes data to multiple worker processes
duplicate: A process which duplicates input
expect: A process which expects some conditions
feedback: A process which feeds data into itself
flow_dependent: A process with a flow dependent type
frame_list_process: A process that reads a list of image file names and generates stream of images and associated time stamps
kw_archive_writer_process: A process to write kw archives
kw_print_number_process: A Simple Kwiver Test Process
multiplication: Multiplies numbers
multiplier_cluster: A constant factor multiplier cluster
mutate: A process with a mutable flag
numbers: Outputs numbers within a range
orphan: A dummy process
orphan_cluster: A dummy cluster
pass: Pass a data stream through
print_number: Print numbers to a file
shared: A process with the shared flag
sink: Ignores incoming data
skip: A process which skips input data
stabilize_image_process: A process to generate current-to-reference image homographies
tagged_flow_dependent: A process with a tagged flow dependent types
take_number: Print numbers to a file
take_string: Print strings to a file
tunable: A process with a tunable parameter

This is the list of modules that can be included in a Sprokit pipeline. We're going to use the numbers module and the the print_number module to create a very simple pipeline. To learn more about the numbers module we'll again use processopedia this time to get details on a particular module. For numbers we'll use the processopedia -t numbers -d command:

Process type: numbers
  Description: Outputs numbers within a range
  Properties: _no_reentrant
  Configuration:
    Name       : end
    Default    : 100
    Description: The value to stop counting at.
    Tunable    : no

    Name       : start
    Default    : 0
    Description: The value to start counting at.
    Tunable    : no

  Input ports:
  Output ports:
    Name       : number
    Type       : integer
    Flags      : _required
    Description: Where the numbers will be available.

And for print_number, we'll use processopedia -t print_number -d:

Process type: print_number
  Description: Print numbers to a file
  Properties: _no_reentrant
  Configuration:
    Name       : output
    Default    :
    Description: The path of the file to output to.
    Tunable    : no

  Input ports:
    Name       : number
    Type       : integer
    Flags      : _required
    Description: Where numbers are read from.

  Output ports:

The output of these commands tells us enough about each process to construct a Sprocket ".pipe" file that defines a processing pipeline. In particular we'll need to know how to configure each process (the "Configuration") and how they can be hooked together (the input and output "Ports").

KWIVER comes with a sample kwiver/pipeline_configs/number_flow.pipe file that configures and connects the pipeline so that the numbers process will generate a set of integers from 1 to 99 and the print_number process will write those to a file called numbers.txt. Of particular interest is the section at the end of the file that actually "hooks up" the pipeline.

To run the pipeline, we'll use the Sprokit pipeline_runner command:

pipeline_runner -p </path/to/kwiver/source>/kwiver/pipeline_configs>/number_flow.pipe

After the pipeline completes, you should find a file, numbers.txt, in your working directory.

Python Processes

One KWIVER's great strengths (as provided by Sprokit) is the ability to create hybrid pipelines which combine C++ and Python processes in the same pipeline. This greatly facilitates prototyping complex processing pipelines. To test this out we'll still use the numbers process, but we'll use a Python version of the print_number process called kw_print_number_process the code for which can be seen in kwiver/src/processes/kw_print_number_process.py. As usual, we can lean about this process with a processopedia command: processopedia -t kw_print_number_process -d:

Process type: kw_print_number_process
  Description: A Simple Kwiver Test Process
  Properties: _no_reentrant, _python
  Configuration:
    Name       : output
    Default    : .
    Description: The path for the output file.
    Tunable    : no

  Input ports:
    Name       : input
    Type       : integer
    Flags      : _required
    Description: Where numbers are read from.

  Output ports:

As you can see, the process is very similar to the C++ print_number process. As a result, the ".pipe" file is very similar.

In order to get around limitations imposed by the Python Global Interpreter Lock, we'll use a different Sprokit scheduler for this pipeline. The pthread_per_process schedule which does essentially what it says: it creates a Python thread for every process in the pipeline:

pipeline_runner -S pythread_per_process -p </path/to/kwiver/source>/kwiver/pipeline_configs>/number_flow_python.pipe

As with the previous pipeline, the numbers will be written to an output file, this time numbers_from_python.txt