Text detection from complex background - c++

I have the following code which calculates the Daubechie 4 wavelet transformation images(LL,LH, HL, HH subbands) and energy features. In this paper is a tutorial about how to detect text from complex background, but I don't have any idea how to continue this. Could somebody help me, maybe to explain how I calculate wavelet energy histogram of an image or with ideas about how to implement what is on the paper?
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include <math.h>
#define h0 (1+sqrt(3))/(4*sqrt(2))
#define h1 (3+sqrt(3))/(4*sqrt(2))
#define h2 (3-sqrt(3))/(4*sqrt(2))
#define h3 (1-sqrt(3))/(4*sqrt(2))
#define g0 h3
#define g1 -h2
#define g2 h1
#define g3 -h0
using namespace std;
using namespace cv;
vector<Mat> wavelet(Mat im)
{
float a,b,c,d,e,f;
Mat im1, im2, im3, im4, im5, im6;
Mat imi=Mat::zeros(im.rows,im.cols,CV_8U);
im.copyTo(imi);
im.convertTo(im,CV_32F,1.0,0.0);
im1=Mat::zeros(im.rows/4,im.cols,CV_32F);
im2=Mat::zeros(im.rows/4,im.cols,CV_32F);
im3=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
im4=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
im5=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
im6=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
for(int rcnt=0;rcnt+3<im.rows;rcnt+=4)
{
for(int ccnt=0;ccnt<im.cols;ccnt++)
{
a=im.at<float>(rcnt,ccnt);
b=im.at<float>(rcnt+1,ccnt);
c=im.at<float>(rcnt+2,ccnt);
d=im.at<float>(rcnt+3,ccnt);
e=(a*h0)+(b*h1)+(c*h2)+(d*h3);
f=(a*g0)+(b*g1)+(c*g2)+(d*g3);
int _rcnt=rcnt/4;
im1.at<float>(_rcnt,ccnt)=e;
im2.at<float>(_rcnt,ccnt)=f;
}
}
for(int rcnt=0;rcnt<im.rows/4;rcnt++)
{
for(int ccnt=0;ccnt+3<im.cols;ccnt+=4)
{
a=im1.at<float>(rcnt,ccnt);
b=im1.at<float>(rcnt,ccnt+1);
c=im1.at<float>(rcnt,ccnt+2);
d=im1.at<float>(rcnt,ccnt+3);
e=(a*h0)+(b*h1)+(c*h2)+(d*h3);
f=(a*g0)+(b*g1)+(c*g2)+(d*g3);
int _ccnt=ccnt/4;
im3.at<float>(rcnt,_ccnt)=e;
im4.at<float>(rcnt,_ccnt)=f;
}
}
for(int rcnt=0;rcnt<im.rows/4;rcnt++)
{
for(int ccnt=0;ccnt+3<im.cols;ccnt+=4)
{
a=im2.at<float>(rcnt,ccnt);
b=im2.at<float>(rcnt,ccnt+1);
c=im2.at<float>(rcnt,ccnt+2);
d=im2.at<float>(rcnt,ccnt+3);
e=(a*h0)+(b*h1)+(c*h2)+(d*h3);
f=(a*g0)+(b*g1)+(c*g2)+(d*g3);
int _ccnt=ccnt/4;
im5.at<float>(rcnt,_ccnt)=e;
im6.at<float>(rcnt,_ccnt)=f;
}
}
Mat LL = Mat(im3);
Mat LH = Mat(im4);
Mat HL = Mat(im5);
Mat HH = Mat(im6);
LL.convertTo(LL,CV_8U);
LH.convertTo(LH,CV_8U);
HL.convertTo(HL,CV_8U);
HH.convertTo(HH,CV_8U);
vector<Mat> elements;
elements.push_back(LL);
elements.push_back(LH);
elements.push_back(HL);
elements.push_back(HH);
return elements;
}
int main(int argc, char **argv)
{
Mat image = imread(argv[1],0);
vector<Mat> subbands = wavelet(image);
int rows = subbands[0].rows;
int cols = subbands[0].cols;
Mat energy(rows,cols,CV_8UC1);
for (int i=0;i<rows;i++)
{
for (int j=0;j<cols;j++)
{
int x=subbands[1].at<uchar>(i,j);
int y=subbands[2].at<uchar>(i,j);
int z=subbands[3].at<uchar>(i,j);
energy.at<uchar>(i,j)=sqrt(x*x+y*y+z*z);
}
}
imshow("energy",energy);
waitKey(0);
}

