Visual Servoing Platform  version 3.6.1 under development (2024-11-16)
Tutorial: How to create a basic iOS application that uses ViSP
Note
We assume that you have "ViSP for iOS" either after following Tutorial: Installation from prebuilt packages for iOS devices or Tutorial: Installation from source for iOS devices. Following one of these tutorials allows to exploit visp3.framework and opencv2.framework to build an application for iOS devices.

In this tutorial we suppose that you install visp3.framework in a folder named <framework_dir>/ios. If <framework_dir> corresponds to $HOME/framework, you should get the following:

$ ls $HOME/framework/ios
opencv2.framework         visp3.framework

Note that all the material (source code and Xcode project) described in this tutorial is part of ViSP source code (in tutorial/ios/GettingStarted folder) and could be found in https://github.com/lagadic/visp/tree/master/tutorial/ios/GettingStarted.

Create a new Xcode project

  • Launch Xcode
  • Follow "File > New > Project" menu and create a new iOS "App"
  • Click on "Next" button and complete the options for your new project:
  • Click on "Next" button and select the folder where the new project will be saved. Once done click on "Create". Now you should have something similar to:

Linking ViSP framework

Now we need to link visp3.framework with the Xcode project.

  • Select the project navigator in the left hand panel (1) and click on project name "Getting Started" (2)
  • Use the Finder to drag & drop ViSP and OpenCV frameworks located in <framework_dir>/ios folder in the left hand panel containing all the project files.
  • In the dialog box, enable check box "Copy item if needed" to ease visp3.framework and opencv2.framework headers location addition to the build options
  • Click on "Finish". You should now get something similar to the following image

