vector<CharImage> ImageGenerator::GenerateImages(const CharImage &base, unsigned numImages) const {

  cv::Mat cvImg = convertToMat(base);

  vector<CharImage> result;
  result.reserve(numImages);

  result.push_back(base);
  for (unsigned i = 0; i < numImages - 1; i++) {
    auto t = randomTransform(base);
    result.push_back(transformToCharImage(cvImg, t));
  }

  return result;
}
// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    GLUTWindowPtr gwin= GLUTWindow::create();
    gwin->setId(winid);
    gwin->init();

    // create the scene
    first = Node::create ();
    beginEditCP(first);
    first->setCore(Group::create());
    unsigned i;
    for (i=0; i<numFirst; ++i) {
       first->addChild(makePerturbedAll(4, 1.0f));
       //makeTransformedCube(1.0f,1.0f,1.0f,1,1,1, Color3f(1,0,0)));
    }
    endEditCP(first);
    second = Node::create ();
    beginEditCP(second);
    second->setCore(Group::create());
    for (i=0; i<numSecond; ++i) {
       second->addChild(makePerturbedAll(4, 1.0f, 0.0f));
       //makeTransformedCube(1.0f,1.0f,1.0f,1,1,1, Color3f(0,1,0)));
    }
    endEditCP(second);

    for (i=0; i<numFirst; ++i) {
      TransformPtr trf = TransformPtr::dcast(first->getChild(i)->getCore());
      beginEditCP(trf);
      randomTransform(trf->getMatrix());
      endEditCP(trf);
    }
    for (i=0; i<numSecond; ++i) {
      TransformPtr trf = TransformPtr::dcast(second->getChild(i)->getCore());
      beginEditCP(trf);
      randomTransform(trf->getMatrix());
      endEditCP(trf);
    }

    scene = Node::create ();
    beginEditCP(scene);
    scene->setCore(Group::create());
    scene->addChild(first);
    scene->addChild(second);
    endEditCP(scene);
    addRefCP(scene);
    SLOG << "scene created" << std::endl;

    // create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // tell the manager what to manage
    mgr->setWindow(gwin );
    mgr->setRoot  (scene);

    // show the whole scene
    mgr->showAll();

    // prepare for collision detection
    // * fill cache
    OSGCache::the().setHierarchy(NULL);
    OSGCache::the().apply(scene);
    SLOG << "cache filled." << std::endl;
    // * build hierarchy
    OSGCache::the().setHierarchy(&hier);
    OSGCache::the().apply(scene);
    SLOG << "adapters created.." << std::endl;
    // * create double traverser for collision detection
    traverser = new Traverser();
    traverser->setUseCoherency(false);             // do not use generalized front cache for frame coherency
    traverser->getDataTyped().setStopFirst(false);
#ifndef GV_WITH_RAPID
    SWARNING << "For RAPID support you have to define GV_WITH_RAPID (see Kernel/OSGGVBase.h)" 
	     << std::endl;
#endif
    // * create all traverser
    all = new AllTraverser<OpenSGTraits>();
    all->setDoubleTraverser(traverser);

    // GLUT main loop
    Profiler::the().Reset();
    glutMainLoop();
    
    return 0;
}