Related

How can I convert a CImg image to an itkImage?

I have a CImg image (with double values) with the following form in c++:
CImg<double> image(512,512);
Tcyl.fill(1);
I would like to use ITK functionality to transform this image. So I need to transform this CImg image into itkImage object. How can I convert?
I have never used ITK before, so this was a learning curve. Anyway, I managed to make a radial gradient of floats in CImg and convert that to an ITK image and then write that as a float TIFF.
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
#include "itkImage.h"
#include "itkImportImageFilter.h"
#include "itkImageFileWriter.h"
#include "itkTIFFImageIO.h"
using namespace cimg_library;
using namespace std;
#define W 512
#define H 512
int main() {
// Create and initialise float image with radial gradient
cimg_library::CImg<float> img(W,H);
cimg_forXY(img,x,y) {img(x,y) = hypot((float)(W/2-x),(float)(H/2-y)); }
// Now convert CImg image to ITK image
const unsigned int Dimension = 2;
typedef itk::Image<float,Dimension> InputImageType;
typedef itk::ImportImageFilter<float,Dimension> ImportFilterType;
ImportFilterType::Pointer importFilter = ImportFilterType::New();
InputImageType::SizeType imsize;
imsize[0] = img.width();
imsize[1] = img.height();
ImportFilterType::IndexType start;
start.Fill(0);
ImportFilterType::RegionType region;
region.SetIndex(start);
region.SetSize(imsize);
importFilter->SetRegion(region);
const itk::SpacePrecisionType origin[Dimension] = {0.0,0.0};
importFilter->SetOrigin(origin);
const itk::SpacePrecisionType spacing[Dimension] = {1.0,1.0};
importFilter->SetSpacing(spacing);
// Tell ITK importFilter to take pixels directly from CImg's buffer
importFilter->SetImportPointer(img.data(),imsize[0]*imsize[1],false);
// Write result as a TIFF - so I can check it worked
typedef itk::ImageFileWriter<InputImageType> WriterType;
typedef itk::TIFFImageIO TIFFIOType;
TIFFIOType::Pointer tiffIO = TIFFIOType::New();
tiffIO->SetPixelType(itk::ImageIOBase::SCALAR);
WriterType::Pointer writer = WriterType::New();
writer->SetFileName("result.tif");
writer->SetInput(importFilter->GetOutput());
writer->SetImageIO(tiffIO);
writer->Update();
}
And here's the result (converted to JPEG for SO):
It works just the same if you change float for double except you can't write doubles to a TIFF so the last bit won't work.
I've been messing around some more and managed to load the pixels into a new ITK image ready for further processing, rather than for output:
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
#include "itkImage.h"
#include "itkImageRegionIterator.h"
using namespace cimg_library;
using namespace std;
#define W 5
#define H 3
int main() {
// Create and initialise double image with simple formula
cimg_library::CImg<double> img(W,H);
cimg_forXY(img,x,y) {img(x,y) = (double)x+(10.0*(double)y); }
// Now convert CImg image to ITK image
const unsigned int Dimension = 2;
typedef itk::Image<double,2> ImageType;
ImageType::Pointer image = ImageType::New();
ImageType::SizeType size;
size[0] = img.width();
size[1] = img.height();
ImageType::IndexType start;
start.Fill(0);
ImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);
image->SetRegions(region);
image->Allocate();
double origin[2];
origin[0]=0;
origin[1]=0;
image->SetOrigin(origin);
double spacing[2];
spacing[0]=1;
spacing[1]=1;
image->SetSpacing(spacing);
typedef itk::ImageRegionIterator<ImageType> IteratorType;
IteratorType it(image,region);
it.GoToBegin();
const double* data = img.data();
while(!it.IsAtEnd()){
it.Set(*data);
++it;
++data;
}
// Display pixels for checking purposes
for(unsigned int r = 0; r < H; r++)
{
for(unsigned int c = 0; c < W; c++)
{
ImageType::IndexType pixelIndex;
pixelIndex[0] = c;
pixelIndex[1] = r;
ImageType::PixelType pixelValue = image->GetPixel( pixelIndex );
cout << "Image[" << r << "," << c << "]: " << pixelValue << endl;
}
}
}
Sample Output
Image[0,0]: 0
Image[0,1]: 1
Image[0,2]: 2
Image[0,3]: 3
Image[0,4]: 4
Image[1,0]: 10
Image[1,1]: 11
Image[1,2]: 12
Image[1,3]: 13
Image[1,4]: 14
Image[2,0]: 20
Image[2,1]: 21
Image[2,2]: 22
Image[2,3]: 23
Image[2,4]: 24

