train_digits.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #include <iostream>
  2. #include <opencv2/highgui.hpp>
  3. #include <opencv2/imgproc.hpp>
  4. #include "opencv2/objdetect.hpp"
  5. #include <opencv2/ml.hpp>
  6. using namespace cv::ml;
  7. using namespace cv;
  8. using namespace std;
  9. string pathName = "digits.png";
  10. int SZ = 20;
  11. float affineFlags = WARP_INVERSE_MAP|INTER_LINEAR;
  12. Mat deskew(Mat& img){
  13. Moments m = moments(img);
  14. if(abs(m.mu02) < 1e-2){
  15. return img.clone();
  16. }
  17. float skew = m.mu11/m.mu02;
  18. Mat warpMat = (Mat_<float>(2,3) << 1, skew, -0.5*SZ*skew, 0, 1, 0);
  19. Mat imgOut = Mat::zeros(img.rows, img.cols, img.type());
  20. warpAffine(img, imgOut, warpMat, imgOut.size(),affineFlags);
  21. return imgOut;
  22. }
  23. void loadTrainTestLabel(string &pathName, vector<Mat> &trainCells, vector<Mat> &testCells,vector<int> &trainLabels, vector<int> &testLabels)
  24. {
  25. Mat img = imread(pathName, cv::IMREAD_GRAYSCALE);
  26. int ImgCount = 0;
  27. for(int i = 0; i < img.rows; i = i + SZ)
  28. {
  29. for(int j = 0; j < img.cols; j = j + SZ)
  30. {
  31. Mat digitImg = (img.colRange(j,j+SZ).rowRange(i,i+SZ)).clone();
  32. if(j < int(0.9*img.cols))
  33. {
  34. trainCells.push_back(digitImg);
  35. }
  36. else
  37. {
  38. testCells.push_back(digitImg);
  39. }
  40. ImgCount++;
  41. }
  42. }
  43. cout << "Image Count : " << ImgCount << endl;
  44. float digitClassNumber = 0;
  45. for(int z=0;z<int(0.9*ImgCount);z++){
  46. if(z % 450 == 0 && z != 0){
  47. digitClassNumber = digitClassNumber + 1;
  48. }
  49. trainLabels.push_back(digitClassNumber);
  50. }
  51. digitClassNumber = 0;
  52. for(int z=0;z<int(0.1*ImgCount);z++){
  53. if(z % 50 == 0 && z != 0){
  54. digitClassNumber = digitClassNumber + 1;
  55. }
  56. testLabels.push_back(digitClassNumber);
  57. }
  58. }
  59. void CreateDeskewedTrainTest(vector<Mat> &deskewedTrainCells,vector<Mat> &deskewedTestCells, vector<Mat> &trainCells, vector<Mat> &testCells){
  60. for(int i=0;i<trainCells.size();i++){
  61. Mat deskewedImg = deskew(trainCells[i]);
  62. deskewedTrainCells.push_back(deskewedImg);
  63. }
  64. for(int i=0;i<testCells.size();i++){
  65. Mat deskewedImg = deskew(testCells[i]);
  66. deskewedTestCells.push_back(deskewedImg);
  67. }
  68. }
  69. HOGDescriptor hog(
  70. Size(20,20), //winSize
  71. Size(8,8), //blocksize
  72. Size(4,4), //blockStride,
  73. Size(8,8), //cellSize,
  74. 9, //nbins,
  75. 1, //derivAper,
  76. -1, //winSigma,
  77. cv::HOGDescriptor::HistogramNormType::L2Hys, //histogramNormType,
  78. 0.2, //L2HysThresh,
  79. 0, //gammal correction,
  80. 64, //nlevels=64
  81. 1
  82. );
  83. void CreateTrainTestHOG(vector<vector<float> > &trainHOG, vector<vector<float> > &testHOG, vector<Mat> &deskewedtrainCells, vector<Mat> &deskewedtestCells){
  84. for(int y=0;y<deskewedtrainCells.size();y++){
  85. vector<float> descriptors;
  86. hog.compute(deskewedtrainCells[y],descriptors);
  87. trainHOG.push_back(descriptors);
  88. }
  89. for(int y=0;y<deskewedtestCells.size();y++){
  90. vector<float> descriptors;
  91. hog.compute(deskewedtestCells[y],descriptors);
  92. testHOG.push_back(descriptors);
  93. }
  94. }
  95. void ConvertVectortoMatrix(vector<vector<float> > &trainHOG, vector<vector<float> > &testHOG, Mat &trainMat, Mat &testMat)
  96. {
  97. int descriptor_size = trainHOG[0].size();
  98. for(int i = 0;i<trainHOG.size();i++){
  99. for(int j = 0;j<descriptor_size;j++){
  100. trainMat.at<float>(i,j) = trainHOG[i][j];
  101. }
  102. }
  103. for(int i = 0;i<testHOG.size();i++){
  104. for(int j = 0;j<descriptor_size;j++){
  105. testMat.at<float>(i,j) = testHOG[i][j];
  106. }
  107. }
  108. }
  109. void getSVMParams(SVM *svm)
  110. {
  111. cout << "Kernel type : " << svm->getKernelType() << endl;
  112. cout << "Type : " << svm->getType() << endl;
  113. cout << "C : " << svm->getC() << endl;
  114. cout << "Degree : " << svm->getDegree() << endl;
  115. cout << "Nu : " << svm->getNu() << endl;
  116. cout << "Gamma : " << svm->getGamma() << endl;
  117. }
  118. Ptr<SVM> svmInit(float C, float gamma)
  119. {
  120. Ptr<SVM> svm = SVM::create();
  121. svm->setGamma(gamma);
  122. svm->setC(C);
  123. svm->setKernel(SVM::RBF);
  124. svm->setType(SVM::C_SVC);
  125. return svm;
  126. }
  127. void svmTrain(Ptr<SVM> svm, Mat &trainMat, vector<int> &trainLabels)
  128. {
  129. Ptr<TrainData> td = TrainData::create(trainMat, ROW_SAMPLE, trainLabels);
  130. svm->train(td);
  131. svm->save("results/eyeGlassClassifierModel.yml");
  132. }
  133. void svmPredict(Ptr<SVM> svm, Mat &testResponse, Mat &testMat )
  134. {
  135. svm->predict(testMat, testResponse);
  136. }
  137. void SVMevaluate(Mat &testResponse, float &count, float &accuracy, vector<int> &testLabels)
  138. {
  139. for(int i = 0; i < testResponse.rows; i++)
  140. {
  141. // cout << testResponse.at<float>(i,0) << " " << testLabels[i] << endl;
  142. if(testResponse.at<float>(i,0) == testLabels[i])
  143. count = count + 1;
  144. }
  145. accuracy = (count/testResponse.rows)*100;
  146. }
  147. int main()
  148. {
  149. vector<Mat> trainCells;
  150. vector<Mat> testCells;
  151. vector<int> trainLabels;
  152. vector<int> testLabels;
  153. loadTrainTestLabel(pathName,trainCells,testCells,trainLabels,testLabels);
  154. vector<Mat> deskewedTrainCells;
  155. vector<Mat> deskewedTestCells;
  156. CreateDeskewedTrainTest(deskewedTrainCells,deskewedTestCells,trainCells,testCells);
  157. std::vector<std::vector<float> > trainHOG;
  158. std::vector<std::vector<float> > testHOG;
  159. CreateTrainTestHOG(trainHOG,testHOG,deskewedTrainCells,deskewedTestCells);
  160. int descriptor_size = trainHOG[0].size();
  161. cout << "Descriptor Size : " << descriptor_size << endl;
  162. Mat trainMat(trainHOG.size(),descriptor_size,CV_32FC1);
  163. Mat testMat(testHOG.size(),descriptor_size,CV_32FC1);
  164. ConvertVectortoMatrix(trainHOG,testHOG,trainMat,testMat);
  165. float C = 12.5, gamma = 0.5;
  166. Mat testResponse;
  167. Ptr<SVM> model = svmInit(C, gamma);
  168. /////////// SVM Training ////////////////
  169. svmTrain(model, trainMat, trainLabels);
  170. /////////// SVM Testing ////////////////
  171. svmPredict(model, testResponse, testMat);
  172. ////////////// Find Accuracy ///////////
  173. float count = 0;
  174. float accuracy = 0 ;
  175. getSVMParams(model);
  176. SVMevaluate(testResponse, count, accuracy, testLabels);
  177. cout << "the accuracy is :" << accuracy << endl;
  178. return 0;
  179. }