Streaming OpenCV Output Through HTTP/Network with MJPEG

If you want to stream your OpenCV output image to another device which connected to the same network, one way is to write the OpenCV output as MJPEG file, then stream this file through HTTP.

Please note that:
– This might be not the best way (correct me if I’m wrong)
– OpenCV 2.3 cv::VideoWriter has memory leak bug

0. OpenCV Stuff
I assume you already have your OpenCV libraries installed, because several of OpenCV’s dependencies are also MJPEG-Streamer’s, such as libv4l-dev and libjpeg-dev. And make sure your OpenCV application works (it writes the mjpeg file)

1. Install MJPEG-Streamer
Install the dependencies first

sudo apt-get install imagemagick

Then get the latest MJPEG-Streamer from the repository:

git clone
cd mjpg-streamer/mjpg-streamer
make USE_LIBV4L2=true clean all
sudo make DESTDIR=/usr/local install

Then set the environment variable LD_LIBRARY_PATH if you haven’t, either in /etc/bash.bashrc or your own ~/.bashrc, add this line:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

2. Into The Main Show
First fire up your OpenCV application, this is my application, simple background subtraction and writes the output into mjpg file.

git clone
cd bgsubtract/
make bgsubtract2

Prepare the folder to put the mjpg file into, for example in my home folder:

mkdir /home/ariandy/mjpg

Then run the application:

./bgsubtract2 /home/ariandy/mjpg/out.mjpg -bgs

Leave it running in one terminal, and open another terminal to test the MJPEG-Streamer:

mjpeg_streamer -i " -f /home/ariandy/mjpg" -o " -w /usr/local/www"

The command above is the most basic setting to get the streaming to work. By default, the web server is listening to port 8080. If you want to use port 80, you have to run the command as root (or with sudo).

The default www root of MJPEG-Streamer is located at /usr/local/www. There you can find the demo pages, from which you can get the idea of several ways to display the stream: either direct stream (supported by most Grade-A Desktop Browsers (Sorry, IE!)), using Java MJPEG viewer (cambozola), javascript, etc.

3. Viewing The Stream
On the client, simply point the browser to the server’s IP address with corresponding port (8080). e.g. server’s IP address is, then to access it from the client, point to If you want to omit the :8080 part, then you have to run the server on port 80 (HTTP), as following:

sudo mjpeg_streamer -i " -f /home/ariandy/mjpg" -o " -w /usr/local/www -p 80"

I tried this with Google Chrome, Firefox, Android Browser, and Firefox for Android.


Calculating FPS in OpenCV for Live Capture

cvGetCaptureProperty(CV_CAP_PROP_FPS); simply won’t work for live capture from camera. So following is my workaround, enhanced version of this source:

#include "cv.h"
#include "highgui.h"

#include <stdio.h>
#include <time.h> // to calculate time needed
#include <limits.h> // to get INT_MAX, to protect against overflow

int main(int argc, char** argv){
	CvCapture* capture = cvCaptureFromCAM( 0 );
	if (!capture){
		fprintf(stderr, "ERROR: Capture is null\nPress any key to exit\n");
		return -1;
	// fps counter begin
	time_t start, end;
	int counter = 0;
	double sec;
	double fps;
	// fps counter end
	cvNamedWindow("Original", CV_WINDOW_AUTOSIZE);
		// fps counter begin
		if (counter == 0){
		// fps counter end
		IplImage* origImage = cvQueryFrame(capture);
		cvShowImage("Original", origImage);

		// do your stuff here

		// fps counter begin
		sec = difftime(end, start);
		fps = counter/sec;
		if (counter > 30)
			printf("%.2f fps\n", fps);
		// overflow protection
		if (counter == (INT_MAX - 1000))
			counter = 0;
		// fps counter end

		// will exit when ESC button is pressed
		if ( (cvWaitKey(10) & 255) == 27 ) break;
	return 0;