Skip to content

Getting_started

Gijs-Koot edited this page Dec 19, 2014 · 10 revisions

The basics

StormCV is used to define a image/video processing pipeline and deploy it on a Storm cluster. These processing pipeline may only contain a few steps or may, it does not really matter. The figure below shows a very simple example of a pipeline (called topology in Storm) that reads a stream, scales it down, converts frames to grayscale and streams the result out.

simple topology

This linear topology can run on a single machine when it is only processing one stream (which requires only one spout/bolt of each type). It is possible to specify how many of each processing element you want. So for 10 streams you can have 5 stream readers (reading 2 streams each), 10 Scale operations, 4 Grayscale operations and 2 streamers (total of 21 elements) which should run on a cluster containing at least 21 CPU cores.

Executing the example

The example above can be found in the stormcv_examples project within the repository. Execute the following steps assume you have a bisic understanding of Git and work with the Eclipse IDE:

  1. clone the repository git clone https://github.com/sensorstorm/StormCV.git
  2. open Eclipse and import the stormcv_examples project from your local repository into your eclipse workspace (besides src/ and lib/ there should be a resources/data directory containing a number of faceX.jpg images and two mp4 files)
  3. open E1_GrayScaledTopology.java within the nl.tno.stormcv.example package. This class defines the topology as shown above in the lines 42 - 61, the rest of the code is global configuration.
  4. Running this class will build the topology and execute it in local (simulation) mode. This will generate a bunch of logging information in the console and depending on your hardware it might take some time (30 seconds) to set it all up.
  5. Open a browser when the local topology has started and go to http://localhost:8558/streaming/tiles to see the output. There should be two images and refreshing the page will refresh the images as well. Click one of the images to see the actual mjpg stream generated. If you get an empty gray web page it means the topology is set up but streams are not yet being read, keep refreshing the page until you get output.

Now lets go through the important parts of the code:

// first define a list with all the url's that must be read. These urls will be divided among all spouts in the topology.
// Since this topology contains 1 spout this means it will read both streams in parallel
List<String> urls = new ArrayList<String>(); 
urls.add( "rtsp://streaming3.webcam.nl:1935/n224/n224.stream" );
urls.add("rtsp://streaming3.webcam.nl:1935/n233/n233.stream");
	
int frameSkip = 13; //the spout will extract one frame out of every 13 and send it to the next bolt
	
// The TopologyBuilder is the main tool to build and configure topologies
TopologyBuilder builder = new TopologyBuilder();
	
// add a spout with StreamFrameFetcher which will read the streams defined in the urls list
builder.setSpout("spout", 
	new CVParticleSpout( new StreamFrameFetcher(urls).frameSkip(frameSkip) ) // add a basic Spout containing the StreamFrameFetcher
	 , 1 ); // the '1' at the end indicates there is only one instance of this spout in the topology
	
// add a bolt with scale operation to scale down frames to 66% of the original size. 
builder.setBolt("scale", new SingleInputBolt( new ScaleImageOperation(0.66f)), 1)
.shuffleGrouping("spout"); // This bolt gets input from the spout
	
// add a bolt with grayscale operation to turn frames to gray
builder.setBolt("grayscale", new SingleInputBolt( new GrayscaleOperation()),1)
.shuffleGrouping("scale"); //This bolt gets input from the scale
	
// add batch bolt which will wait for 2 subsequent frames from scale bolt before streaming them
builder.setBolt("streamer", new BatchInputBolt( 
	// This Batcher functions as a (very small) buffer for the streaming operation. 
	new SlidingWindowBatcher(2, frameSkip).maxSize(6),  
	// add a Mjpeg operation which will bind itself to port 8558 
	new MjpegStreamingOperation().port(8558).framerate(5)).groupBy(new Fields(FrameSerializer.STREAMID)
), 1).shuffleGrouping("grayscale"); 
	
// the code below executes this topology on localhost		
try {
	LocalCluster cluster = new LocalCluster();
	cluster.submitTopology( "grayscaled", conf, builder.createTopology() );
	Utils.sleep(120*1000); // run for 2 minutes before shutting down
	cluster.shutdown();
	
	// replace the 4 lines above simply by this one to execute the topology on a Storm cluster
	// StormSubmitter.submitTopology("some_topology_name", conf, builder.createTopology());
} catch (Exception e){ }

You can continue with other examples described here or read some more about StormCV's components and principles here

Clone this wiki locally