cchacholiades cchacholiades - 4 months ago 70
C++ Question

How to use caffemodel with OpenCV on iOS?

I am trying to use a

alongside OpenCV on iOS devices. I found this github repository, but it can only be built with Xcode 6. I am working with Xcode 7, but I also downloaded Xcode 6 and still have no success on building it.

How can I use a caffemodel with OpenCV on iOS 9?

PS: The alternative would be this but it's written with swift & metal and I need to be able to use it with OpenCV.


You can use OpenCV DNN contrib module.

You need first to build OpenCV with contrib modules, you can find the steps here.

Then you can import and use the .caffemodel following this tutorial.

Here is an updated version of the tutorial, since it's not working as is:

#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace cv::dnn;
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
/* Find best class for the blob (i. e. class with maximal probability) */
void getMaxClass(dnn::Blob &probBlob, int *classId, double *classProb)
    Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix
    Point classNumber;
    minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
    *classId = classNumber.x;
std::vector<String> readClassNames(const char *filename = "synset_words.txt")
    std::vector<String> classNames;
    std::ifstream fp(filename);
    if (!fp.is_open())
        std::cerr << "File with classes labels not found: " << filename << std::endl;
    std::string name;
    while (!fp.eof())
        std::getline(fp, name);
        if (name.length())
            classNames.push_back( name.substr(name.find(' ')+1) );
    return classNames;
int main(int argc, char **argv)

    String modelTxt = "bvlc_googlenet.prototxt";
    String modelBin = "bvlc_googlenet.caffemodel";
    String imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";
    Ptr<dnn::Importer> importer;
    try                                     //Try to import Caffe GoogleNet model
        importer = dnn::createCaffeImporter(modelTxt, modelBin);
    catch (const cv::Exception &err)        //Importer can throw errors, we will catch them
        std::cerr << err.msg << std::endl;
    if (!importer)
        std::cerr << "Can't load network by using the following files: " << std::endl;
        std::cerr << "prototxt:   " << modelTxt << std::endl;
        std::cerr << "caffemodel: " << modelBin << std::endl;
        std::cerr << "bvlc_googlenet.caffemodel can be downloaded here:" << std::endl;
        std::cerr << "" << std::endl;
    dnn::Net net;
    importer.release();                     //We don't need importer anymore
    Mat img = imread(imageFile);
    if (img.empty())
        std::cerr << "Can't read image from the file: " << imageFile << std::endl;
    resize(img, img, Size(224, 224));                   //GoogLeNet accepts only 224x224 RGB-images
    dnn::Blob inputBlob = dnn::Blob(img);   //Convert Mat to dnn::Blob batch of images
    net.setBlob(".data", inputBlob);        //set the network input
    net.forward();                          //compute output
    dnn::Blob prob = net.getBlob("prob");   //gather output of "prob" layer
    int classId;
    double classProb;
    getMaxClass(prob, &classId, &classProb);//find the best class
    std::vector<String> classNames = readClassNames();
    std::cout << "Best class: #" << classId << " '" << << "'" << std::endl;
    std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
    return 0;
} //main