Linking opencv nonfree components (SIFT features and OCL specifically)

ianrust picture ianrust · Oct 24, 2014 · Viewed 8.9k times · Source

I am having trouble compiling some code after a OS upgrade (Ubuntu 12.04 to 14.04) and a re-install of opencv.

The general issue is with the "nonfree" parts of opencv which I compiled from source using the following procedure:

mkdir ~/OpenCV && cd ~/OpenCV
wget http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.10/opencv-2.4.10.zip
unzip opencv-2.4.10.zip
cd opencv-2.4.10
cmake -D WITH_CUDA=ON -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr .
make
sudo make install

This installs the nonfree libraries,as verified in the output of cmake:

-- General configuration for OpenCV 2.4.10 =====================================
--   Version control:               unknown
-- 
--   Platform:
--     Host:                        Linux 3.13.0-37-generic x86_64
--     CMake:                       2.8.12.2
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               RELEASE
-- 
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ Compiler:                /usr/bin/c++  (ver 4.8.2)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -msse -msse2 -msse3 -ffunction-sections -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wno-narrowing -Wno-delete-non-virtual-dtor -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -msse -msse2 -msse3 -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /usr/bin/cc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -msse -msse2 -msse3 -ffunction-sections -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wno-narrowing -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -msse -msse2 -msse3 -ffunction-sections -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):      
--     Linker flags (Debug):        
--     Precompiled headers:         YES
-- 
--   OpenCV modules:
--     To be built:                 core flann imgproc highgui features2d calib3d ml video legacy objdetect photo gpu ocl nonfree contrib python stitching superres ts videostab
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 androidcamera dynamicuda java viz
-- 
--   GUI: 
--     QT:                          NO
--     GTK+ 2.x:                    YES (ver 2.24.23)
--     GThread :                    YES (ver 2.40.0)
--     GtkGlExt:                    NO
--     OpenGL support:              NO
--     VTK support:                 NO
-- 
--   Media I/O: 
--     ZLib:                        /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.8)
--     JPEG:                        /usr/lib/x86_64-linux-gnu/libjpeg.so (ver )
--     PNG:                         /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.2.50)
--     TIFF:                        /usr/lib/x86_64-linux-gnu/libtiff.so (ver 42 - 4.0.3)
--     JPEG 2000:                   /usr/lib/x86_64-linux-gnu/libjasper.so (ver 1.900.1)
--     OpenEXR:                     /usr/lib/x86_64-linux-gnu/libImath.so /usr/lib/x86_64-linux-gnu/libIlmImf.so /usr/lib/x86_64-linux-gnu/libIex.so /usr/lib/x86_64-linux-gnu/libHalf.so /usr/lib/x86_64-linux-gnu/libIlmThread.so (ver 1.6.1)
-- 
--   Video I/O:
--     DC1394 1.x:                  NO
--     DC1394 2.x:                  YES (ver 2.2.1)
--     FFMPEG:                      YES
--       codec:                     YES (ver 54.35.0)
--       format:                    YES (ver 54.20.4)
--       util:                      YES (ver 52.3.0)
--       swscale:                   YES (ver 2.1.1)
--       gentoo-style:              YES
--     GStreamer:                   NO
--     OpenNI:                      NO
--     OpenNI PrimeSensor Modules:  NO
--     PvAPI:                       NO
--     GigEVisionSDK:               NO
--     UniCap:                      NO
--     UniCap ucil:                 NO
--     V4L/V4L2:                    NO/YES
--     XIMEA:                       NO
--     Xine:                        NO
-- 
--   Other third-party libraries:
--     Use IPP:                     NO
--     Use Eigen:                   YES (ver 3.2.0)
--     Use TBB:                     NO
--     Use OpenMP:                  NO
--     Use GCD                      NO
--     Use Concurrency              NO
--     Use C=:                      NO
--     Use Cuda:                    NO
--     Use OpenCL:                  YES
-- 
--   OpenCL:
--     Version:                     dynamic
--     Include path:                /home/ian/Downloads/opencv-2.4.10/3rdparty/include/opencl/1.2
--     Use AMD FFT:                 NO
--     Use AMD BLAS:                NO
-- 
--   Python:
--     Interpreter:                 /usr/bin/python2 (ver 2.7.6)
--     Libraries:                   /usr/lib/x86_64-linux-gnu/libpython2.7.so (ver 2.7.6)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.8.2)
--     packages path:               lib/python2.7/dist-packages
-- 
--   Java:
--     ant:                         NO
--     JNI:                         NO
--     Java tests:                  NO
-- 
--   Documentation:
--     Build Documentation:         NO
--     Sphinx:                      NO
--     PdfLaTeX compiler:           /usr/bin/pdflatex
-- 
--   Tests and samples:
--     Tests:                       YES
--     Performance tests:           YES
--     C/C++ Examples:              NO
-- 
--   Install path:                  /usr
-- 
--   cvconfig.h is in:              /home/ian/Downloads/opencv-2.4.10
-- -----------------------------------------------------------------
-- 

