我正在尝试对图像进行分类,无论字符是否打印在表面上。
这样做。
首先,我使用真实图像拍摄图像的冲浪功能,并手动删除真实图像,尝试创建一个单词到xml文件,然后尝试预测。
然而,除非我使用完全不同的图像或完全裁剪的图像,否则我的SVM分类器会预测它是正确的。
这些是我用于火车的图像
https://www.dropbox.com/sh/xked9ywnibzv3tt/AADC0lP4WYAo3ddEDgvHpFhha/negative?dl=0
这是我的代码。
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "opencv2/core/core.hpp"
#include<dirent.h>
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
Ptr<FeatureDetector> detector = FeatureDetector::create("SURF");
Ptr<DescriptorExtractor> descriptors = DescriptorExtractor::create("SURF");
string to_string(const int val) {
int i = val;
std::string s;
std::stringstream out;
out << i;
s = out.str();
return s;
}
Mat compute_features(Mat image) {
vector<KeyPoint> keypoints;
Mat features;
detector->detect(image, keypoints);
KeyPointsFilter::retainBest(keypoints, 1500);
descriptors->compute(image, keypoints, features);
return features;
}
BOWKMeansTrainer addFeaturesToBOWKMeansTrainer(String dir, BOWKMeansTrainer& bowTrainer) {
DIR *dp;
struct dirent *dirp;
struct stat filestat;
dp = opendir(dir.c_str());
Mat features;
Mat img;
string filepath;
#pragma loop(hint_parallel(4))
for (; (dirp = readdir(dp));) {
filepath = dir + dirp->d_name;
cout << "Reading... " << filepath << endl;
if (stat( filepath.c_str(), &filestat )) continue;
if (S_ISDIR( filestat.st_mode )) continue;
img = imread(filepath, 0);
features = compute_features(img);
bowTrainer.add(features);
}
return bowTrainer;
}
void computeFeaturesWithBow(string dir, Mat& trainingData, Mat& labels, BOWImgDescriptorExtractor& bowDE, int label) {
DIR *dp;
struct dirent *dirp;
struct stat filestat;
dp = opendir(dir.c_str());
vector<KeyPoint> keypoints;
Mat features;
Mat img;
string filepath;
#pragma loop(hint_parallel(4))
for (;(dirp = readdir(dp));) {
filepath = dir + dirp->d_name;
cout << "Reading: " << filepath << endl;
if (stat( filepath.c_str(), &filestat )) continue;
if (S_ISDIR( filestat.st_mode )) continue;
img = imread(filepath, 0);
detector->detect(img, keypoints);
bowDE.compute(img, keypoints, features);
trainingData.push_back(features);
labels.push_back((float) label);
}
cout << string( 100, '\n' );
}
int main() {
initModule_nonfree();
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
TermCriteria tc(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 10, 0.001);
int dictionarySize = 1000;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(descriptors, matcher);
string dir = "/positive/", filepath;
DIR *dp;
struct dirent *dirp;
struct stat filestat;
cout << "Add Features to KMeans" << endl;
addFeaturesToBOWKMeansTrainer("/positive/", bowTrainer);
addFeaturesToBOWKMeansTrainer("/negative/", bowTrainer);
cout << endl << "Clustering..." << endl;
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
Mat labels(0, 1, CV_32FC1);
Mat trainingData(0, dictionarySize, CV_32FC1);
cout << endl << "Extract bow features" << endl;
computeFeaturesWithBow("/positive/", trainingData, labels, bowDE, 1);
computeFeaturesWithBow("/negative/", trainingData, labels, bowDE, 0);
CvSVMParams params;
params.kernel_type=CvSVM::LINEAR;
params.svm_type=CvSVM::C_SVC;
params.gamma=5;
params.C=100;
params.term_crit=cvTermCriteria(CV_TERMCRIT_NUMBER,100,0.000001);
CvSVM svm;
cout << endl << "Begin training" << endl;
bool res =svm.train(trainingData,labels,cv::Mat(),cv::Mat(),params);
svm.save("classifier.xml");
//CvSVM svm;
svm.load("classifier.xml");
vector<KeyPoint> cameraKeyPoints;
Mat rotated = imread("test.jpg",0);
Mat featuresFromimage;
detector->detect(rotated, cameraKeyPoints);
bowDE.compute(rotated, cameraKeyPoints, featuresFromimage);
cout <<"anar:"<< svm.predict(featuresFromimage) << endl;
imshow("edges", rotated);
cvWaitKey(0);
return 0;
}
问题1 :由于这些图像太熟悉我怎么能做预测呢
if similiarity > %80
"correct"
else
"defected"
问题2 由于这种角色背叛在工厂中非常罕见,因此很难获得大量缺陷图像进行训练。手动创建此图像上的缺陷是正确的解决方案吗?如果不是我能真正做到的?
问题3
我可以在这种图像上实际采用哪种预处理方法来提高SVM的准确性?
谢谢