I am trying to set up a bag of visual words using openCV 3.0. I have looked a bit everywhere and all I seem to be able to find is code that is only compatible with versions in the 2.x domain. As of now this is what I have:
#include <opencv2/core/core.hpp>
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int argc, const char** argv) {
Ptr<FeatureDetector> features;
Ptr<DescriptorExtractor> descriptors;
Ptr<DescriptorMatcher> matcher;
int MAX_ITER = 100;
int EPS = 2;
TermCriteria tc(MAX_ITER + EPS,1,0.001);
int dictSize = 1000;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictSize,tc,retries,flags);
BOWImgDescriptorExtractor bowDE(descriptors,matcher);
Mat img1 = imread("/Users/Lucas/Desktop/pic2.jpg");
Mat img2 = imread("/Users/Lucas/Desktop/2.jpg");
vector<KeyPoint> keypoints,keypoints2;
features->detect(img1, keypoints);
features->detect(img2, keypoints2);
Mat myFeatures;
Mat myFeatures2;
descriptors->compute(img1, keypoints, myFeatures);
descriptors->compute(img2, keypoints2, myFeatures2);
bowTrainer.add(myFeatures);
bowTrainer.add(myFeatures2);
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
cout << dictionary << endl;
return 0;
}
I have put this together by using a few tutorials and snippets, but I am running into an issue. When the program gets to
features->detect(img1, keypoints);
it exits with a segmentation fault 11, whatever that means. Could someone help me and point out what it is I am doing wrong?
you have to create your FeatureDetector, DescriptorExtractor first. atm, you got null-pointer instances (that's your segfault).
#include <opencv2/xfeatures2d.hpp>
...
Ptr<FeatureDetector> features = xfeatures2d::SIFT::create();
Ptr<DescriptorExtractor> descriptors = xfeatures2d::SIFT::create();
Ptr<DescriptorMatcher> matcher = makePtr<BFMatcher>(NORM_L2);
note, that since you have to use SIFT or SURF, you will need the opencv_contrib repo installed for this
Related
I am trying the compile the following code to compute the chamfer distance. However I get the following error while compiling it. I am using opencv-3.2 on ubuntu 18.04, 64 bit.
fatal error: opencv2/contrib/contrib.hpp: No such file or directory
Synaptic package manager says that libopencv-contrib-dev and libopencv-contrib-3.2 are installed at /usr/include/opencv2 and /usr/lib/x86_64-linux-gnu respectively. I checked for contrib.hpp but found no file or folder named contrib in these locations.
The code for the chamfer distance computation is as below:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, const char** argv )
{
Mat img = imread(argv[1], 0);
Mat tpl = imread(argv[2], 0);
Mat cimg;
cvtColor(img, cimg, CV_GRAY2BGR);
vector<vector<Point> > results;
vector<float> costs;
int best = chamerMatching( img, tpl, results, costs );
return 0;
}
My question is: How to add the correct headers and get the above chamfer distance code working in opencv 3.2?
It looks like the contrib module is not available in OpenCV 3.2. This module was removed in OpenCV 4.0 and is no longer part of the library. If you want to use the Chamfer matching algorithm in your code, you can try using the matchShapes function from the imgproc module instead. This function can be used to compare the shapes of two contours and return a measure of their similarity:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, const char** argv )
{
Mat img = imread(argv[1], 0);
Mat tpl = imread(argv[2], 0);
// Find the contours of the images
vector<vector<Point> > img_contours;
vector<vector<Point> > tpl_contours;
findContours(img, img_contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
findContours(tpl, tpl_contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
// Compute the Chamfer distance between the contours
double chamfer = matchShapes(img_contours[0], tpl_contours[0], CHAMFER_DIST_L2, 0);
cout << "Chamfer distance: " << chamfer << endl;
return 0;
}
I'm trying to create Bag-Of-Words so I can train the SVM later. I'm new with OpenCV so I used a code that I found on the Internet. The problem is that I have the following error:
OpenCV Error: Assertion failed (!_descriptors.empty()) in add, file /build/buildd/opencv-2.4.8+dfsg1/modules/features2d/src/bagofwords.cpp, line 57
terminate called after throwing an instance of 'cv::Exception'
what(): /build/buildd/opencv-2.4.8+dfsg1/modules/features2d/src/bagofwords.cpp:57: error: (-215) !_descriptors.empty() in function add
Aborted (core dumped)
And here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Ptr<FeatureDetector> features = FeatureDetector::create("FAST");
Ptr<DescriptorExtractor> descriptors = DescriptorExtractor::create("FAST");
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
//defining terms for bowkmeans trainer
TermCriteria tc(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 0.001);
int dictionarySize = 1000;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bow_trainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(descriptors, matcher);
//training data now
Mat mat_features1, mat_features2;
Mat img = imread("../positive_images/2014-12-07 19-55-07 804ea51d (1).JPG", 0);
Mat img2 = imread("../positive_images/Pictures23.bmp_0000_0342_0104_0564_0543.png", 0);
vector<KeyPoint> keypoints, keypoints2;
features->detect(img, keypoints);
features->detect(img2,keypoints2);
descriptors->compute(img, keypoints, mat_features1);
descriptors->compute(img2, keypoints2, mat_features2);
bow_trainer.add(mat_features1);
bow_trainer.add(mat_features2);
Mat dictionary = bow_trainer.cluster();
bowDE.setVocabulary(dictionary);
return 0;
}
And here is how the code is compiled:
g++ BOW_creator.cpp -o BOW_creator `pkg-config --cflags --libs opencv`
Do you know what the problem could be? Can you tell me how to fix it?
Let me know if you need me to provide more information.
I'm trying using SURF feature detector but I'm always getting this error-
The program '[1120] Corner Detection.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
Here is the code
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2\nonfree\nonfree.hpp"
using namespace cv;
using namespace std;
void foo(Mat &image1, Mat &image2)
{
int minHeassian = 400;
SurfFeatureDetector detector(minHeassian);
std::vector< KeyPoint > keypoints1, keypoints2;
keypoints1.resize(1000);
keypoints2.resize(1000);
detector.detect(image1, keypoints1); // <--- crashes at this line
detector.detect(image2, keypoints2); // <--- probably will crash here too
SurfDescriptorExtractor extractor;
Mat discriptors1, discriptors2;
extractor.compute(image1, keypoints1, discriptors1);
extractor.compute(image2, keypoints2, discriptors2);
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match(discriptors1, discriptors2, matches);
double minDist = 100;
for (int i = 0; i < matches.size(); ++i)
if (matches[i].distance < minDist)
minDist = matches[i].distance;
std::vector< DMatch > goodMatches;
for (int i = 0; i < matches.size(); ++i)
if (matches[i].distance <= max(0.02, (double)matches[i].distance))
goodMatches.push_back(matches[i]);
Mat matchImage;
drawMatches(image1, keypoints1, image2, keypoints2,
goodMatches, matchImage,
Scalar::all(-1), Scalar::all(-1), vector<char>(),
DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
namedWindow("Matches", WINDOW_AUTOSIZE);
imshow("Matches", matchImage);
waitKey(0);
}
int _tmain(int argc, _TCHAR* argv[])
{
cv::initModule_nonfree();
Mat left, right;
right = imread("D:\\right.jpg", IMREAD_COLOR);
left = imread("D:\\left.jpg", IMREAD_COLOR);
foo(left, right);
return 0;
}
I get the error at the line
detector.detect(image1, keypoints1);
I have following lib files mentioned to linker-
opencv_core249d.lib
opencv_imgproc249d.lib
opencv_highgui249d.lib
opencv_ml249d.lib
opencv_video249d.lib
opencv_features2d249d.lib
opencv_calib3d249d.lib
opencv_objdetect249d.lib
opencv_contrib249d.lib
opencv_legacy249d.lib
opencv_flann249d.lib
opencv_features2d249.lib
opencv_nonfree249.lib
I have tried everything I found on the Internet but nothing worked. What is wrong with this code?
I'm running VS 2013 on Windows 8.1 and I'm using OpenCV version 2.4.9.
Solved
It was a silly mistake. I used the library opencv_nonfree249.lib whereas I should be using opencv_nonfree249**d**.lib as I was working in debug mode.
You are using the library opencv_nonfree249.lib in a debug environment which is meant for release environment. Add a d to the lib name to make it opencv_nonfree249d.lib which will work for debug environment.
Why do the SIFT and SURF detectors crash?
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
Mat image = imread("TestImage.jpg");
// Create smart pointer for SIFT feature detector.
Ptr<FeatureDetector> featureDetector = FeatureDetector::create("SIFT");
vector<KeyPoint> keypoints;
// Detect the keypoints
featureDetector->detect(image, keypoints); // here crash
// ...
}
The error is Segmentation fault (core dumped). I use OpenCV 2.4.8, gcc 4.9 and Ubuntu. If I use the other types of features it runs normally. What am I missing?
Have you tried to call initModule_nonfree()?
#include <opencv2/nonfree/nonfree.hpp>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
initModule_nonfree();
Mat image = imread("TestImage.jpg");
// Create smart pointer for SIFT feature detector.
Ptr<FeatureDetector> featureDetector = FeatureDetector::create("SIFT");
vector<KeyPoint> keypoints;
// Detect the keypoints
featureDetector->detect(image, keypoints); // here crash
// ...
}
Also, you didnt check the pointer featureDetector which is probably null (since you have not called initModule).
I am trying to make the follwing Code by Mohammad Reza Mostajabi (http://alum.sharif.ir/~mostajabi/Tutorial.html) run under Ubuntu 12.04 with OpenCV 2.4.6.1. I made some minor changes with the libraries included and added "cv::initModule_nonfree()" right after starting the main file.
#include "cv.h"
#include "highgui.h"
#include "ml.h"
#include <stdio.h>
#include <iostream>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <vector>
using namespace cv;
using namespace std;
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
char ch[30];
//--------Using SURF as feature extractor and FlannBased for assigning a new point to the nearest one in the dictionary
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor();
SurfFeatureDetector detector(500);
//---dictionary size=number of cluster's centroids
int dictionarySize = 1500;
TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(extractor, matcher);
void collectclasscentroids() {
IplImage *img;
int i,j;
for(j=1;j<=4;j++)
for(i=1;i<=60;i++){
sprintf( ch,"%s%d%s%d%s","train/",j," (",i,").jpg");
const char* imageName = ch;
img = cvLoadImage(imageName,0);
vector<KeyPoint> keypoint;
detector.detect(img, keypoint);
Mat features;
extractor->compute(img, keypoint, features);
bowTrainer.add(features);
}
return;
}
int main(int argc, char* argv[])
{
cv::initModule_nonfree();
int i,j;
IplImage *img2;
cout<<"Vector quantization..."<<endl;
collectclasscentroids();
vector<Mat> descriptors = bowTrainer.getDescriptors();
int count=0;
for(vector<Mat>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
count+=iter->rows;
}
cout<<"Clustering "<<count<<" features"<<endl;
//choosing cluster's centroids as dictionary's words
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
cout<<"extracting histograms in the form of BOW for each image "<<endl;
Mat labels(0, 1, CV_32FC1);
Mat trainingData(0, dictionarySize, CV_32FC1);
int k=0;
vector<KeyPoint> keypoint1;
Mat bowDescriptor1;
//extracting histogram in the form of bow for each image
for(j=1;j<=4;j++)
for(i=1;i<=60;i++){
sprintf( ch,"%s%d%s%d%s","train/",j," (",i,").jpg");
const char* imageName = ch;
img2 = cvLoadImage(imageName,0);
detector.detect(img2, keypoint1);
bowDE.compute(img2, keypoint1, bowDescriptor1);
trainingData.push_back(bowDescriptor1);
labels.push_back((float) j);
}
//Setting up SVM parameters
CvSVMParams params;
params.kernel_type=CvSVM::RBF;
params.svm_type=CvSVM::C_SVC;
params.gamma=0.50625000000000009;
params.C=312.50000000000000;
params.term_crit=cvTermCriteria(CV_TERMCRIT_ITER,100,0.000001);
CvSVM svm;
printf("%s\n","Training SVM classifier");
bool res=svm.train(trainingData,labels,cv::Mat(),cv::Mat(),params);
cout<<"Processing evaluation data..."<<endl;
Mat groundTruth(0, 1, CV_32FC1);
Mat evalData(0, dictionarySize, CV_32FC1);
k=0;
vector<KeyPoint> keypoint2;
Mat bowDescriptor2;
Mat results(0, 1, CV_32FC1);;
for(j=1;j<=4;j++)
for(i=1;i<=60;i++){
sprintf( ch,"%s%d%s%d%s","eval/",j," (",i,").jpg");
const char* imageName = ch;
img2 = cvLoadImage(imageName,0);
detector.detect(img2, keypoint2);
bowDE.compute(img2, keypoint2, bowDescriptor2);
evalData.push_back(bowDescriptor2);
groundTruth.push_back((float) j);
float response = svm.predict(bowDescriptor2);
results.push_back(response);
}
//calculate the number of unmatched classes
double errorRate = (double) countNonZero(groundTruth- results) / evalData.rows;
printf("%s%f","Error rate is ",errorRate);
return 0;
}
After doing this I can compile the Code without problems. I can also run it within Eclipse, but once I try to make it work in terminal I get the following error message:
" OpenCV Error: Assertion failed (!_descriptors.empty()) in add, file /home/mark/Downloads/FP/opencv-2.4.6.1/modules/features2d/src/bagofwords.cpp, line 57
terminate called after throwing an instance of 'cv::Exception'
what(): /home/mark/Downloads/FP/opencv-2.4.6.1/modules/features2d/src/bagofwords.cpp:57: error: (-215) !_descriptors.empty() in function add "
I've been trying to solve the problem for a few days now, but I just cannot get rid of this error. I also tried to do it with CodeBlocks, which gives me the same error. I would appreciate some help very much!
Thanks!
It's possible that your program fails to load input images (when launched from the terminal window) because it can't find them. Make sure that your input images are copied to the directory from which you run the application. Eclipse may have a different home directory and hence it sees the image when the program is started in Eclipse.