VC++ EasyPR车牌识别
生活随笔
收集整理的這篇文章主要介紹了
VC++ EasyPR车牌识别
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
EasyPR是一個開源的中文車牌識別系統,其目標是成為一個簡單、高效、準確的非限制場景(unconstrained situation)下的車牌識別庫。
相比于其他的車牌識別系統,EasyPR有如下特點:
1、它基于openCV這個開源庫。這意味著你可以獲取全部源代碼,并且移植到opencv支持的所有平臺。
2、它能夠識別中文。例如車牌為蘇EUK722的圖片,它可以準確地輸出std:string類型的"蘇EUK722"的結果。
3、它的識別率較高。圖片清晰情況下,車牌檢測與字符識別可以達到80%以上的精度。
其源碼下載鏈接:https://gitee.com/easypr/EasyPR
官方提供了一個功能詳細的Demo,在這里僅僅是對Demo做一個封裝,為了更方便其他應用程序調用,其接口聲明如下(libPRSDK.h):
#ifdef LIPRSDK_EXPORTS #define LIPRSDK_API extern "C" __declspec(dllexport) #else #define LIPRSDK_API extern "C" __declspec(dllimport) #endif/* 說明:資源初始化 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API BOOL IPR_Startup();/* 說明:資源清理 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API BOOL IPR_Cleanup();/* 說明:車牌定位 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_PlateLocateFromMemory(int width, int height, char* yuv, int size); LIPRSDK_API int IPR_PlateLocateFromFile(char* filename);/* 說明:車牌判斷 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_PlateJudgeFromMemory(int width, int height, char* yuv, int size); LIPRSDK_API int IPR_PlateJudgeFromFile(char* filename); /* 說明:車牌檢測 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_PlateDetectFromMemory(int width, int height, char* yuv, int size); LIPRSDK_API int IPR_PlateDetectFromFile(char* filename);/* 說明:車牌識別 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_PlateRecogniseFromMemory(int width, int height, char* yuv, int size, char* szPlate, int* lenPlate); LIPRSDK_API int IPR_PlateRecogniseFromFile(char* filename, char* szPlate, int* lenPlate);/* 說明:字符分離 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_CharsSegmentFromMemory(int width, int height, char* yuv, int size); LIPRSDK_API int IPR_CharsSegmentFromFile(char* filename);/* 說明:字符鑒別 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_CharsIdentifyFromMemory(int width, int height, char* yuv, int size, char* szLicense); LIPRSDK_API int IPR_CharsIdentifyFromFile(char* filename, char* szLicense);/* 說明:字符識別 參數:(無) 返回值:0-成功,-1失敗 */ LIPRSDK_API int IPR_CharsRecogniseFromMemory(int width, int height, char* yuv, int size, char* szPlate, int* lenPlate); LIPRSDK_API int IPR_CharsRecogniseFromFile(char* filename, char* szPlate, int* lenPlate);源碼實現(libPRSDK.cpp):
// libPRSDK.cpp : 定義 DLL 應用程序的導出函數。 //#include "stdafx.h" #include "libPRSDK.h"#ifdef _DEBUG #pragma comment(lib,"../../codev1.6/build/libEasyPRD.lib") #else #pragma comment(lib,"../../codev1.6/build/libEasyPR.lib") #endif#include "../../codev1.6/include/easypr.h" #include "../../codev1.6/include/easypr/util/switch.hpp"using namespace cv; using namespace std; using namespace easypr;#include "wtypes.h" BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize) {// Get the required size of the buffer that receives the Unicode // string. DWORD dwMinSize;dwMinSize = MultiByteToWideChar(CP_ACP, 0, lpcszStr, -1, NULL, 0);if (dwSize < dwMinSize){return FALSE;}// Convert headers from ASCII to Unicode.MultiByteToWideChar(CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);return TRUE; }//------------------------------------------------------------------------------------- //Description: // This function maps a wide-character string to a new character string // //Parameters: // lpcwszStr: [in] Pointer to the character string to be converted // lpszStr: [out] Pointer to a buffer that receives the translated string. // dwSize: [in] Size of the buffer // //Return Values: // TRUE: Succeed // FALSE: Failed // //Example: // MByteToWChar(szW,szA,sizeof(szA)/sizeof(szA[0])); //--------------------------------------------------------------------------------------- BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize) {DWORD dwMinSize;dwMinSize = WideCharToMultiByte(CP_OEMCP, NULL, lpcwszStr, -1, NULL, 0, NULL, FALSE);if (dwSize < dwMinSize){return FALSE;}WideCharToMultiByte(CP_OEMCP, NULL, lpcwszStr, -1, lpszStr, dwSize, NULL, FALSE);return TRUE; }// 使用方法也很簡單, 示例如下: // wchar_t wText[10] = { L"函數示例" }; // char sText[20] = { 0 }; // WCharToMByte(wText, sText, sizeof(sText) / sizeof(sText[0])); // MByteToWChar(sText, wText, sizeof(wText) / sizeof(wText[0])); ///* 說明:資源初始化 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API BOOL IPR_Startup() {return FALSE; }/* 說明:資源清理 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API BOOL IPR_Cleanup() {return FALSE; }/* 說明:車牌定位 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_PlateLocateFromMemory(int width, int height, char* yuv, int size) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat src;cv::cvtColor(yuvImg, src, CV_YUV2BGR_I420);vector<cv::Mat> resultVec;CPlateLocate plate;plate.setDebug(1);plate.setLifemode(true);int result = plate.plateLocate(src, resultVec);if (result > 0)return -1;size_t num = resultVec.size();for (size_t j = 0; j < num; j++) {cv::Mat resultMat = resultVec[j];// 車牌識別CCharsRecognise cr;std::string plateLicense = "";int result = cr.charsRecognise(resultMat, plateLicense);if (result == 0) {return 0; // std::cout << "charsRecognise: " << plateLicense << std::endl; // vector<int> compression_params; // compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);//CV_IMWRITE_JPEG_QUALITY(0~100) CV_IMWRITE_PNG_COMPRESSION(0~9) // compression_params.push_back(9); // try { // cv::String sText = Utils::utf8_to_gbk("D:\\plate_locate_resultxxx.png"); // imwrite(sText, resultMat, compression_params);// 車牌保存()注意:路徑不支持中文 // } // catch (runtime_error& ex) { // fprintf(stderr, "Exception converting image to png format: %s\n", ex.what()); // }// YUV轉Mat// int bufLen = w * h * 3 / 2;// unsigned char* pYuvBuf = new unsigned char[bufLen];// cv::Mat yuvImg;// yuvImg.create(h * 3 / 2, w, CV_8UC1);// memcpy(yuvImg.data, pYuvBuf, bufLen*sizeof(unsigned char));// // // YUV轉RGB// cv::Mat rgbImg;// cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);// MatRGB轉MatYUV轉YUV// cv::Mat srcImg;// cv::Mat yuvImg;// cv::cvtColor(srcImg, yuvImg, CV_BGR2YUV_I420);// int bufLen = w * h * 3 / 2;// unsigned char* pYuvBuf = new unsigned char[bufLen];// memcpy(pYuvBuf, yuvImg.data, bufLen*sizeof(unsigned char));}}return 0; }LIPRSDK_API int IPR_PlateLocateFromFile(char* filename) {const string file = filename;// "resources/image/test.jpg";cv::Mat src = imread(file);vector<cv::Mat> resultVec;CPlateLocate plate;plate.setDebug(1);plate.setLifemode(true);int result = plate.plateLocate(src, resultVec);if (result > 0)return -1;size_t num = resultVec.size();for (size_t j = 0; j < num; j++) {cv::Mat resultMat = resultVec[j];// 車牌識別CCharsRecognise cr;std::string plateLicense = "";int result = cr.charsRecognise(resultMat, plateLicense);if (result == 0) {return 0; // std::cout << "charsRecognise: " << plateLicense << std::endl; // // // 車牌保存()注意:路徑不支持中文 // vector<int> compression_params; // compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);//CV_IMWRITE_JPEG_QUALITY(0~100) CV_IMWRITE_PNG_COMPRESSION(0~9) // compression_params.push_back(9); // try { // cv::String sText = "F:\\EasyPR(車牌識別)\\plate_locate_resultxxx.png"; // imwrite(sText, resultMat, compression_params); // } // catch (runtime_error& ex) { // fprintf(stderr, "Exception converting image to png format: %s\n", ex.what()); // }// YUV轉Mat// int bufLen = w * h * 3 / 2;// unsigned char* pYuvBuf = new unsigned char[bufLen];// cv::Mat yuvImg;// yuvImg.create(h * 3 / 2, w, CV_8UC1);// memcpy(yuvImg.data, pYuvBuf, bufLen*sizeof(unsigned char));// // // YUV轉RGB// cv::Mat rgbImg;// cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);// MatRGB轉MatYUV轉YUV// cv::Mat srcImg;// cv::Mat yuvImg;// cv::cvtColor(srcImg, yuvImg, CV_BGR2YUV_I420);// int bufLen = w * h * 3 / 2;// unsigned char* pYuvBuf = new unsigned char[bufLen];// memcpy(pYuvBuf, yuvImg.data, bufLen*sizeof(unsigned char));// imshow("plate_locate", resultMat); // waitKey(0); // destroyWindow("plate_judge");}}return -1; }/* 說明:車牌判斷 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_PlateJudgeFromMemory(int width, int height, char* yuv, int size) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat src;cv::cvtColor(yuvImg, src, CV_YUV2BGR_I420);vector<cv::Mat> matVec;vector<cv::Mat> resultVec;CPlateLocate lo;lo.setDebug(1);lo.setLifemode(true);int resultLo = lo.plateLocate(src, matVec);if (0 != resultLo)return -1;cout << "plate_locate_img" << endl;size_t num = matVec.size();for (size_t j = 0; j < num; j++) {Mat resultMat = matVec[j];}int resultJu = PlateJudge::instance()->plateJudge(matVec, resultVec);if (0 != resultJu)return -1;num = resultVec.size();for (size_t j = 0; j < num; j++) {Mat resultMat = resultVec[j];}return resultJu; }LIPRSDK_API int IPR_PlateJudgeFromFile(char* filename) {const string file = filename;// Utils::utf8_to_gbk(filename);cv::Mat src = imread(file);vector<cv::Mat> matVec;vector<cv::Mat> resultVec;CPlateLocate lo;lo.setDebug(1);lo.setLifemode(true);int resultLo = lo.plateLocate(src, matVec);if (0 != resultLo) return -1;cout << "plate_locate_img" << endl;size_t num = matVec.size();for (size_t j = 0; j < num; j++) {Mat resultMat = matVec[j];}int resultJu = PlateJudge::instance()->plateJudge(matVec, resultVec);if (0 != resultJu) return -1;num = resultVec.size();for (size_t j = 0; j < num; j++) {Mat resultMat = resultVec[j];}return resultJu; }/* 說明:車牌檢測 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_PlateDetectFromMemory(int width, int height, char* yuv, int size) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat src;cv::cvtColor(yuvImg, src, CV_YUV2BGR_I420);vector<CPlate> resultVec;CPlateDetect pd;pd.setPDLifemode(true);int result = pd.plateDetect(src, resultVec);if (result == 0) {size_t num = resultVec.size();for (size_t j = 0; j < num; j++) {CPlate resultMat = resultVec[j];}}return result; }LIPRSDK_API int IPR_PlateDetectFromFile(char* filename) {const string file = filename;// Utils::utf8_to_gbk(filename);cv::Mat src = imread(file);vector<CPlate> resultVec;CPlateDetect pd;pd.setPDLifemode(true);int result = pd.plateDetect(src, resultVec);if (result == 0) {size_t num = resultVec.size();for (size_t j = 0; j < num; j++) {CPlate resultMat = resultVec[j];}}return result; }/* 說明:車牌識別 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_PlateRecogniseFromMemory(int width, int height, char* yuv, int size, char* plate, int* lenPlate) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat src;cv::cvtColor(yuvImg, src, CV_YUV2BGR_I420);CPlateRecognize pr;pr.setLifemode(true);pr.setDebug(true);vector<string> plateVec;int result = pr.plateRecognize(src, plateVec);if (result == 0) {*lenPlate = 0;size_t num = plateVec.size();for (size_t j = 0; j < num; j++) {if (j > 1) {memcpy(plate, "|", 1);*lenPlate += 1;}memcpy(plate, plateVec[j].c_str(), plateVec[j].length());*lenPlate += plateVec[j].length();}}return result; }LIPRSDK_API int IPR_PlateRecogniseFromFile(char* filename, char* plate, int* lenPlate) {const string file = filename;// Utils::utf8_to_gbk(filename);cv::Mat src = imread(file);CPlateRecognize pr;pr.setLifemode(true);//pr.setDebug(true);vector<string> plateVec;int result = pr.plateRecognize(src, plateVec);if (result == 0) {*lenPlate = 0;size_t num = plateVec.size();for (size_t j = 0; j < num; j++) {if (strstr(plate, plateVec[j].c_str()) <= 0){if (j > 0) {strcat_s(plate, 256, "|");*lenPlate += 1;}strcat_s(plate, 256, plateVec[j].c_str());*lenPlate += plateVec[j].length();}}}return result; }/* 說明:字符分離 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_CharsSegmentFromMemory(int width, int height, char* yuv, int size) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat src;cv::cvtColor(yuvImg, src, CV_YUV2BGR_I420);std::vector<cv::Mat> resultVec;CCharsSegment plate;int result = plate.charsSegment(src, resultVec);if (result == 0) {size_t num = resultVec.size();for (size_t j = 0; j < num; j++) {cv::Mat resultMat = resultVec[j];}}return result; }LIPRSDK_API int IPR_CharsSegmentFromFile(char* filename) {const string file = filename;// Utils::utf8_to_gbk(filename);cv::Mat src = imread(file);std::vector<cv::Mat> resultVec;CCharsSegment plate;int result = plate.charsSegment(src, resultVec);if (result == 0) {size_t num = resultVec.size();for (size_t j = 0; j < num; j++) {cv::Mat resultMat = resultVec[j];}}return result; }/* 說明:字符鑒別 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_CharsIdentifyFromMemory(int width, int height, char* yuv, int size, char* szLicense) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat plate;cv::cvtColor(yuvImg, plate, CV_YUV2BGR_I420);std::vector<Mat> matChars;std::string license;CCharsSegment cs;int result = cs.charsSegment(plate, matChars);if (result == 0) {for (auto block : matChars) {auto character = CharsIdentify::instance()->identify(block);license.append(character.second);}}std::string plateLicense = szLicense;// "蘇E771H6"; #ifdef OS_WINDOWSplateLicense = easypr::utils::utf8_to_gbk(plateLicense.c_str()); #endifstd::cout << "plateLicense: " << plateLicense << std::endl;std::cout << "plateIdentify: " << license << std::endl;if (plateLicense != license) {std::cout << "Identify Not Correct!" << std::endl;return -1;}std::cout << "Identify Correct!" << std::endl;return result; }LIPRSDK_API int IPR_CharsIdentifyFromFile(char* filename, char* szLicense) {const string file = filename;// Utils::utf8_to_gbk(filename);cv::Mat plate = imread(file);std::vector<Mat> matChars;std::string license;CCharsSegment cs;int result = cs.charsSegment(plate, matChars);if (result == 0) {for (auto block : matChars) {auto character = CharsIdentify::instance()->identify(block);license.append(character.second);}}std::string plateLicense = szLicense;// "蘇E771H6"; #ifdef OS_WINDOWSplateLicense = easypr::utils::utf8_to_gbk(plateLicense.c_str()); #endifstd::cout << "plateLicense: " << plateLicense << std::endl;std::cout << "plateIdentify: " << license << std::endl;if (plateLicense != license) {std::cout << "Identify Not Correct!" << std::endl;return -1;}std::cout << "Identify Correct!" << std::endl;return result; }/* 說明:字符識別 參數:(無) 返回值:TRUE-成功,FALSE-失敗 */ LIPRSDK_API int IPR_CharsRecogniseFromMemory(int width, int height, char* yuv, int size, char* szPlate, int* lenPlate) {int bufLen = width * height * 3 / 2;if (size != bufLen)return -1;// YUV轉Matcv::Mat yuvImg;yuvImg.create(height * 3 / 2, width, CV_8UC1);memcpy(yuvImg.data, yuv, bufLen*sizeof(unsigned char));// MatYUV轉MatRGBcv::Mat src;cv::cvtColor(yuvImg, src, CV_YUV2BGR_I420);CCharsRecognise cr;std::string plateLicense = "";int result = cr.charsRecognise(src, plateLicense);if (result == 0){memcpy(szPlate, plateLicense.c_str(), plateLicense.length());*lenPlate = plateLicense.length();}return result; }LIPRSDK_API int IPR_CharsRecogniseFromFile(char* filename, char* plate, int* lenPlate) {const string file = filename;// Utils::utf8_to_gbk(filename);cv::Mat src = imread(file);CCharsRecognise cr;std::string plateLicense = "";int result = cr.charsRecognise(src, plateLicense);if (result == 0){memcpy(plate, plateLicense.c_str(), plateLicense.length());*lenPlate = plateLicense.length();}return result; }?
總結
以上是生活随笔為你收集整理的VC++ EasyPR车牌识别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Schema详解
- 下一篇: What code you will g