I had a problem compiling some code after updating the OS (Ubuntu 12.04-14.04) and reinstalling opencv.
A common problem is with the "loose" parts of opencv that I compiled from the 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 non-free libraries, as verified by cmake output:
However, when I try to 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;
Mat input;
vector<KeyPoint> keypoints;
Mat descriptor;
Mat featuresUnclustered;
SiftDescriptorExtractor detector(500);
for (directory_iterator itr(path_positive); itr!=directory_iterator(); ++itr)
{
filename = path_positive+itr->path().leaf().string();
input = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
detector.detect(input, keypoints);
detector.compute(input, keypoints,descriptor);
featuresUnclustered.push_back(descriptor);
}
for (directory_iterator itr(path_negative); itr!=directory_iterator(); ++itr)
{
filename = path_negative+itr->path().leaf().string();
input = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
detector.detect(input, keypoints);
detector.compute(input, keypoints,descriptor);
featuresUnclustered.push_back(descriptor);
}
int dictionarySize=10;
TermCriteria tc(CV_TERMCRIT_EPS,100,0.001);
int retries=1;
int flags=KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags);
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();
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 );
response.push_back( label );
}
}
}
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;
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);
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 make file:
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 as follows:
/etc/ld.so.conf.d/opencv.conf contains:
/usr/include
/usr/lib
after which I ran:
sudo ldconfig
This exact same error occurs when compiling a similar package in ROS with the following CMakesList.txt:
cmake_minimum_required(VERSION 2.8.3)
project(car_detector)
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)
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})
, , , - .
!