Docker container with Bluemix CLI tools

BluemixCLI on docker hub
BluemixCLI on docker hub

Being an developer advocate means to play always with the latest version of tools and being on the edge. But installed programs are getting out of date and so I always end up with having installed old versions of CLI tools. One reason why I love cloud (aka other people’s computers) computing so much is because I don’t need to update the software, it is done by professionals. In order to have always the latest version of my Bluemix CLI tools in hand and being authenticated I compiled a little docker container with my favourite command line tools. cf, bx, docker and wsk.

Getting the docker container

I published the docker container on the official docker hub. So getting it is very easy when the docker tools are installed. This command will download the latest version of the container and therefore the latest version of installed cli tools. We need to run this command from time to time to make sure the latest version is available on our computer.

docker pull ansi/bluemixcli

Get the necessary parameters

For all command line tools we need username, passwords and IDs. Obviously we can not hardcode them into the docker container therefore we need to pass them along as command line parameters when starting the docker container.

  • Username (the same as we use to login to Bluemix)
  • Password (the same as we use to login to Bluemix)
  • Org (The Organisation we want to work in, must already be existing)
  • Space (The Space we want to work in, must already be created)
  • AccountID (This can we catched from the URL when we open “Manage Organisation and click on the account)
  • OpenwhiskID (Individual for org and space, get be catched here:

Run the container

The container can be started with docker run and passing all parameters with -e in:

docker run -it --rm                      \
-e BX_USERNAME=<Bluemix Username>        \
-e BX_PASSWORD=<Bluemix Password>        \
-e BX_ORG=<Bluemix Organisation>         \
-e BX_SPACE=<Bluemix Space>              \
-e BX_ACCOUNT_ID=<Bluemix Account ID>    \
-e WSK_AUTH=<Openwhisk Authentification> \
-v ${PWD}:/root/host                     \
ansi/bluemixcli /bin/bash

Line 8 mounts the local directory inside the docker container under /root/host. So we can fire up the container and have a bash with the latest tools and our source code available.

Use the tools

Before we can use the tools we need to configure them and authenticate against Bluemix. The script “” which is located in “/root/” (our working directory) takes care of all logins and authentications.


The Cloudfoundry command line tool for starting, stopping apps and connecting services.


The Bluemix version of the Cloudfoundry command line tool. Including the plugin for container maintenance. By initializing this plugin we also get the credentials and settings for the docker client to use Bluemix as a docker daemon.


The normal docker client with Bluemix as daemon configured.


The OpenWhisk client already authenticated.

We can configure an alias in our .bashrc so by just typing “bxdev” we will have bash with the latest cli tools available.

Draw an analytic chart directly in the picture

Debugging feature extraction of images

Histogram chart drawn on image
Histogram chart drawn on image

A big part when writing code for visual recognition in cognitive computing is to extract information aka. features from images. For example we need to understand colour information and want to see a histogram chart on a certain RGB or HSV channel. OpenCV offers a nice way to combine image analytics and image manipulation. In combination with the library mathplot it is relatively easy to analyse the picture, extract features and write debug information as a chart to the picture itself.

Getting a test picture

For this demo I will choose a picture from a webcam of the Observatory Friolzheim. On we can get a life picture taken from the observatory dome. Beside the webcam pointing to the building there are also weather information (very helpful when mapping images features) and a AllSky cam.

Getting the software and libraries

As described in this blog article there is a nice docker container for openCV available. We can use this one and just add missing libs and tools with a minimalistic Dockerfile:

from victorhcm/opencv:latest
RUN pip install matplotlib

and build it with

docker build -t mathplot-opencv:latest .

Python file to get the chart for debug visual features

import cv2
import glob
import numpy
import matplotlib
import matplotlib.pyplot as plt

fig = plt.figure()
ax  = fig.add_subplot(111)
ax.set_xlim([0, 255])

for fullname in glob.glob("data/*.jpg"):
    filename  = fullname.split('/')[1]
    name      = filename.split('.')[0]
    image     = cv2.imread(fullname, cv2.IMREAD_COLOR)
    histogram = numpy.bincount(image.ravel(), minlength=256)

    histogram[:2] = 0
    histogram[250:] = 0

    weights = [0.3, 0.4, 0.3]
    histogram = numpy.convolve(histogram, numpy.array(weights)[::-1], 'same')
    maxindex  = numpy.argmax(histogram)
    print maxindex

    ax.plot(histogram, 'blue')

    imga = numpy.fromstring(fig.canvas.tostring_rgb(), dtype=numpy.uint8, sep='')
    imga = imga.reshape(fig.canvas.get_width_height()[::-1] + (3,))
    imga = cv2.cvtColor(imga, cv2.COLOR_RGB2BGR)
    imga = cv2.addWeighted(image, 0.7, imga, 0.3, 0)
    cv2.imwrite("debug/%s.png" % name, imga)


Line 5

This one is very important if we want to run this matplotlib “headless”. Meaning without a graphic export attached to the runtime. Like in a docker container or on a remote server.

Line 8-10

We create a matplot lib figure with subplot here where we are going to add the chart.

Line 16

As openCV uses numpy to work with images, the image itself is displayed in a multidimensional array and image.ravel() flattens this to a one dimensional array. Bincount just counts the amount of unique numbers used in this array. So with this line we just create a new 1 dimensional array of all the RGB colours in the image which is basically a histogram of the image. By doing so we mix all colours together, which is ok in this sample or a classic histogram. However if we want to see only one channel we can use

hsv     = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)

to extract a single channel.

Line 18-19

If the picture contains very shiny or very black parts the high and low values like <10 or >250 are over proportionally high. This will distort the histogram sometimes. These two lines just resets the histogram array on the upper and lower end to 0.

Line 21-22

This just smooth the histogram.

Line 23-24

Histogram without blanked parts
Histogram without blanked parts

Argmax returns the index of the highest number in a array. This one can be considered as a feature of the image. For example if we want to rank or sort our webcam pictures by daytime regarding to the sunlight this features gives us an indication. If we are using this feature the lines 18-19 becomes very important here to eliminate the reflexions in a picture. For example in the demo image the observation dome. The upper pictures contains the chart which already blanked out parts. The original chart looks like the one on the right.

Line 26-27

The matplotlib chart is drawn here into the subplot. Still the matplotlib chart and the image itself are “stored” in different libraries.

Line 29

Here the magic happens. fig.canvas.tostring_rgb exports the chart from matplotlib into a string and numpy.fromstring imports this string back to a numpy array which is like the picture we imported at the beginning.

Line 30

Here we reshapes the newly created image to the same size as the imported image.

Line 31

OpenCV can handle all kind of different image colour representations, like RGB, HSV aso. The fromstring importer reads in RGB but our image is in BGR, so this line just converts the colour representation.

Line 32

Here we combine both image with a weighted parameter of 70% of the original image and 30% of the chart.

Line 33

Finally we save this image in a debug folder with the same filename but just because we can as a png file.

Line 35

Finally we clear up the used memory. This is very important when we convert a huge amount of images.

How to use this for visual recognition

By extracting features in images this little piece of code helps us to add the feature directly in a debug image. In our example we only used the histogram and extracted the colour with the highest number, but by having the histogram in hand we could see what was the underlying information the sorting algorithm used. Sorting images in night, dusk/dawn, daylight can be a way of preparing pictures for further processing in neuronal networks. By browsing through the images in one of this sorting folders we can easily see what went wrong in a picture which does not belong in this group. Typical problem is night and day pictures are missorted because of reflexions.