Ejemplo n.º 1
0
static std::vector<std::string> plate_recognize(const char* image,
                                                const char* model_svm,
                                                const char* model_ann,
                                                const bool life_mode = true) {
  cv::Mat img = cv::imread(image);

  _ASSERT(!img.empty());

  CPlateRecognize pr;
  pr.setLifemode(life_mode);
  pr.setDebug(false);

  std::vector<std::string> results;
  pr.plateRecognize(img, results);

  return std::move(results);
}
Ejemplo n.º 2
0
int test_plate_recognize()
{
	cout << "test_plate_recognize" << endl;

	Mat src = imread(img_plate_recognize);

	CPlateRecognize pr;
	pr.LoadANN("model/ann.xml");
	pr.LoadSVM("model/svm.xml");

	pr.setLifemode(true);
	pr.setDebug(true);

	vector<string> plateVec;

	int result = pr.plateRecognize(src, plateVec);
	if (result == 0)
	{
		int num = plateVec.size();
		for (int j = 0; j < num; j++)
		{
			cout << "plateRecognize: " << plateVec[j] << endl;			
		}
	}

	if (result != 0)
		cout << "result:" << result << endl;

	return result;
}
Ejemplo n.º 3
0
JNIEXPORT jbyteArray JNICALL Java_com_example_carplate_CarPlateDetection_ImageProc(
		JNIEnv *env, jclass obj, jstring imgpath, jstring svmpath,
		jstring annpath) {
	CPlateRecognize pr;
//	const string *img = (*env)->GetStringUTFChars(env, imgpath, 0);
//	const string *svm = (*env)->GetStringUTFChars(env, svmpath, 0);
//	const string *ann = (*env)->GetStringUTFChars(env, annpath, 0);
	char* img = jstring2str(env,imgpath);
	char* svm = jstring2str(env,svmpath);
	char* ann = jstring2str(env,annpath);
	Mat src = imread(img);
	pr.LoadSVM(svm);
	pr.LoadANN(ann);

	pr.setGaussianBlurSize(5);
	pr.setMorphSizeWidth(17);

	pr.setVerifyMin(3);
	pr.setVerifyMax(20);

	pr.setLiuDingSize(7);
	pr.setColorThreshold(150);

	vector < string > plateVec;

	int count = pr.plateRecognize(src, plateVec);
	string str = "0";

	if (count == 0) {
		str = plateVec[0];
	}

	char *result = new char[str.length() + 1];
	strcpy(result, str.c_str());
	jbyte *by = (jbyte*) result;
	jbyteArray jarray = env->NewByteArray(strlen(result));
	env->SetByteArrayRegion(jarray, 0, strlen(result), by);
	return jarray;
}
Ejemplo n.º 4
0
int test_plate_recognize()
{
	cout << "test_plate_recognize" << endl;

	Mat src = imread("image/plate_locate.jpg");
	//Mat src = imread("image/baidu_image/test6.jpg");

	CPlateRecognize pr;
	pr.LoadANN("model/ann.xml");
	pr.LoadSVM("model/svm.xml");

	pr.setGaussianBlurSize(5);
	pr.setMorphSizeWidth(17);

	pr.setVerifyMin(3);
	pr.setVerifyMax(20);

	pr.setLiuDingSize(7);
	pr.setColorThreshold(150);

	vector<string> plateVec;

	int result = pr.plateRecognize(src, plateVec);
	if (result == 0)
	{
		int num = plateVec.size();
		for (int j = 0; j < num; j++)
		{
			cout << "plateRecognize: " << plateVec[j] << endl;			
		}
	}

	cout << "Enter 1 for coninue:";
	int a = 0;
	cin >> a;

	return result;
}
Ejemplo n.º 5
0
static std::vector<CPlate> tcl_plate_recognize1(cv::Mat img,
                                                const char* model_svm,
                                                const char* model_ann,
                                                const bool life_mode1 = true) {
  // img = cv::imread(image);
  assert(!img.empty());
  CPlateRecognize pr;
  pr.LoadSVM(model_svm);
  pr.LoadANN(model_ann);
  pr.setLifemode(life_mode1);
  pr.setDebug(false);

  std::vector<std::string> results;
  std::vector<CPlate> allPlates;
  pr.tcl_plateRecognize(img, results, 0, allPlates);
  return allPlates;
  // return std::move(results);
}
Ejemplo n.º 6
0
static std::vector<std::string> plate_recognize(const char* image,
                                                const char* model_svm,
                                                const char* model_ann,
                                                const bool life_mode = true) {
  cv::Mat img = cv::imread(image);

  assert(!img.empty());

  CPlateRecognize pr;
  pr.LoadSVM(model_svm);
  pr.LoadANN(model_ann);
  pr.setLifemode(life_mode);
  pr.setDebug(false);

  std::vector<std::string> results;
  std::vector<easypr::CPlate> plates;
  pr.plateRecognize(img, results, plates);

  return std::move(results);
}
Ejemplo n.º 7
0
int acurayTest(const string& test_path) {
    ////获取该路径下的所有文件
    auto files = Utils::getFiles(test_path);
    
    // CPlateLocate lo;
    // CPlateJudge ju;
    CPlateRecognize pr;
    
    pr.LoadANN("model/ann.xml");
    pr.LoadSVM("model/svm.xml");
    pr.setLifemode(true);
    pr.setDebug(false);
    
    // 设置要处理的一张图片中最多有多少车牌
    pr.setMaxPlates(4);
    
    // CPlateDetect pd;
    // pd.LoadSVM("model/svm.xml");
    // pd.setPDLifemode(true);
    
    int size = files.size();
    // int size = 200;
    
    if (0 == size) {
        cout << "No File Found in general_test/native_test!" << endl;
        return 0;
    }
    
    cout << "Begin to test the easypr accuracy!" << endl;
    
    // 总的测试图片数量
    int count_all = 0;
    // 错误的图片数量
    int count_err = 0;
    // 未识别的图片数量
    int count_norecogin = 0;
    
    // 总的字符差距
    float diff_all = 0;
    // 平均字符差距
    float diff_avg = 0;
    // 完全匹配的识别次数
    float match_count = 0;
    // 完全匹配的识别次数所占识别图片中的比例
    float match_rate = 0;
    
    // 开始和结束时间
    time_t begin, end;
    time(&begin);
    
    for (int i = 0; i < size; i++) {
        string filepath = files[i].c_str();
        cout << "------------------" << endl;
        
        // 获取真实的车牌
        string plateLicense = Utils::getFileName(filepath);
        cout << "原牌:" << plateLicense << endl;
        
        // EasyPR开始判断车牌
        Mat src = imread(filepath);
        
        vector<string> plateVec;
        int result = pr.plateRecognize(src, plateVec, i);
        if (result == 0) {
            int num = plateVec.size();
            
            if (num == 0) {
                cout << "无车牌" << endl;
                if (plateLicense != "无车牌") count_norecogin++;
            } else if (num > 1) {
                // 多车牌使用diff最小的那个记录
                int mindiff = 10000;
                for (int j = 0; j < num; j++) {
                    cout << plateVec[j] << " (" << j + 1 << ")" << endl;
                    string colorplate = plateVec[j];
                    
                    // 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小"
                    vector<string> spilt_plate = Utils::splitString(colorplate, ':');
                    
                    int size = spilt_plate.size();
                    if (size == 2 && spilt_plate[1] != "") {
                        int diff =
                        levenshtein_distance(plateLicense, spilt_plate[size - 1]);
                        if (diff < mindiff) mindiff = diff;
                    }
                }
                
                cout << "差距:" << mindiff << "个字符" << endl;
                if (mindiff == 0) {
                    // 完全匹配
                    match_count++;
                }
                diff_all = diff_all + mindiff;
            } else {
                // 单车牌只计算一次diff
                for (int j = 0; j < num; j++) {
                    cout << plateVec[j] << endl;
                    string colorplate = plateVec[j];
                    
                    // 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小"
                    vector<string> spilt_plate = Utils::splitString(colorplate, ':');
                    
                    int size = spilt_plate.size();
                    if (size == 2 && spilt_plate[1] != "") {
                        int diff =
                        levenshtein_distance(plateLicense, spilt_plate[size - 1]);
                        cout << "差距:" << diff << "个字符" << endl;
                        
                        if (diff == 0) {
                            // 完全匹配
                            match_count++;
                        }
                        diff_all = diff_all + diff;
                    }
                }
            }
        } else {
            cout << "错误码:" << result << endl;
            count_err++;
        }
        count_all++;
    }
    time(&end);
    
    cout << "------------------" << endl;
    cout << "Easypr accuracy test end!" << endl;
    cout << "------------------" << endl;
    cout << endl;
    cout << "统计参数:" << endl;
    cout << "总图片数:" << count_all << "张,  ";
    cout << "未识出图片:" << count_norecogin << "张,  ";
    
    float count_recogin = count_all - (count_err + count_norecogin);
    float count_rate = count_recogin / count_all;
    //float count_norate = 1 - count_rate;
    cout << "定位率:" << count_rate * 100 << "%  " << endl;
    
    diff_avg = diff_all / count_recogin;
    match_rate = match_count / count_recogin * 100;
    
    cout << "平均字符差距:" << diff_avg << "个,  ";
    cout << "完全匹配数:" << match_count << "张,  ";
    cout << "完全匹配率:" << match_rate << "%  " << endl;
    
    double seconds = difftime(end, begin);
    double avgsec = seconds / double(count_all);
    
    cout << "总时间:" << seconds << "秒,  ";
    cout << "平均执行时间:" << avgsec << "秒  " << endl;
    
    cout << endl;
    
    cout << "------------------" << endl;
    
    ofstream myfile("run_accuracy.txt", ios::app);
    if (myfile.is_open()) {
        time_t t = time(0);  // get time now
        struct tm* now = localtime(&t);
        char buf[80];
        
        strftime(buf, sizeof(buf), "%Y-%m-%d %X", now);
        myfile << string(buf) << endl;
        
        myfile << "总图片数:" << count_all << "张,  ";
        myfile << "未识出图片:" << count_norecogin << "张,  ";
        myfile << "定位率:" << count_rate * 100 << "%  " << endl;
        myfile << "平均字符差距:" << diff_avg << "个,  ";
        myfile << "完全匹配数:" << match_count << "张,  ";
        myfile << "完全匹配率:" << match_rate << "%  " << endl;
        myfile << "总时间:" << seconds << "秒,  ";
        myfile << "平均执行时间:" << avgsec << "秒  " << endl;
        myfile.close();
    } else {
        cout << "Unable to open file";
    }
    return 0;
}
int general_test()
{
	////获取该路径下的所有文件
	vector<string> files;
	getFiles(your_data_path, files);

	CPlateLocate lo;
	CPlateJudge ju;
	CPlateRecognize pr;

	pr.LoadANN("model/ann.xml");
	pr.LoadSVM("model/svm.xml");
	pr.setLifemode(true);

	int size = files.size();
	//int size = 200;

	if (0 == size)
	{
		cout << "No File Found!" << endl;
		return 0;
	}

	cout << "Begin to prepare general_test!" << endl;

	for (int i = 0; i < size; i++)
	{
		string filepath = files[i].c_str();
		cout << "------------------" << endl;

		// EasyPR开始判断车牌
		Mat src = imread(filepath);
		vector<string> plateVec;

		int result = pr.plateRecognize(src, plateVec);
		if (result == 0)
		{
			int num = plateVec.size();

			if (num == 0)
			{
				cout << ""<< "无车牌" <<endl;
			} 
			else 
			{
				cout << plateVec[0] <<endl;
				string colorplate = plateVec[0];

				// 输出"蓝牌:苏E7KU22"中冒号后面的车牌
				vector<string> spilt_plate;
				SplitString(colorplate, spilt_plate, ":");

				int size = spilt_plate.size();
				if (size == 2)
				{
					stringstream ss(stringstream::in | stringstream::out);
					ss << "F:/data/easypr-data/tmp-4" << "/" << spilt_plate[size-1] << ".jpg";
					imwrite(ss.str(), src);
				}
			}
		} 
		else
		{
			cout << "错误码:" << result << endl;
		}
	}

	return 0;
}
Ejemplo n.º 9
0
int plate_recognize_main(){
	cout << "process plate_detect_main..." << endl;

	
	// Mat src = imread(NATIVE_RECG_PATH+"/test.yuv");
	Mat src; //= imread(NATIVE_RECG_PATH+"/test.yuv");
	src.create(480,640, CV_8UC3);

	FILE *in;
	in=fopen("RECG/data.input","r");

	int i,j,y=0,u=0,v=0;
	char t,handle=1;
	double R,G,B;
	char temp;
	for (j=0;j<480;j++){
		for (i=0;i<640;i++){
			if (OPTION_HEX)
				fscanf(in,"%c%c%X",&temp,&temp,&y);
			else
				fscanf(in,"%X",&y);
			if (handle){
				if (OPTION_HEX)
					fscanf(in,"%c%c%X",&temp,&temp,&u);
				else
					fscanf(in,"%X",&u);
				handle=0;
			}else{
				if (OPTION_HEX)
					fscanf(in,"%c%c%X",&temp,&temp,&v);
				else
					fscanf(in,"%X",&v);
				handle=1;
			}
			
			R=(y+1.4075*(v-128));
			G=(y-0.455*(u-128)-0.7169*(v-128));
			B=(y+1.779*(u-128));

			src.at<Vec3b>(j,i)[0] = (unsigned char)(B<0)?0:(B>255)?255:(unsigned char)B;
			src.at<Vec3b>(j,i)[1] = (unsigned char)(G<0)?0:(G>255)?255:(unsigned char)G;
			src.at<Vec3b>(j,i)[2] = (unsigned char)(R<0)?0:(R>255)?255:(unsigned char)R;
		}
	}
	fclose(in);

	// show_dialog(src);
	// exit;

	CPlateRecognize plate;
	plate.LoadANN("model/ann.xml");
	plate.LoadSVM("model/svm.xml");
	plate.setDebug(OPTION_DEBUG);
	plate.setLifemode(OPTION_LIFEMODE);

	vector<string> plateVec;

	int result = plate.plateRecognize(src, plateVec);
	if (result == 0)
	{
		int num = plateVec.size();
		for (int j = 0; j < num; j++)
		{
			cout << "plateRecognize[" << j << "]: "<< plateVec[j] << endl;			
		}
	}

	if (result != 0)
		cout << "result:" << result << endl;

	return result;
}
Ejemplo n.º 10
0
void CBATCHDlg::OnBnClickedButtonPlaterecognize2()
{
	int i;
	
	CPlateRecognize pr;
	pr.LoadANN("model/ann.xml");
	pr.LoadSVM("model/svm.xml");

	//pr.setGaussianBlurSize(5);
	//pr.setMorphSizeWidth(17);

	//pr.setVerifyMin(3);
	//pr.setVerifyMax(20);

	//pr.setLiuDingSize(7);
	pr.setColorThreshold(150);

	stringstream ss(stringstream::in | stringstream::out);
	
	int num_char = 0;
	int num_plate = 0;
	for(vector<CString>::size_type v_i = 0; v_i < m_images.size(); ++v_i)
	{	
		vector<string> plateVec;

		ss << m_images[v_i] << " Result: ";

		vector<Mat> resultVec;
		string str = m_images[v_i].GetBuffer(0);

		int index1 = str.find_last_of("\\");
		int index2 = str.find_last_of(".");
		string name = str.substr(index1 + 1,index2 - index1 - 1);

		Mat src = imread(str, 1);
		string str_cr;

		int result = pr.plateRecognize2(src, plateVec);
		int max_tmp;
		int num_tmp;
		if (result == 0)
		{
			num_tmp = 0;
			max_tmp = 0;
			for(i = 0; i < plateVec.size(); ++i) 
			{ 
				num_tmp = 0;
				ss << " " << plateVec[i];
				if(2 <= plateVec[i].size() && plateVec[i][0] == name[0]) ++num_tmp;
				for(int j = 2; j < plateVec[i].size() && j <= 8; ++j)
				{
					if(plateVec[i][j] == name[j]) ++num_tmp;
				}
				if(num_tmp > max_tmp) max_tmp = num_tmp;
			}
			if(max_tmp == 7) ++num_plate;
			num_char += max_tmp;
			ss << "\r\n";
		}
		else
		{
			ss << "No Answer\r\n";
		}
	}

	ss << "Char accuracy rate:" << (1.0 * num_char / (m_images.size() * 7)) << "\r\n";
	ss << "Plate accuracy rate:" << (1.0 * num_plate / m_images.size()) << "\r\n";

	m_res = ss.str().c_str();
	UpdateData(FALSE);

	CString filePath = this->m_savepath + "\\plate_recognize.txt";
	std::ofstream resfile(filePath);
	resfile << ss.str().c_str();
	resfile.close();
}
Ejemplo n.º 11
0
void CBATCHDlg::OnBnClickedButtonPlaterecognize()
{	
	CPlateRecognize pr;
	pr.LoadANN("model/ann.xml");
	pr.LoadSVM("model/svm.xml");

	pr.setGaussianBlurSize(5);
	pr.setMorphSizeWidth(17);

	pr.setVerifyMin(3);
	pr.setVerifyMax(20);

	pr.setLiuDingSize(7);
	pr.setColorThreshold(150);

	string res_str = "";
	
	int num_char = 0;
	for(vector<CString>::size_type v_i = 0; v_i < m_images.size(); ++v_i)
	{	
		vector<string> plateVec;

		res_str += m_images[v_i];
		res_str += " Result: ";

		vector<Mat> resultVec;
		string str = m_images[v_i].GetBuffer(0);

		int index1 = str.find_last_of("\\");
		int index2 = str.find_last_of(".");
		string name = str.substr(index1 + 1,index2 - index1 - 1);

		Mat src = imread(str, 1);
		string str_cr;

		int result = pr.plateRecognize(src, plateVec);
		if (result == 0)
		{

			for(int i = 0; i < plateVec.size(); ++i) 
			{ 
				res_str += " ";
				res_str += plateVec[i]; 
				for(int j = 2; j < plateVec[i].size() && j < 8; ++j)
				{
					if(plateVec[i][j] == name[j]) ++num_char;
				}
			}
			res_str += "\r\n";
		}
		else
		{
			res_str += "No Answer\r\n";
		}
	}
	res_str += "Char accuracy rate:";
	res_str += (1.0 * num_char / (m_images.size() * 6));
	res_str += "\r\n";

	m_res = res_str.c_str();
	UpdateData(FALSE);

	CString filePath = this->m_savepath + "\\plate_recognize.txt";
	std::ofstream resfile(filePath);
	resfile << res_str.c_str();
	resfile.close();
}
Ejemplo n.º 12
0
    int accuracyTest(const char* test_path) {
      std::shared_ptr<easypr::Kv> kv(new easypr::Kv);
      kv->load("etc/chinese_mapping");

      map<string, vector<CPlate>> xmlMap;
      string path(test_path);
      path = path + "/GroundTruth.xml";
      getGroundTruth(xmlMap, path.c_str());

      //cout << xmlMap.size() << endl;
      //cout << xmlMap.begin()->first << endl;
      //vector<CPlate> plateVec = xmlMap.begin()->second;
      //cout << plateVec[0].getPlateStr() << endl;

      XMLNode xMainNode = XMLNode::createXMLTopNode("tagset");
#ifdef OS_WINDOWS
      XMLNode::setGlobalOptions(XMLNode::char_encoding_GBK);
#endif
      auto files = Utils::getFiles(test_path);

      std::string path_result = "result/Result.xml";

      CPlateRecognize pr;

      // 设置Debug模式

      pr.setDebug(false);

      pr.setLifemode(true);

      // 设置要处理的一张图片中最多有多少车牌

      pr.setMaxPlates(4);

      pr.setDetectType(PR_DETECT_COLOR | PR_DETECT_SOBEL);
      //pr.setDetectType(PR_DETECT_CMSER);

      int size = files.size();

      if (0 == size) {
        cout << "No File Found in general_test/native_test!" << endl;
        return 0;
      }

      cout << "Begin to test the easypr accuracy!" << endl;

      // 总的测试图片数量

      int count_all = 0;

      // 错误的图片数量

      int count_err = 0;

      // 未识别的图片数量

      int count_norecogin = 0;

      std::list<std::string> not_recognized_files;

      // 总的字符差距

      float diff_all = 0;

      // 平均字符差距

      float diff_avg = 0;

      // 完全匹配的识别次数

      float match_count = 0;

      // 完全匹配的识别次数所占识别图片中的比例

      float match_rate = 0;

      // 开始和结束时间

      time_t begin, end;
      time(&begin);

      for (int i = 0; i < size; i++) {
        string filepath = files[i].c_str();

        // EasyPR开始判断车牌

        Mat src = imread(filepath);

        // 如果是非图像文件,直接过去

        if (!src.data) continue;

        cout << "------------------" << endl;

        // 获取真实的车牌

        string plateLicense = Utils::getFileName(filepath);
        cout << kv->get("original_plate") << ":" << plateLicense << endl;

        XMLNode xNode = xMainNode.addChild("image");
        xNode.addChild("imageName").addText(plateLicense.c_str());

        map<string, vector<CPlate>>::iterator it;

        it = xmlMap.find(plateLicense);
        if (it != xmlMap.end()) {
          cout << it->first << endl;
          vector<CPlate> plateVec = it->second;
          for (auto plate : plateVec) {
            cout << plate.getPlateStr() << " (g)" << endl;
          }
        }

        XMLNode rectangleNodes = xNode.addChild("taggedRectangles");
        vector<CPlate> plateVec;

        int result = pr.plateRecognize(src, plateVec);
        //int result = pr.plateRecognizeAsText(src, plateVec);
        if (result == 0) {
          int num = plateVec.size();

          if (num == 0) {
            cout << kv->get("empty_plate") << endl;
            if (plateLicense != kv->get("empty_plate")) {
              not_recognized_files.push_back(plateLicense);
              count_norecogin++;
            }
          }
          else if (num > 1) {

            // 多车牌使用diff最小的那个记录

            int mindiff = 10000;
            for (int j = 0; j < num; j++) {
              cout << plateVec[j].getPlateStr() << " (" << j + 1 << ")" << endl;

              XMLNode rectangleNode = rectangleNodes.addChild("taggedRectangle");
              RotatedRect rr = plateVec[j].getPlatePos();
              LocateType locateType = plateVec[j].getPlateLocateType();

              rectangleNode.addAttribute("x", to_string((int)rr.center.x).c_str());
              rectangleNode.addAttribute("y", to_string((int)rr.center.y).c_str());
              rectangleNode.addAttribute("width", to_string((int)rr.size.width).c_str());
              rectangleNode.addAttribute("height", to_string((int)rr.size.height).c_str());

              rectangleNode.addAttribute("rotation", to_string((int)rr.angle).c_str());
              rectangleNode.addAttribute("locateType", to_string(locateType).c_str());
              rectangleNode.addText(plateVec[j].getPlateStr().c_str());

              string colorplate = plateVec[j].getPlateStr();

              // 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小"

              vector<string> spilt_plate = Utils::splitString(colorplate, ':');

              int size = spilt_plate.size();
              if (size == 2 && spilt_plate[1] != "") {
                int diff = utils::levenshtein_distance(plateLicense,
                  spilt_plate[size - 1]);
                if (diff < mindiff) mindiff = diff;
              }
            }

            cout << kv->get("diff") << ":" << mindiff << kv->get("char") << endl;
            if (mindiff == 0) {

              // 完全匹配

              match_count++;
            }
            diff_all = diff_all + mindiff;
          }
          else {

            // 单车牌只计算一次diff

            for (int j = 0; j < num; j++) {
              cout << plateVec[j].getPlateStr() << endl;

              XMLNode rectangleNode = rectangleNodes.addChild("taggedRectangle");
              RotatedRect rr = plateVec[j].getPlatePos();
              LocateType locateType = plateVec[j].getPlateLocateType();

              rectangleNode.addAttribute("x", to_string((int)rr.center.x).c_str());
              rectangleNode.addAttribute("y", to_string((int)rr.center.y).c_str());
              rectangleNode.addAttribute("width", to_string((int)rr.size.width).c_str());
              rectangleNode.addAttribute("height", to_string((int)rr.size.height).c_str());

              rectangleNode.addAttribute("rotation", to_string((int)rr.angle).c_str());
              rectangleNode.addAttribute("locateType", to_string(locateType).c_str());
              rectangleNode.addText(plateVec[j].getPlateStr().c_str());

              string colorplate = plateVec[j].getPlateStr();

              // 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小"

              vector<string> spilt_plate = Utils::splitString(colorplate, ':');

              int size = spilt_plate.size();
              if (size == 2 && spilt_plate[1] != "") {
                int diff = utils::levenshtein_distance(plateLicense,
                  spilt_plate[size - 1]);
                cout << kv->get("diff") << ":" << diff << kv->get("char") << endl;

                if (diff == 0) {

                  // 完全匹配

                  match_count++;
                }
                diff_all = diff_all + diff;
              }
            }
          }
        }
        else {
          cout << kv->get("error_code") << ":" << result << endl;
          count_err++;
        }
        count_all++;
      }
      time(&end);

      cout << "------------------" << endl;
      cout << "Easypr accuracy test end!" << endl;
      cout << "------------------" << endl;
      cout << endl;
      cout << kv->get("summaries") << ":" << endl;
      cout << kv->get("sum_pictures") << ":" << count_all << ",  ";
      cout << kv->get("unrecognized") << ":" << count_norecogin << ",  ";

      xMainNode.writeToFile(path_result.c_str());

      float count_recogin = float(count_all - (count_err + count_norecogin));
      float count_rate = count_recogin / count_all;
      cout << kv->get("locate_rate") << ":" << count_rate * 100 << "%  " << endl;

      if (count_recogin > 0) {
        diff_avg = diff_all / count_recogin;
      }

      if (count_recogin > 0) {
        match_rate = match_count / count_recogin * 100;
      }

      cout << kv->get("diff_average") << ":" << diff_avg << ",  ";
      cout << kv->get("full_match") << ":" << match_count << ",  ";
      cout << kv->get("full_rate") << ":" << match_rate << "%  " << endl;

      double seconds = difftime(end, begin);
      double avgsec = seconds / double(count_all);

      cout << kv->get("seconds") << ":" << seconds << kv->get("sec") << ",  ";
      cout << kv->get("seconds_average") << ":" << avgsec << kv->get("sec") << endl;

      cout << kv->get("unrecognized") << ":" << endl;

      for (auto it = not_recognized_files.begin(); it != not_recognized_files.end();
        ++it) {
        cout << *it << endl;
      }

      cout << endl;

      cout << "------------------" << endl;

      ofstream myfile("accuracy.txt", ios::app);
      if (myfile.is_open()) {
        time_t t = time(0);  // get time now
        struct tm* now = localtime(&t);
        char buf[80];

        strftime(buf, sizeof(buf), "%Y-%m-%d %X", now);
        myfile << string(buf) << endl;

        myfile << kv->get("sum_pictures") << ":" << count_all << ",  ";
        myfile << kv->get("unrecognized") << ":" << count_norecogin << ",  ";
        myfile << kv->get("locate_rate") << ":" << count_rate * 100 << "%  "
          << endl;
        myfile << kv->get("diff_average") << ":" << diff_avg << ",  ";
        myfile << kv->get("full_match") << ":" << match_count << ",  ";
        myfile << kv->get("full_rate") << ":" << match_rate << "%  " << endl;
        myfile << kv->get("seconds") << ":" << seconds << kv->get("sec") << ",  ";
        myfile << kv->get("seconds_average") << ":" << avgsec << kv->get("sec")
          << endl;
        myfile.close();
      }
      else {
        cout << "Unable to open file";
      }
      return 0;
    }