Blog from July, 2017

A quick note on new operations in cv-calc utility. Time does not permit to present proper examples, but hopefully, cv-calc --help would be sufficient to give you an idea.

cv-calc grep

Output only those input images that conform a certain condition. Currently, only min/max number or ratio of non-zero pixels is supported, but the condition can be any set of filters applied to the input image (see cv-cat --help --verbose for the list of the filters available).

Example: Output only images that have at least 60% of pixels darker than a given threshold:

> cat images.bin | cv-calc grep --filters="convert-to=f,0.0039;invert;threshold=0.555" --non-zero=ratio,0.6

cv-calc stride

Stride to the input image with a given kernel (just like a convolution stride), output resulting images.

cv-calc thin

Thin the image stream by a given rate or a desired frames-per-second number.

csv-shape is a new utility for various operations on reshaping csv data.

For now, only one operation is implemented: concatenate:

Concatenate by Grouping Input Records

> ( echo 1,a; echo 2,b; echo 3,c; echo 4,d; ) | csv-shape concatenate -n 2

Note: For ascii text inputs the records do not have to be regular or even have the same number of fields.

Concatenate by Sliding Window


> ( echo 1,a; echo 2,b; echo 3,c; echo 4,d; ) | csv-shape concatenate -n 2 --sliding-window


> ( echo 1,a; echo 2,b; echo 3,c; echo 4,d; ) | csv-to-bin ui,c | csv-shape concatenate -n 2 --sliding-window --binary ui,c | csv-from-bin ui,c,ui,c

This is a brief introduction to cv-cat new filters:


Filter: Accumulated

This filter is used to calculate pixel-wise (and channel-wise) average from the sequential series of input images.

As it relies on the sequential accumulated input images, this filter is run in serial mode in cv-cat. This as implications when used with 'forked' image processing.

However parallel processing is utilised on image rows dimension.

Please download the following file which contains a total of 8 images: images.bin: 8 images showing movement. Viewing the images:

cat images.bin | cv-cat "view=250;null" 


Calculating averages using all accumulated input images, the output is also 8 images.

cat images.bin | cv-cat "accumulated=average;view=250;null"

The 6th output image is the average of all 6 accumulated images, the 7th is the average of the 7 accumulated input images.


Exponential Moving Average (EMA):

Calculating the average using a sliding window of images. Here a sliding window of 3 images is used.

cat images.bin | cv-cat "accumulated=average,3;view=250;null"

The output is 8 images, the 6th image is the accumulation of image 1 to 6. Please research the simple EMA formula.


Forked Arithmetic Filters: Multiply, Divide, Add and Subtract

This group of filters work similar to the mask filer: Masking images with cv-cat, they both use a sub-filters to generate a mask or operand image. 

A mask has values of 0 or '> 0' mask file to apply to the image, a corresponding pixel in the mask with a value of 0 is masked. The arithmetic filters work on operand images where is pixel value is important.


This filter will do pixel-wise multiplication the operand image and the input image. It wraps cv::multiply function.

Please download this simple mask file: scaled-3f.bin

#Viewing the mask
cat scaled-3f.bin | cv-calc header
cat scaled-3f.bin| cv-cat "view=1000;null"

Applying a single scaled image to the input images:

cat images.bin | cv-cat "multiply=load:scaled-3f.bin;view=250;null"

You should see images similar to below. scaled-3f.bin has values in the range of 0 to 1.0, the command above will darken the images.

From the example above: cv-cat's multiply is run in parallel, multiple input images are applied the scaled-3f.bin file in parallel.

This is because the all sub-filter(s) can run in parallel mode, in this case there is only one sub-filter 'load'.

The example below also shows multiply running in parallel mode as as load and threshold are parallel-able filters.

cat images.bin | cv-cat "multiply=load:scaled-3f.bin|threshold:0.7,1;view=250;null"


This filter simply subtract the operand image from each input image. This is a wrapper to cv::subtract.

The operand image is derived from the sub-filters. In this example we shall use the accumulated filter mentioned earlier. This is a simple method for detecting moving objects in the image.

cat images.bin| cv-cat "subtract=accumulated:average,3;brightness=5;view=250;null"

Each input image is subtracted the EMA average, where the EMA window is 3.

You should see similar images shown below:

In the example above: the multiply filter is run in serial mode. This is because one of the sub-filter or sub-filters ('accumulated' in this case) can only be run in serial mode.

If you have a webcam handy or it is built into the laptop, try this command:

cv-cat --camera "subtract=accumulated:average,10;view;null"


This is a wrapper to cv::add

This filter is the opposite of subtract. In this case if you add the EMA average (the "background") to the input images. Any moving object becomes transparent.

cat images.bin| cv-cat "add=accumulated:average,3;view=250;null"

This is the result:

Of course you can always try this pipeline with a physical camera:

cv-cat --camera "subtract=accumulated:average,10;view;null"



This filter wraps cv::divide, divides the input images by the operand.

The file scaled-3f.bin has values in the range 0 to 1.0, hence dividing the image by scaled-3f.bin will brighten the image.

Arithmetic filters: the output image type is the same as the input image type.

cat images.bin| cv-cat "divide=load:scaled-3f.bin;view=250;null"