However, when I try and compile the following code:

#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include <opencv2/nonfree/nonfree.hpp>
#include "boost/filesystem.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;
using namespace boost::filesystem;

void createDicitonary(Mat & dictionary, string path_positive, string path_negative)
{
    string filename;      
    //to store the current input image
    Mat input;    

    //To store the keypoints that will be extracted by SIFT
    vector<KeyPoint> keypoints;
    //To store the SIFT descriptor of current image
    Mat descriptor;
    //To store all the descriptors that are extracted from all the images.
    Mat featuresUnclustered;
    //The SIFT feature extractor and descriptor
    SiftDescriptorExtractor detector(500);  

    for (directory_iterator itr(path_positive); itr!=directory_iterator(); ++itr)
    {
        filename = path_positive+itr->path().leaf().string();
        //open the file
        input = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); //Load as grayscale      
        //detect feature points
        detector.detect(input, keypoints);
        //compute the descriptors for each keypoint
        detector.compute(input, keypoints,descriptor);        
        //put the all feature descriptors in a single Mat object 
        featuresUnclustered.push_back(descriptor);        
    }    

    for (directory_iterator itr(path_negative); itr!=directory_iterator(); ++itr)
    {
        filename = path_negative+itr->path().leaf().string();
        //open the file
        input = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); //Load as grayscale         
        //detect feature points
        detector.detect(input, keypoints);
        //compute the descriptors for each keypoint
        detector.compute(input, keypoints,descriptor);        
        //put the all feature descriptors in a single Mat object 
        featuresUnclustered.push_back(descriptor);        
    }

    //Construct BOWKMeansTrainer
    //the number of bags
    int dictionarySize=10;
    //define Term Criteria
    TermCriteria tc(CV_TERMCRIT_EPS,100,0.001);
    //retries number
    int retries=1;
    //necessary flags
    int flags=KMEANS_PP_CENTERS;
    //Create the BoW (or BoF) trainer
    BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags);
    //cluster the feature vectors
    dictionary=bowTrainer.cluster(featuresUnclustered);
}

void labelSamples(string path,Mat & train,Mat & response,int label, Mat & dictionary)
{
    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
    Ptr<DescriptorExtractor> extractor = new SiftDescriptorExtractor();
    BOWImgDescriptorExtractor dextract( extractor, matcher );
    SiftFeatureDetector detector(500);

    for (directory_iterator itr(path); itr!=directory_iterator(); ++itr)
    {
        string filename = path+itr->path().leaf().string();

        // set training data using BOWImgDescriptorExtractor
        dextract.setVocabulary( dictionary );
        std::vector<KeyPoint> keypoints;
        Mat img = imread( filename, CV_LOAD_IMAGE_GRAYSCALE );
        detector.detect( img, keypoints);
        Mat desc;
        dextract.compute( img, keypoints, desc );
        if ( !desc.empty() )
        {
            train.push_back( desc );            // update training data
            response.push_back( label );        // update response data
        }
    }
}