Writing a ViSP iOS application

  • Because we will mix Objective-C and ViSP C++ Code, rename ViewController.m file into ViewController.mm
  • Now copy/paste $VISP_WS/visp/tutorial/ios/GettingStarted/GettingStarted/ViewController.mm file content into ViewController.mm. Note that this Objective-C code is inspired from tutorial-homography-from-points.cpp.
    /*
    * ViSP, open source Visual Servoing Platform software.
    * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
    *
    * This software is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    * See the file LICENSE.txt at the root directory of this source
    * distribution for additional information about the GNU GPL.
    *
    * For using ViSP with software that can not be combined with the GNU
    * GPL, please contact Inria about acquiring a ViSP Professional
    * Edition License.
    *
    * See https://visp.inria.fr for more information.
    *
    * This software was developed at:
    * Inria Rennes - Bretagne Atlantique
    * Campus Universitaire de Beaulieu
    * 35042 Rennes Cedex
    * France
    *
    * If you have questions regarding the use of this file, please contact
    * Inria at visp@inria.fr
    *
    * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    */
    #ifndef DOXYGEN_SHOULD_SKIP_THIS
    #import "ViewController.h"
    #ifdef __cplusplus
    #import <visp3/visp.h>
    #endif
    @interface ViewController ()
    @end
    @implementation ViewController
    #pragma mark - Example of a function that uses ViSP
    - (void)processViSPHomography{
    std::vector<vpPoint> oP(4), aP(4), bP(4);
    double L = 0.1;
    oP[0].setWorldCoordinates( -L,-L, 0);
    oP[1].setWorldCoordinates(2*L,-L, 0);
    oP[2].setWorldCoordinates( L, 3*L, 0);
    oP[3].setWorldCoordinates( -L, 4*L, 0);
    vpHomogeneousMatrix bMo(0,0, 1, 0, 0, 0) ;
    vpHomogeneousMatrix aMb(0.2, 0, 0.1, 0,vpMath::rad(20), 0);
    vpHomogeneousMatrix aMo = aMb*bMo ;
    // Normalized coordinates of points in the image frame
    std::vector<double> xa(4), ya(4), xb(4), yb(4);
    for(int i=0 ; i < 4; i++){
    oP[i].project(aMo);
    xa[i] = oP[i].get_x();
    ya[i] = oP[i].get_y();
    oP[i].project(bMo);
    xb[i] = oP[i].get_x();
    yb[i] = oP[i].get_y();
    }
    // Compute the homography
    vpHomography::DLT(xb, yb, xa, ya, aHb, true);
    std::cout << "Homography:\n" << aHb << std::endl;
    // Compute the 3D transformation
    aHb.computeDisplacement(aRb, atb, n);
    std::cout << "atb: " << atb.t() << std::endl;
    // Compute coordinates in pixels of point 3
    vpImagePoint iPa, iPb;
    vpMeterPixelConversion::convertPoint(cam, xb[3], yb[3], iPb);
    vpMeterPixelConversion::convertPoint(cam, xa[3], ya[3], iPa);
    std::cout << "Ground truth:" << std::endl;
    std::cout << " Point 3 in pixels in frame b: " << iPb << std::endl;
    std::cout << " Point 3 in pixels in frame a: " << iPa << std::endl;
    // Estimate the position in pixel of point 3 from the homography
    vpMatrix H = cam.get_K() * aHb * cam.get_K_inverse();
    // Project the position in pixel of point 3 from the homography
    std::cout << "Estimation from homography:" << std::endl;
    std::cout << " Point 3 in pixels in frame a: " << vpHomography::project(cam, aHb, iPb) << std::endl;
    }
    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self processViSPHomography];
    }
    - (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }
    @end
    #endif
    Generic class defining intrinsic camera parameters.
    vpMatrix get_K_inverse() const
    vpMatrix get_K() const
    Implementation of column vector and the associated operations.
    Definition: vpColVector.h:191
    Implementation of an homogeneous matrix and operations on such kind of matrices.
    Implementation of an homography and operations on homographies.
    Definition: vpHomography.h:174
    static void DLT(const std::vector< double > &xb, const std::vector< double > &yb, const std::vector< double > &xa, const std::vector< double > &ya, vpHomography &aHb, bool normalization=true)
    void computeDisplacement(vpRotationMatrix &aRb, vpTranslationVector &atb, vpColVector &n)
    static vpImagePoint project(const vpCameraParameters &cam, const vpHomography &bHa, const vpImagePoint &iPa)
    Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
    Definition: vpImagePoint.h:82
    static double rad(double deg)
    Definition: vpMath.h:129
    Implementation of a matrix and operations on matrices.
    Definition: vpMatrix.h:169
    static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
    Implementation of a rotation matrix and operations on such kind of matrices.
    Class that consider the case of a translation vector.
    vpRowVector t() const
    In this sample, we first import the headers to use vpHomography class. Then we create a new function called processViSPHomography(). This function is finally called in viewDibLoad().
  • After the previous copy/paste, you should have something similar to
  • Now we are ready to build this simple "Getting Started" application using Xcode "Product > Build" menu.
    Note
    Here it may be possible that you get a build issue iOS error: libxml/parser.h not found. Just follow the link to see how to fix this issue.
  • You can now run your code using "Product > Run" menu (Simulator or device does not bother because we are just executing code). You should obtain these logs showing that visp code was correctly executed by your iOS project.
  • if you don't see the output (1) presented in the red rectangle in the previous image, you may click on icon (2) to display All Output.

Known issues

iOS error: libxml/parser.h not found

If you encounter the following issue iOS error: libxml/parser.h not found

the solution to this problem is to add libxml path. To this end, as shown in the next image:

  • Select the project navigator in the left hand panel (1)
  • Click on the project name (2)
  • Click on the project name here also (3)
  • Select "Build Settings" panel (4)
  • Select "All" and "Combined" settings view (5)
  • Enter "header search" in the search tool bar (6)
  • In "Header Search Paths" press + button for "Debug" and "Release" configurations and add a new line (7):
    ${SDK_ROOT}/usr/include/libxml2
  • Then clean and build again. Issue should be fixed.

Next tutorial

You are now ready to see the Tutorial: Image processing on iOS.