blog

Eyeball

Teaching Your Computer To See The Easy Way

by

You’re curious about how SnapChat can apply those stamps, you want to create an autonomous controller for your USB controlled Nerf missile launcher, or maybe you have an actual business need. Here is a simple formula to get started with OpenCV so that you can achieve your Computer Vision dreams. Cinder provides a great creative computing framework with a simple pattern of update and draw cycles. It already has support for OpenGL rendering, and it can easily support OpenCV.

I used Cinder 0.9.0, OpenCV 3.0 in this tutorial.

  1. Download Cinder
    1b. If you want to take it easy, download my project from Github here.
  2. Create a project using Cinder’s Tinderbox, choose your platform, and select the OpenCV cinderblock.
    Either use the provided OpenCV template…screenshot-2016-10-24-19-36-08
    Or select the OpenCV cinderblock and have TinderBox copy it to your project.
    screenshot-2016-10-24-18-57-07
  3. Modify your app class’ setup() method.This is called one time after the app class is instantiated. We’ll open the computer’s camera, initialize the detector, and create a buffer to draw the frame.
    [code language=”cpp” firstline=”52″]
    auto size = this->getWindowSize();
    // Initialize the camera.
    fCaptureDev = Capture::create(size.x, size.y);
    fCaptureDev->start();
    // Set up detector with a HAAR cascade. See Resources folder for other types.
    auto path = cinder::app::Platform::get()->getResourcePath("haarcascade_eye.xml");
    fClassifier = new cv::CascadeClassifier(path.c_str());
    // Prepare a GPU buffer used to draw the captured frame.
    fGlFrame = gl::Texture::create(size.x, size.y);
    [/code]
  4. Modify your app class’ update() method.Do the hard work here such as detecting and tracking. Prepare anything you need so that your drawing method only has to draw.
    [code language=”cpp” firstline=”72″]
    if (fCaptureDev->checkNewFrame())
    {
    // Capture the current frame.
    const Surface8uRef rgbFrame = fCaptureDev->getSurface();
    // Find the objects
    // Convert rgb -> gray -> cv::Mat
    cv::Mat ocvGrayImage = toOcv(Channel(*rgbFrame));
    fClassifier->detectMultiScale(ocvGrayImage, fDetections);
    // Get the frame in a format OpenGL can draw, i.e. load it to GPU.
    fGlFrame->update(*rgbFrame);
    }
    [/code]
  5. Modify your app class’ draw() method.Do as little as possible here. It can interfere with user event responsiveness.
    [code language=”cpp” firstline=”90″]
    gl::color(1, 1, 1); // restore white color or the image is tinted
    gl::draw(fGlFrame);
    gl::color(0, 1, 0);
    for (const auto& detection : fDetections)
    {
    Rectf bounds(detection.tl().x,
    detection.tl().y,
    detection.br().x,
    detection.br().y);
    gl::drawStrokedCircle(bounds.getCenter(), bounds.getWidth() / 2);
    }
    [/code]

See the OpenCV site for tons of tutorials that will take you much farther than this.

+ more

Accurate Timing

Accurate Timing

In many tasks we need to do something at given intervals of time. The most obvious ways may not give you the best results. Time? Meh. The most basic tasks that don't have what you might call CPU-scale time requirements can be handled with the usual language and...

read more