int main(int argc, char* argv[])
{

  cout << "Starting Training" << std::endl;

  if (argc != 3)
  {
    std::cout << "Error: please use the program as such: cartrainer path-to-positive-director path-to-negative-directory" << std::endl;
    return 1;
  }

  std::string pos(argv[1]);
  std::string neg(argv[2]);

  if (!is_directory(pos))
  {
    std::cout << "Error: " << pos << "not a directory" << std::endl;
    return 1;    
  }

  if (!is_directory(neg))
  {
    std::cout << "Error: " << neg << "not a directory" << std::endl;
    return 1;    
  }

  Mat dictionary;

  createDicitonary(dictionary,pos,neg);
  cout << "Created dictionary" << std::endl;

  Mat train,response;

  labelSamples(pos,train,response,1,dictionary);
  cout << "Labelled Positive Samples" << std::endl;

  labelSamples(neg,train,response,-1,dictionary);
  cout << "Labelled Negative Samples" << std::endl;

  // svm parameters
  CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
  CvSVMParams svm_param = CvSVMParams( CvSVM::EPS_SVR, CvSVM::LINEAR, 10.0, 8.0, 1.0, 10.0, 0.5, 0.0001, NULL, criteria);

  // train svm
  cv::SVM svm;
  svm.train(train, response,cv::Mat(),cv::Mat(),svm_param);
  svm.save("svm-car-classifier.xml");

  FileStorage fs("training_data.yml", FileStorage::WRITE);

  fs << "dictionary" << dictionary;
  fs << "train" << train;
  fs << "response" << response;
  fs.release();

  return 0;
}

with the following makefile:

CC = g++
LINK = g++
INSTALL = install
CFLAGS = `pkg-config opencv --cflags` -I /usr/include/boost-1_46 -I.
LFLAGS = `pkg-config opencv --libs` -L /usr/lib -L /opt/ros/indigo/lib -lboost_system -lboost_filesystem -lopencv_features2d -lopencv_nonfree -lopencv_ocl
all: cartrainer

TrainClassifier.o: TrainClassifier.cpp
    $(CC) $(CFLAGS) -o $@ -c $^

cartrainer: TrainClassifier.o
    $(LINK) -o $@ $^ $(LFLAGS)

clean:
    rm -f cartrainer *.o

install:
    cp cartrainer ~/usr/bin/

In the following way:

make

I get the following errors:

/usr/lib/libopencv_nonfree.so: undefined reference to `cv::ocl::integral(cv::ocl::oclMat const&, cv::ocl::oclMat&)'
collect2: error: ld returned 1 exit status
make: *** [cartrainer] Error 1

I tried adding it to my ldconfig in the following way:

/etc/ld.so.conf.d/opencv.conf contains:

/usr/include
/usr/lib

after which I ran:

sudo ldconfig

This exact same error also occurs when I compile a similar package in ROS with the following CMakesList.txt:

cmake_minimum_required(VERSION 2.8.3)
project(car_detector)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS 
    roscpp 
    std_msgs
    message_generation
    camera_capture
    cv_bridge
    image_transport
    image_util
    lib_map_interface
)

find_package(OpenCV REQUIRED)

# Generate messages in the 'msg' folder
add_message_files(
    FILES
    CarDetection.msg
    CarDetections.msg
 )

generate_messages(DEPENDENCIES std_msgs geometry_msgs)

catkin_package(CATKIN_DEPENDS message_runtime std_msgs image_util lib_map_interface)

include_directories(${catkin_INCLUDE_DIRS}
    ${lib_map_interface_INCLUDE_DIRS})

add_executable(node_car_detector NodeCarDetector.cpp)
target_link_libraries(node_car_detector ${catkin_LIBRARIES} libimage_util)
add_dependencies(node_car_detector ${catkin_EXPORTED_TARGETS})

add_executable(node_car_classifier NodeCarClassifier.cpp)
target_link_libraries(node_car_classifier ${catkin_LIBRARIES} ${OpenCV_LIBS} libimage_util lib_map_interface)
add_dependencies(node_car_classifier ${catkin_EXPORTED_TARGETS})

I'm not sure what else to try so I'd really appreciate it if someone had any ideas

Thanks so much!

Answer

ianrust picture ianrust · Oct 29, 2014

I fixed it.

I needed to turn off the CUDA/OpenCL components of opencv. So instead of running Cmake like this:

cmake -D WITH_CUDA=ON -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr .

I ran it like this:

cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_OPENCL=OFF -D CMAKE_INSTALL_PREFIX=/usr/local .

And everything compiled just fine!