How to get the Chain Code xml file in OpenCV 3.0 c++

I'm using Freeman Chain Code as Feature Extraction for an image.
I'm not able to read the image and I need to obtain a chain code xml file.
How can i retrieve the chain code xml file and save it?
Below is my c++ code in OpenCV 3.0
Can someone help..
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <fstream>
#include<string.h>
using namespace std;
using namespace cv;
int main() {
Mat img = imread("test.jpg")
imshow("Test", img);
vector<vector<Point>> contours; // Vector for storing contour
vector<Vec4i> hierarchy;
cv::findContours(img, contours, RETR_EXTERNAL,CV_CHAIN_CODE);
cout << Mat(contours[0]) << endl;
findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
cout << "CHAIN_APPROX_SIMPLE" << endl;
cout << Mat(contours[0]) << endl;
CvChain* chain = 0;
CvMemStorage* storage = 0;
storage = cvCreateMemStorage();
cvFindContours(&IplImage(img), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_TREE, CV_CHAIN_CODE);
int total = chain->total;
cv::Mat hist(1, 8, CV_32F, Scalar(0));
int totalCount = 0;
for (; chain != NULL; chain = (CvChain*)chain->h_next)
{
int numChain = 0;
CvSeqReader reader;
int i, total = chain->total;
cvStartReadSeq((CvSeq*)chain, &reader, 0);
cout<<"--------------------chain\n";
for (i = 0; i<total; i++)
{
char code;
CV_READ_SEQ_ELEM(code, reader);
int Fchain = (int)code;
hist.at<float>(0, Fchain)++;
totalCount++;
cout<<"%d"<<code;
}
}
Mat prob = hist / totalCount;
cout << prob << endl;
waitKey(0);
return 0;
}
Whenever the code is being run,I'm having this error.Have I used a wrong format?? Can anyone please help?
OpenCV Error: Unsupported format or combination of formats ([Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only) in cvStartFindContours, file C:\buildslave64\win64_amdocl\master_PackSlave-win64-vc14-shared\opencv\modules\imgproc\src\contours.cpp, line 198
I have updated my code.I'm able to save the xml file but but I'm getting the data in only 1 row.
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <fstream>
#include<string.h>
using namespace std;
using namespace cv;
vector<String> files;
int main() {
double totalCount = 0;
cv::glob("C:/Users//Videos/Database/Frames/*.jpg", files);
for (size_t i = 0; i < files.size(); i++) {
Mat image = imread(files[i]);
//Mat image = imread("Outline.jpg");
Canny(image, image, 100, 100 * 2, 3, false);
CvChain* chain;
CvMemStorage* storage = 0;
storage = cvCreateMemStorage();
cvFindContours(&IplImage(image), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_EXTERNAL, CV_CHAIN_CODE);
int total = chain->total;
// 1 row, 8 cols, filled with zeros, (float type, because we want to normalize later):
cv::Mat hist(1, 8, CV_32F, Scalar(0));
for (; chain != NULL; chain = (CvChain*)chain->h_next)
{
CvSeqReader reader;
int i, total = chain->total;
cvStartReadSeq((CvSeq*)chain, &reader, 0);
for (i = 0; i < total; i++)
{
char code;
CV_READ_SEQ_ELEM(code, reader);
int Fchain = (int)code;
// increase the counter for the respective bin:
hist.at<float>(0, Fchain)++;
totalCount++;
}
}
// print the raw histogram:
cout << "Histo: " << hist << endl;
cout << "Total: " << totalCount << endl;
// normalize it:
Mat prob = hist / totalCount;
cout << "Proba: " << prob << endl;
FileStorage fs("freeman.xml", FileStorage::WRITE);
fs << "chain" << prob;
waitKey(0);
return 0;
}
}
As shown below i'm having my chain code xml like this.Why am i getting this? Can anyone help me please?
<?xml version="1.0"?>
<opencv_storage>
<chain type_id="opencv-matrix">
<rows>1</rows>
<cols>8</cols>
<dt>f</dt>
<data>
5.00000000e-01 0. 0. 0. 5.00000000e-01 0. 0. 0.</data></chain>
</opencv_storage>
The error message says exactly and unambiguously what is wrong - it's enough to read it. cv::findContours() accepts only images of CV_8UC1 pixel type or only CV_32SC1 if you use CV_RETR_FLOODFILL mode. In your particular case, you need to convert your img object to CV_8UC1 after loading - you are probably loading an RGB image.

opencv error: assertion failed in cv::Mat::at file: mat.inl.hpp line 930

I have code for svm training phase. I use ms visual studio. I got error while executing below code:
#include <opencv/highgui.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <fstream>
#include <ctime>
#include <stdio.h>
#include <math.h>
#include <opencv\cv.h>
#include <opencv2\objdetect\objdetect.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\core\core.hpp>
#include <vector>
#include <windows.h>
#include <atlstr.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <opencv2\core\core.hpp>
#include <opencv\cvaux.hpp>
using namespace cv;
using namespace cv::ml;
using namespace std;
void readCenters(cv::Mat&, const char *);
cv::Mat shuffleRows(const cv::Mat&,const cv::Mat&);
int CLUSTER_COUNT=5;//number of clusters
Mat train_data1;
Mat test_data;
void splitData(cv::Mat &data,cv::Mat &train_data1,cv::Mat &test_data)
{
int N=data.rows;
float ratio=0.7;
int train_data_length= N*ratio;
int test_data_length=N-train_data_length;
data(cv::Rect(0,0,data.cols,train_data_length)).copyTo(train_data1);
data(cv::Rect(0,train_data_length,data.cols,test_data_length)).copyTo(test_data);
cout<<"length : "<<train_data_length<<endl;
}
void readData(cv::Mat& data)
{
std::vector<const char *> filenames;
filenames.push_back("Data/ik147_1.txt");
filenames.push_back("Data/ik147_2.txt");
filenames.push_back("Data/ik147_3.txt");
filenames.push_back("Data/labels.txt");
std::string line;
std::vector<cv::Mat> raw_data(4);//= new std::vector<cv::Mat>(4);
int row;
double min,max;
for(int i =0;i<4;i++)
{
std::ifstream file( filenames[i] );
while( file>>row )
{
raw_data[i].push_back(row);
}
minMaxLoc(raw_data[i],&min,&max);
cout<<filenames[i]<<" min :"<<min<<", max :"<<max<<std::endl;
}
int N=raw_data[0].rows;
// cv::Mat data(N,3,CV_32FC1);
int columns_to_read=3;
data.create(N,columns_to_read,CV_32FC1);
for(int i=0;i<columns_to_read;i++)
{
raw_data[i](cv::Rect(0,0,1,N)).copyTo(data(cv::Rect(i,0,1,N)));
}
}
void computeLabelledData(cv:: Mat& data,cv::Mat &data_with_labels){
cv::Mat labels,centers;
cv::kmeans(data, CLUSTER_COUNT, labels,
cv::TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
3, cv::KMEANS_PP_CENTERS, centers);
data_with_labels.create(data.rows,data.cols+1,CV_32FC1);
data.copyTo(data_with_labels(cv::Rect(0,0,data.cols,data.rows)));
labels.copyTo(data_with_labels(cv::Rect(data.cols,0,labels.cols,labels.rows)));
}
int main()
{
Mat data;
readData(data);
Mat data_with_labels,train_data_labels,test_data_labels;
computeLabelledData(data,data_with_labels);
splitData(data,train_data1,test_data);
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
int N=data.rows; //number of data points
int K=5; //number of labels
Mat train_data(train_data1.rows,train_data1.cols,CV_32F);
Mat labels;
int clusterCount=K;
int sampleCount = N;
Mat centers(5,2,CV_32FC1);
readCenters(centers,"centers.txt");
Point center;
center.x = 0;//rng_center.uniform(0, height);
center.y = 0;//rng_center.uniform(0, width);
// Set up training data
Mat labels_converted;
labels.convertTo(labels_converted, CV_32SC1);
Ptr<SVM> svm = SVM::create();
// edit: the params struct got removed,
// we use setter/getter now:
svm->setType(SVM::C_SVC);
// svm->setC(0.1);
svm->setKernel(SVM::LINEAR);
svm->setDegree(1./5);
svm->setGamma(100);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
// Train the SVM
//CvSVM svm;
svm->train(train_data, ROW_SAMPLE, labels_converted);
svm->save("svm_params.xml");
cout<<"svm parameters saved to : svm_params.xml"<<endl;
getchar();
}
void readCenters(cv::Mat &centers, const char * filename){
const int ROWS=5;
const int COLS=2;
cout<<"reading centers "<<filename<<endl;
float array[ROWS][COLS];
std::ifstream file( filename );
std::string line;
int row,col;
int i=0;
while( file>>row>>col )
{
centers.at<float>(i,0)=row;
centers.at<float>(i,1)=col;
i++;
}
}
cv::Mat shuffleRows(const cv::Mat &matrix,const cv::Mat &seeds)
{
cv::Mat output;
for (int cont = 0; cont < matrix.rows; cont++)
output.push_back(matrix.row((int)seeds.at<float>(cont,0)));
return output;
}
while executing this code, I got this error:
I able to read data from text files also centers.txt for define centers for kmeans. It is showing error at Mat::at in mat.inl.hpp file. I followed other references. Also tried to change datatypes from CV_32FC1 to CV_32F. But I cannot solve error.1
This error often happens when you are trying to access a pixel not inside your matrix. Also known as accessing a part of memory your program wasn't expecting to.
Take this example:
I have a matrix that is 10,10 and I try to access the 11,11 pixel. My program will crash and I will get the error that you are showing above. This can also happen even if I try to access 8,8 if I haven't loaded the image properly.
Take your code, wherever you are accessing a matrix could cause this issue, for instance this part of your code:
for(int i=0;i<columns_to_read;i++)
{
raw_data[i](cv::Rect(0,0,1,N)).copyTo(data(cv::Rect(i,0,1,N)));
}
You will need to step through it and see where it is crashing and then figure out what you are doing wrong.

Object Detection using SVM

I am new to SVM. I used to do object detection using HAAR Cascading. Now I am trying to implement SVM for object detection. I searched online and got to know about the basics.
I wanted to use libsvm while coding for c++. I am getting lots of problems.
Can anyone please explain step by step process of using it for object detection.
BTW I looked into opencv documentation of svm. But I am not able to do anything further.
Also I got this code for training my SVM and saving it into an xml file.
Now I want a code which can take this xml and detect objects in test cases.
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <iostream>
#include <vector>
#include<string.h>
using namespace std;
using namespace cv;
int main ( int argc, char** argv )
{
cout << "OpenCV Training SVM Automatic Number Plate Recognition\n";
cout << "\n";
char* path_Plates;
char* path_NoPlates;
int numPlates;
int numNoPlates;
int imageWidth=150;
int imageHeight=150;
//Check if user specify image to process
if(1)
{
numPlates= 11;
numNoPlates= 90 ;
path_Plates= "/home/kaushik/opencv_work/Manas6/Pics/Positive_Images/";
path_NoPlates= "/home/kaushik/opencv_work/Manas6/Pics/Negative_Images/i";
}else{
cout << "Usage:\n" << argv[0] << " <num Plate Files> <num Non Plate Files> <path to plate folder files> <path to non plate files> \n";
return 0;
}
Mat classes;//(numPlates+numNoPlates, 1, CV_32FC1);
Mat trainingData;//(numPlates+numNoPlates, imageWidth*imageHeight, CV_32FC1 );
Mat trainingImages;
vector<int> trainingLabels;
for(int i=1; i<= numPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss<<path_Plates<<i<<".jpg";
try{
const char* a = ss.str().c_str();
printf("\n%s\n",a);
Mat img = imread(ss.str(), CV_LOAD_IMAGE_UNCHANGED);
img= img.clone().reshape(1, 1);
//imshow("Window",img);
//cout<<ss.str();
trainingImages.push_back(img);
trainingLabels.push_back(1);
}
catch(Exception e){;}
}
for(int i=0; i< numNoPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_NoPlates<<i << ".jpg";
try
{
const char* a = ss.str().c_str();
printf("\n%s\n",a);
Mat img=imread(ss.str(), 0);
//imshow("Win",img);
img= img.clone().reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(0);
//cout<<ss.str();
}
catch(Exception e){;}
}
Mat(trainingImages).copyTo(trainingData);
//trainingData = trainingData.reshape(1,trainingData.rows);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainingLabels).copyTo(classes);
FileStorage fs("SVM.xml", FileStorage::WRITE);
fs << "TrainingData" << trainingData;
fs << "classes" << classes;
fs.release();
return 0;
}
Any help would be greatly appreciated.
Also I would love to have suggestions on how to implement libsvm for object detection.
This is a simple code which you could take a test with your xml file:
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "cv.h"
#include <vector>
#include <string.h>
#include <ml.h>
#include <iostream>
#include <io.h>
using namespace cv;
using namespace std;
int main()
{
FileStorage fs;
fs.open("SVM.xml", FileStorage::READ);
Mat trainingData;
Mat classes;
fs["TrainingData"] >> trainingData;
fs["classes"] >> classes;
CvSVMParams SVM_params;
SVM_params.svm_type = CvSVM::C_SVC;
SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR;
SVM_params.degree = 1;
SVM_params.gamma = 1;
SVM_params.coef0 = 0;
SVM_params.C = 1;
SVM_params.nu = 0;
SVM_params.p = 0;
SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01);
CvSVM svm(trainingData, classes, Mat(), Mat(), SVM_params);
Mat src = imread("D:\\SVM\\samples\\\pos\\10.jpg");
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat p = gray.reshape(1, 1);
p.convertTo(p, CV_32FC1);
int response = (int)svm.predict( p );
if(response ==1 )
{
cout<<"this is a object!"<<endl;
cout<<endl;
}
else
{
cout<<"no object detected!"<<endl;
cout<<endl;
}
return 0;
}
by the way,it seems that there is little problem when runing your offered code,the result shows that:"opencv errror,Image step is wrongin cv::Mat::reshape".Had you met such situation before?Thank you.

