5.21.2014

BeagleBone: MJPG-Streamer + C920

One reason for testing the BeagleBone Black was because of its processing capabilities. After some research it seemed as if it would work well streaming video. We decided to try MJPG-Streamer (which we had previously tried here on the Raspberry Pi) with Logitech's C920 Webcam. We chose to use this camera because of its HD capability, onboard H264 video encoding, and USB compatibility. Below is the camera taken out of its case:



The dependencies need on the BeagleBone and for the C920 are slightly different. First update and upgrade your operating system to insure that everything is up-to-date:





Below is a list of the correct dependencies. All work with apt-get install (for example, to install g++ use sudo apt-get install g++):

  • g++
  • cmake
  • build-essential
  • imagemagick
  • pkg-config
  • libv4l
  • libv4l-dev
  • v4l-utils
  • v4l2ucp
  • libjpeg8-dev

Now with the dependencies installed you can download MJPG-Streamer from our forked repository:




Make a symbolic link to the videodev2.h file:




Finally, install MJPG-Streamer:





After setting everything up there still may be an error that says the V4L2 Device isn't loaded. This happens because the uvccamera module is not loaded. To load the module:




You might need to switch between loading and unloading the module to get MJPG-Streamer to work. To unload the uvcvideo module use this command:





To play the video use the MJPG-Streamer commands and view it from the webserver (https://<localhost>:8080)!:





 You should see a 1280x720 image with 30 fps! A clear, crisp, and speedy stream. Perfect for the submersible. After a long, long journey looking into the different streaming methods available, it seems that MJPG-Stream is the best option for our project.





13 comments:

  1. Great, thanks for sharing !

    You don't mention why you go this route instead of directly piping the h264 stream of the cam.
    Is it because it's simpler to work with an MJPG and also because you don't lack bandwidth ?

    ReplyDelete
  2. Good question! The reason is because of the quality..whenever the camera is moved quickly the video stream quality goes way down. Another reason is versatility -- MJPG-Streamer allows us to easily read the jpegs from the camera with a number of different types of software (OpenCV, HTML, etc) easier then encoding and decoding the h264 video. Basically it was the most straightforward, fastest, and highest quality stream we have gotten.

    Thanks for the comment!

    ReplyDelete
  3. Nice blog. The problem with h264 during motion is because it uses interframe compression to minimize data required, isn't that right? When you move fast, the succeeding frames are too different so you lose picture quality. MJPG only uses intraframe compression, I think, so less compression but retains quality when succeeding frames are very different.

    ReplyDelete
    Replies
    1. I guess you're right about the root cause, but h264 still acts to insert more key frames in case there is movement (most of the time automatically, but maybe it's not available on c920 chip).

      Delete
    2. Thanks for the comments (that's rice to hear, rho)!

      It has to be something with the compression percentages. The C920 (and the Pi Camera) might use a higher compression Lossy format (http://en.wikipedia.org/wiki/Lossy_compression) and therefore not have enough data to give a clear image when the frames are switched quickly. I'm not that well versed in different video compression formats, but this seems to make sense. Is this a correct assumption/conclusion?

      Delete
    3. M-JPEG:
      "Because frames are compressed independently of one another, M-JPEG imposes lower processing and memory requirements on hardware devices.
      As a purely intraframe compression scheme, the image-quality of M-JPEG is directly a function of each video frame's static (spatial) complexity. Frames with large smooth-transitions or monotone surfaces compress well, and are more likely to hold their original detail with few visible compression artifacts. "
      "It tolerates rapidly changing motion in the video stream, whereas compression schemes using interframe compression [e.g. H.264] can often experience unacceptable quality loss when the video content changes significantly between each frame."

      see informative Wikipedia entry:
      http://en.wikipedia.org/wiki/Motion_JPEG#Encoding

      Delete
    4. By the way, in case you haven't run across it before - you might also be interested in Raspicam (formerly RaspiMJPEG). It's different from MJPEGstreamer:
      http://www.raspberrypi.org/forums/viewtopic.php?f=43&t=63276&p=468491#p468491
      https://github.com/silvanmelchior/userland/tree/master/host_applications/linux/apps/raspicam
      http://elinux.org/RPi-Cam-Web-Interface

      Delete
  4. This is great. I have been struggling with streaming H264 on my beaglebone and c920 as an input for openCV. I think this might just work because openCV seems to handle mjpeg better than H264. My question is: How would I call the mjpeg stream as an input for my camera in opencv? (i.e. capture = VideoCapture(http:/"address to mjpeg"). Please let me know what you think. Thanks!!!

    ReplyDelete
    Replies
    1. As long as you tell your OpenCVFrameGrabber object to read jpeg images (i.e., grabber.setFormat("jpeg")), then you can just pass it this string as its source when you instantiate it: "http://[ip of mjpeg-streamer stream]/?action=stream&type=.mjpg"

      Hope this helps. Comment again if anything is unclear.

      Delete
    2. Hi, thank you for the quick response! What exactly do you mean by telling OpenCVFrameGrabber to set the format for jpeg? My capturing object in my code looks like this:

      video = VideoCapture()
      capture = video.open("http://192.168.7.2:8090/?action=stream?dummy=param.mpjg")
      So would I just try capture.SetCaptureProperty(capture,CV_CAP_PROP_FORMAT,jpeg)??

      Thanks for the help let me know what you think!

      Delete
    3. Are you writing your program in Java or C?

      Delete
    4. Hi, I've got it figured out. I'm streaming mjpg on the beaglebone black and then picking it up through opencv. It works really smooth if I run openCV on a PC but when I do it on the BBB I have to stream it with a resolution of 320x240 because the BBB can't keep up with decoding, and tracking images, etc... Thanks for all of your help!

      Delete