OpenCv BruterForceMatcher Failed while drawMatches

With following OpenCV code I try to test the BruteForceMatcher and get error message:
OpenCV Error: Assertion failed (!outImage.empty()) in cv::drawKeypoints, file C:
\buildslave64\win64_amdocl\2_4_PackSlave-win32-vc11-shared\opencv\modules\featur
es2d\src\draw.cpp, line 115
#include <iostream>
#include <fstream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/stitching/stitcher.hpp"
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define MAX_PICNUM 18
bool try_use_gpu = false;
vector<Mat> imgs;
string result_name = "result.jpg";
int main(int argc, char* argv[]) {
initModule_nonfree();
int picNum = 2;
Mat imgs[MAX_PICNUM];
for (int i = 0; i < picNum; ++i) {
stringstream ss;
string iStr;
ss << i;
ss >> iStr;
imgs[i] = imread("../" + iStr + ".jpg");
}
SiftFeatureDetector siftdtc;
vector<KeyPoint> keyPointVec[MAX_PICNUM];
for (int i = 0; i < picNum; ++i) {
siftdtc.detect(imgs[i], keyPointVec[i]);
}
SiftDescriptorExtractor siftDesc;
Mat descriptextractors[MAX_PICNUM];
for (int i = 0; i < picNum; ++i) {
siftDesc.compute(imgs[i], keyPointVec[i], descriptextractors[i]);
}
SiftDescriptorExtractor extractor;
Mat descriptor1,descriptor2;
BruteForceMatcher<L2<float>> matcher;
vector<DMatch> matches;
Mat img_matches;
extractor.compute(imgs[0], keyPointVec[0], descriptor1);
extractor.compute(imgs[1], keyPointVec[1], descriptor2);
matcher.match(descriptor1,descriptor2,matches);
drawMatches(imgs[0], keyPointVec[0], imgs[1], keyPointVec[1], matches, img_matches);
cvSaveImage("matchs.jpg", &(IplImage)(img_matches));
waitKey();
return 0;
}
It seems like it is the error in drawMatches?