Coder Social home page Coder Social logo

liuruoze / easypr Goto Github PK

View Code? Open in Web Editor NEW
6.3K 525.0 2.5K 190.46 MB

(CGCSTCD'2017) An easy, flexible, and accurate plate recognition project for Chinese licenses in unconstrained situations. CGCSTCD = China Graduate Contest on Smart-city Technology and Creative Design

License: Apache License 2.0

C++ 98.13% CMake 0.48% C 0.10% Shell 0.02% Python 1.28%
computer-vision machine-learning artificial-intelligence plate-recognition unconstrained-situation datasets artificial-neural-networks support-vector-machines supervised-learning chinese-characters

easypr's People

Contributors

fugangqiang avatar igrass avatar lbyfind avatar liuruoze avatar micooz avatar zhangxinnan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easypr's Issues

EasyPR 车标识别

能够识别车子的类型,例如大众,宝马,奔驰,尼桑,丰田等。

svm_train bug

我在windows测试SVM train的时候遇到一个问题。
文件名是plate_344.jpg,但是sprintf之后save_to就不对了,我改成如下就过了:
sprintf(save_to, "%s/train/%s", images_folder, file_name.c_str());

PS: 目前divide必须手动添加目录/has/train, /has/test, /no/train/, /no/test;为啥不检验一下目录是否存在,然后自动添加呢?比如在UTIL里添加:

bool Util::testIfFolderExist(const string &folder) {

if defined(WIN32) || defined(_WIN32)

if (_access(folder.c_str(), 0) == 0)
    return true;
else {
    string command = "mkdir " + folder;
    system(command.c_str());
    return true;
}

elif defined(linux) || defined(linux) || defined(APPLE)

DIR *dp;
if ((dp = opendir(path)) == NULL) {
    string command = "mkdir -p " + folder;
    system(command.c_str());
    return true;
}
else
    return true;

endif

return false;

}

train报错-easypr_test.exe svm --train --has-plate=has/ --no-plate=no/ --divide --svm=mo del/svm.xml

Dividing data to be trained and tested...
has/京CX8888_0.jpg -> has//train/京CX8888_0.jpg
has/赣A82F36_12.jpg -> has//train/赣A82F36_12.jpg
has/京A88731_0.jpg -> has//train/京A88731_0.jpg
has/京A88731_2.jpg -> has//train/京A88731_2.jpg
has/京CX8888_1.jpg -> has//test/京CX8888_1.jpg
has/京H99999_0.jpg -> has//test/京H99999_0.jpg
no/赣A82F36_5.jpg -> no//train/赣A82F36_5.jpg
no/赣A82F36_0.jpg -> no//train/赣A82F36_0.jpg
no/京A88731_1.jpg -> no//train/京A88731_1.jpg
no/京H99999_4.jpg -> no//train/京H99999_4.jpg
no/赣A82F36_10.jpg -> no//train/赣A82F36_10.jpg
no/京H99999_3.jpg -> no//train/京H99999_3.jpg
no/赣A82F36_8.jpg -> no//train/赣A82F36_8.jpg
no/赣A82F36_6.jpg -> no//train/赣A82F36_6.jpg
no/京CX8888_2.jpg -> no//train/京CX8888_2.jpg
no/京H99999_2.jpg -> no//train/京H99999_2.jpg
no/京H99999_1.jpg -> no//train/京H99999_1.jpg
no/京H99999_5.jpg -> no//train/京H99999_5.jpg
no/京A88731_4.jpg -> no//train/京A88731_4.jpg
no/赣A82F36_11.jpg -> no//train/赣A82F36_11.jpg
no/赣A82F36_9.jpg -> no//train/赣A82F36_9.jpg
no/赣A82F36_13.jpg -> no//test/赣A82F36_13.jpg
no/赣A82F36_1.jpg -> no//test/赣A82F36_1.jpg
no/赣A82F36_3.jpg -> no//test/赣A82F36_3.jpg
no/赣A82F36_7.jpg -> no//test/赣A82F36_7.jpg
no/赣A82F36_2.jpg -> no//test/赣A82F36_2.jpg
no/赣A82F36_4.jpg -> no//test/赣A82F36_4.jpg
no/京A88731_3.jpg -> no//test/京A88731_3.jpg
Collecting train data...
Collecting train data in has//train
Collecting train data in no//train
Generating svm model file, please wait...
OpenCV Error: Bad argument (While cross-validation one or more of the classes ha
ve been fell out of the sample. Try to enlarge CvSVMParams::k_fold) in CvSVM::
do_train, file C:\builds\2_4_PackSlave-win32-vc12-shared\opencv\modules\ml\src\s
vm.cpp, line 1402
C:\builds\2_4_PackSlave-win32-vc12-shared\opencv\modules\ml\src\svm.cpp:1402: er
ror: (-5) While cross-validation one or more of the classes have been fell out o
f the sample. Try to enlarge CvSVMParams::k_fold in function CvSVM::do_train

OpenCV Error: Null pointer (Invalid pointer to file storage) in cvStartWriteStru
ct, file C:\builds\2_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\persi
stence.cpp, line 2948

v1.2 centos 编译出错,刚下载的

环境:
2.6.32-504.1.3.el6.x86_64 #1 SMP Tue Nov 11 17:57:25 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
opencv-2.4.9

[root@v01lab EasyPR-1.2]# make
Scanning dependencies of target EasyPR
[ 4%] Building CXX object CMakeFiles/EasyPR.dir/src/main.cpp.o
[ 9%] Building CXX object CMakeFiles/EasyPR.dir/src/core/core_func.cpp.o
[ 13%] Building CXX object CMakeFiles/EasyPR.dir/src/core/chars_identify.cpp.o
[ 18%] Building CXX object CMakeFiles/EasyPR.dir/src/core/chars_recognise.cpp.o
/home/pr/EasyPR12/src/core/chars_recognise.cpp: In constructor ‘easypr::CCharsRecognise::CCharsRecognise()’:
/home/pr/EasyPR12/src/core/chars_recognise.cpp:9: error: ‘nullptr’ was not declared in this scope
/home/pr/EasyPR12/src/core/chars_recognise.cpp: In destructor ‘easypr::CCharsRecognise::~CCharsRecognise()’:
/home/pr/EasyPR12/src/core/chars_recognise.cpp:17: error: ‘nullptr’ was not declared in this scope
/home/pr/EasyPR12/src/core/chars_recognise.cpp:21: error: ‘nullptr’ was not declared in this scope
make[2]: *** [CMakeFiles/EasyPR.dir/src/core/chars_recognise.cpp.o] Error 1
make[1]: *** [CMakeFiles/EasyPR.dir/all] Error 2
make: *** [all] Error 2

如何自己训练 SVM 模型呢?

我看了开发教程,也看了程序,还是没搞清楚我该怎么自己训练 SVM 模型。 请楼主点拨一下好吗?谢谢!

无法识别代码里面的百度测试图片

EasyPR-Java-master\res\image\baidu_image 里面百度图片很多都无法识别,我是直接用test的代码测试的,我发现一个现象是无法识别的车牌很多都是车牌上面装了个金属框的,我大概调试了一下代码,发现定位代码部分是定位到车牌了,但是定位车牌的区域比实际车牌区域要大,导致后来的OCR字符识别失效了,作者能针对这个优化一下吗?

源代码编码支持UTF8,easypr_test界面支持UTF8

车牌识别感觉就这个项目很靠谱,下载了一个到mac下试了一下。源代码注释都是乱码,easypr_test的输出都是乱码(连输出的车牌号都是乱码)。

不知道是我哪个地方设置不正确,还是真有问题。希望能改进一下,方便linux平台的开发和调试。

训练生成的svm.xml应该怎么用?

根据文档
2015-07-08 11 33 27
生成的训练结果,我把他替换到了resources/model里面,然后再测试的时候提示出错,请问我是哪里有问题吗?

错误信息:
OpenCV Error: Sizes of input arguments do not match (The sample size is different from what has been used for training) in cvPreparePredictData, file /tmp/opencv20150611-92017-pixpdt/opencv-2.4.11/modules/ml/src/inner_functions.cpp, line 1114
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv20150611-92017-pixpdt/opencv-2.4.11/modules/ml/src/inner_functions.cpp:1114: error: (-209) The sample size is different from what has been used for training in function cvPreparePredictData

mac 遇到错误 EasyPR/include/easypr/util.h:74:42: error: no type named 'initializer_list' in namespace 'std' static void print_str_lines(const std::initializer_list<const char*>& lines) {

cmake . 之后,运行make 时遇到了下面的错误:
$ make
[ 5%] Building CXX object CMakeFiles/easypr.dir/src/core/chars_segment.cpp.o
In file included from ~/EasyPR/src/core/chars_segment.cpp:2:
~/EasyPR/include/easypr/util.h:74:42: error: no type named 'initializer_list' in namespace 'std'
static void print_str_lines(const std::initializer_list<const char*>& lines) {
~~~~~^
~/EasyPR/include/easypr/util.h:74:58: error: expected ')'
static void print_str_lines(const std::initializer_list<const char*>& lines) {
^
~/EasyPR/include/easypr/util.h:74:30: note: to match this '('
static void print_str_lines(const std::initializer_list<const char*>& lines) {
^
~/EasyPR/include/easypr/util.h:75:22: error: use of undeclared identifier 'lines'; did you mean 'line'?
for (auto line : lines) {
^~~~~
line
/usr/local/include/opencv2/core/core.hpp:2613:19: note: 'line' declared here
CV_EXPORTS_W void line(CV_IN_OUT Mat& img, Point pt1, Point pt2, const Scalar& color,
^
In file included from ~/EasyPR/src/core/chars_segment.cpp:2:
~/EasyPR/include/easypr/util.h:75:20: error: invalid range expression of type
'void (cv::Mat &, cv::Point_, cv::Point_, const cv::Scalar_ &, int, int, int)'; no viable 'begin' function available
for (auto line : lines) {

不知道您在做mac os 移植的时候是怎样解决的。 我的Mac 版本是 10.10.2

谢谢!

profle模块

开发一个profile类,可以监控EasyPR在识别车牌过程中各个模块(定位,svm判断,分割,识别字符)的时间消耗,以此定位程序中的性能瓶颈

求linux编译方法

因为不怎么懂C++,也没有windows的VC环境,求教如何在linux或者mac下编译

windows编译失败

1>core\debug\11_manifest.rc(1): error RC2135: file not found: Debug\11.exe.embed.manifest

字符识别改进(2)

目前EasyPR对字符识别的准确率较差,需要改进字符识别。

第二个任务(难度:简单):
2.在训练数据上训练模型,在测试数据上测试,使用precise与recall和fscore来衡量准确率;

极端情况下车牌识别

作者您好,我想问下源码中提供的extreme_test,目前我实验时结果都是“无车牌”,是暂时不能识别,还是我个人的问题?

用cmake编译时出现如下错误

/home/root/EasyPR-master/src/core/core_func.cpp: In function 'cv::Mat easypr::colorMatch(const cv::Mat&, cv::Mat&, easypr::Color, bool)':
/home/root/EasyPR-master/src/core/core_func.cpp:45:3: error: 'vector' was not declared in this scope
vector hsvSplit;
^

我的g++版本是4.9.1,还有很多错误,不好复制过来,似乎大意是找不到vector这个类,需要使用std::vector
求问如何解决?

linux编译出错

CMakeFiles/EasyPR.dir/src/util/generate_gdts.cpp.o: In function generate_gdts()': generate_gdts.cpp:(.text+0x17): undefined reference tocv::CascadeClassifier::CascadeClassifier()'
generate_gdts.cpp:(.text+0x190): undefined reference to cv::imread(std::string const&, int)' generate_gdts.cpp:(.text+0x330): undefined reference tocv::_InputArray::_InputArray(cv::Mat const&)'
generate_gdts.cpp:(.text+0x369): undefined reference to cv::imwrite(std::string const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)' generate_gdts.cpp:(.text+0x43b): undefined reference tocv::CascadeClassifier::~CascadeClassifier()'
generate_gdts.cpp:(.text+0x590): undefined reference to cv::CascadeClassifier::~CascadeClassifier()' CMakeFiles/EasyPR.dir/src/util/learn_prepare.cpp.o: In functionlabel_data()':
learn_prepare.cpp:(.text+0x21c): undefined reference to cv::imread(std::string const&, int)' learn_prepare.cpp:(.text+0x3b4): undefined reference tocv::_InputArray::_InputArray(cv::Mat const&)'
都是一些这种类似的问题

Assertion failed Issues about cv::Mat

error1
您好,请问一下,目前使用1.3版将image/test.jpg进行3-1产生notlabel数据后,执行选项3-2 的”标签learndata” 会出现如上的Assertion failed信息,关于这个错误,是否会在1.3正式版修正,谢谢!!

运行报错

平台:OS X 10.10.4

OpenCV 版本:2.4.11

运行命令:./easypr_test recognize -p ../resources/image/plate_recognize.jpg --svm ../resources/model/svm.xml -ann ../resources/model/ann.xml

目录结构:以上命令路径没错

错误信息:OpenCV Error: Assertion failed (layer_sizes != 0) in predict, file /tmp/opencv20150611-92017-pixpdt/opencv-2.4.11/modules/ml/src/ann_mlp.cpp, line 1611
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv20150611-92017-pixpdt/opencv-2.4.11/modules/ml/src/ann_mlp.cpp:1611: error: (-215) layer_sizes != 0 in function predict

用四周的线信息进行二次精准定位

目前定位的车牌,有时候会由于soble或颜色的误差,导致车牌定位不正。或者定位的范围过小,没有覆盖全部的车牌,或者定位的范围过大,只有部分是车牌。如果在一次定位的基础上,再配合车牌四周本身的线信息进行二次定位,就会大幅度减少这种定位不正的现象,从而形成精准定位。

此改进建议放到字符识别完善以后进行。

运行“测试-车牌检测”时,程序出错

我是用的Windows版本。
在测试(testMain();)中,最新版本的车牌检测的主要函数是int result = pd.plateDetect(src, resultVec);,可是这个函数会出错。老版本的函数是int result = pd.plateDetectDeep(src, resultVec);,不会出错。不知其他人遇到这个问题没。

关于easypr/util.h中的getFiles函数

认为你们是用的写法在具体上似乎有些结构混乱

  • 额我的意思是,有一些看似很浪费的写法。

  • 而且对于 32位和64位的需要分别修改代码。

  • 我的建议是这样,不如使用微软推荐的写法:

    HANDLE fileHandle;
    WIN32_FIND_DATAA fileData; //这个就无需考虑 32还是64位了
    
  • 使用递归来获取子文件夹内部的文件比用循环来的好多了,尤其是代码的清晰度上,很容易进行重构。

  • 如果考虑效率,在一个短小的递归中只要代码足够清晰,编译器能够为你优化出不逊色于循环的执行码来,尤其是对 VC++ 这种怪兽级别的家伙。

    if(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
        if(strcmp(fileData.cFileName, ".") == 0 ||
           strcmp(fileData.cFileName, "..") == 0)
                continue;
        strcat(tempDirBuf, fileData.cFileName);
        getFile(tempDirBuf, files); // 递归调用,并且使用strcat来代替append让编译器有更好的优化选择。
        ...
    
  • 对于文件

    else
    {
        strcat(tempFileDirBuf, fileData.cFileName);
    files.pushback(tempFileBuf, files);
    }
    
  • 总体 do...while 使用

    do{
    
             ....// Something 
    }while(FindNextFile(fileHandle, &fileData) != 0) ;
    

这是我近来使用你们的项目时候的某些小建议,当然也可能是我考虑的太片面。

字符识别改进(1)

字符识别改进过程请参考“SVM开发详解”。整个过程被分成若干任务。

第一个任务(难度:简单):
1.分割训练数据与测试数据。

车牌定位的改进建议

我在EasyPR原来的边缘检测定位之前加入了根据车牌颜色(蓝色和黄色)粗定位的功能,能较好筛选出作者文档内Q5的车牌区域。望采纳。代码段如下:
//! 定位车牌图像
//! src 原始图像
//! resultVec 一个Mat的向量,存储所有抓取到的图像
//! 成功返回0,否则返回-1
int CPlateLocate::plateLocate(Mat src, vector& resultVec)
{
Mat src_blur, src_gray;
Mat grad;

int scale = SOBEL_SCALE;
int delta = SOBEL_DELTA;
int ddepth = SOBEL_DDEPTH;

if( !src.data )
{ return -1; }

//高斯模糊。Size中的数字影响车牌定位的效果。
GaussianBlur( src, src_blur, Size(m_GaussianBlurSize, m_GaussianBlurSize), 
    0, 0, BORDER_DEFAULT );

if(m_debug)
{ 
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_GaussianBlur" << ".jpg";
    imwrite(ss.str(), src_blur);
}

/// Convert it to gray
cvtColor( src_blur, src_gray, CV_RGB2GRAY );

if(m_debug)
{ 
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_gray" << ".jpg";
    imwrite(ss.str(), src_gray);
}
// RGB颜色初定位
// http://wenku.baidu.com/view/2329e5d2360cba1aa811da65.html?re=view
// RGB -> HSV
//      蓝         黄         白         黑
//H     200~255     25~55       /           /
//S     0.4~1       0.4~1       0~0.1       /
//V     0.3~1       0.3~1       0.9~1       0~0.35
//cvCvtColor(src,dst,CV_BGR2HSV);
//其中,src为三通道的,dst也为三通道的,
//OPENCV 中 H、S、V、顺序分别为3*x+0  3*x+1   3*x+2
//opencv中的 H分量是 0~180, S分量是0~255, V分量是0~255
//但是HSV颜色空间却规定的是,H范围0~360,S范围0~1,V范围0~1
//所以你需要自己转换一下,H*2,S/255, V/255

// 默认蓝色车牌
cv::Mat tmp;
cv::cvtColor(src, tmp, CV_BGR2HSV);
vector<Mat> hsvSplit;
split(tmp, hsvSplit);
cv::Mat dst_blue(src.rows, src.cols, CV_8UC1);
cv::Mat dst_yellow(src.rows, src.cols, CV_8UC1);
for(int i = 0; i<tmp.rows; i++)
{
    for(int j = 0; j<tmp.cols; j++)
    {
        int nH = hsvSplit[0].at<uchar>(i, j)*2;
        float fS = hsvSplit[1].at<uchar>(i, j)/255.0;
        float fV = hsvSplit[2].at<uchar>(i, j)/255.0;
        if(nH>=200 && nH<=255 && fS>=0.4 && fS<=1 && fV>=0.3 && fV<=1) // 蓝色
            dst_blue.at<uchar>(i, j) = 255;
        else
            dst_blue.at<uchar>(i, j) = 0;
    }
}
Mat element_blue = getStructuringElement(MORPH_ELLIPSE, Size(10, 10));
morphologyEx(dst_blue, dst_blue, MORPH_CLOSE, element_blue);
//Find 轮廓 of possibles plates
cv::Mat con_blue = dst_blue.clone();
vector< vector< Point> > contours_blue;
findContours(con_blue,
    contours_blue, // a vector of contours
    CV_RETR_EXTERNAL, // 提取外部轮廓
    CV_CHAIN_APPROX_NONE); // all pixels of each contours
//Start to iterate to each contour founded
vector<vector<Point> >::iterator itb = contours_blue.begin();

//Remove patch that are no inside limits of aspect ratio and area.
int tb = 0;
vector<cv::Rect> rects_blue;
while(itb != contours_blue.end())
{
    //Create bounding rect of object
    RotatedRect mr = minAreaRect(Mat(*itb));

    //large the rect for more
    if(!verifySizes(mr))
    {
        cv::Mat& roi = dst_blue(mr.boundingRect());
        roi.setTo(0);
    }
    else
    {
        rects_blue.push_back(mr.boundingRect());
    }
    ++itb;
}
//////////////////////////////////////////////////////////////////////////
for(int i = 0; i<tmp.rows; i++)
{
    for(int j = 0; j<tmp.cols; j++)
    {
        int nH = hsvSplit[0].at<uchar>(i, j)*2;
        float fS = hsvSplit[1].at<uchar>(i, j)/255.0;
        float fV = hsvSplit[2].at<uchar>(i, j)/255.0;
        if(nH>=25 && nH<=55 && fS>=0.4 && fS<=1 && fV>=0.3 && fV<=1) // 黄色
            dst_yellow.at<uchar>(i, j) = 255;
        else
            dst_yellow.at<uchar>(i, j) = 0;
    }
}

Mat element_yellow = getStructuringElement(MORPH_ELLIPSE, Size(10, 10));
morphologyEx(dst_yellow, dst_yellow, MORPH_CLOSE, element_blue);
//Find 轮廓 of possibles plates
cv::Mat con_yellow = dst_yellow.clone();
vector< vector< Point> > contours_yellow;
findContours(con_yellow,
    contours_yellow, // a vector of contours
    CV_RETR_EXTERNAL, // 提取外部轮廓
    CV_CHAIN_APPROX_NONE); // all pixels of each contours
//Start to iterate to each contour founded
vector<vector<Point> >::iterator ity = contours_yellow.begin();

//Remove patch that are no inside limits of aspect ratio and area.
tb = 0;
vector<cv::Rect> rects_yellow;
while(ity != contours_yellow.end())
{
    //Create bounding rect of object
    RotatedRect mr = minAreaRect(Mat(*ity));

    //large the rect for more
    if(!verifySizes(mr))
    {
        cv::Mat& roi = dst_yellow(mr.boundingRect());
        roi.setTo(0);
    }
    else
    {
        dst_yellow.push_back(mr.boundingRect());
    }
    ++ity;
}

/// Generate grad_x and grad_y
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;

/// Gradient X
//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x );

/// Gradient Y
//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
convertScaleAbs( grad_y, abs_grad_y );

/// Total Gradient (approximate)
addWeighted( abs_grad_x, SOBEL_X_WEIGHT, abs_grad_y, SOBEL_Y_WEIGHT, 0, grad );

//Laplacian( src_gray, grad_x, ddepth, 3, scale, delta, BORDER_DEFAULT );  
//convertScaleAbs( grad_x, grad ); 
cv::Mat out_blue;
cv::multiply(grad, dst_blue, out_blue);
cv::Mat out_yellow;
cv::multiply(grad, dst_yellow, out_yellow);
if(m_debug)
{ 
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_Sobel_blue" << ".jpg";
    imwrite(ss.str(), out_blue);
    ss << "image/tmp/debug_Sobel_yellow" << ".jpg";
    imwrite(ss.str(), out_yellow);
}

Mat img_threshold_blue;
Mat img_threshold_yellow;
threshold(out_blue, img_threshold_blue, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);
threshold(out_yellow, img_threshold_yellow, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);
//threshold(grad, img_threshold, 75, 255, CV_THRESH_BINARY);

if(m_debug)
{ 
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_threshold_blue" << ".jpg";
    imwrite(ss.str(), img_threshold_blue);
    ss << "image/tmp/debug_threshold_yellow" << ".jpg";
    imwrite(ss.str(), img_threshold_yellow);
}

Mat element = getStructuringElement(MORPH_RECT, Size(m_MorphSizeWidth, m_MorphSizeHeight) );
morphologyEx(img_threshold_blue, img_threshold_blue, MORPH_CLOSE, element);
morphologyEx(img_threshold_yellow, img_threshold_yellow, MORPH_CLOSE, element);

if(m_debug)
{ 
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_morphology_blue" << ".jpg";
    imwrite(ss.str(), img_threshold_blue);
    ss << "image/tmp/debug_morphology_yellow" << ".jpg";
    imwrite(ss.str(), img_threshold_yellow);
}

//Find 轮廓 of possibles plates
contours_blue.clear();
findContours(img_threshold_blue,
    contours_blue, // a vector of contours
    CV_RETR_EXTERNAL, // 提取外部轮廓
    CV_CHAIN_APPROX_NONE); // all pixels of each contours
contours_yellow.clear();
findContours(img_threshold_yellow,
    contours_yellow, // a vector of contours
    CV_RETR_EXTERNAL, // 提取外部轮廓
    CV_CHAIN_APPROX_NONE); // all pixels of each contours

Mat result;
if(m_debug)
{ 
    //// Draw blue contours on a white image
    src.copyTo(result);
    drawContours(result, contours_blue,
        -1, // draw all contours
        Scalar(0,0,255), // in blue
        1); // with a thickness of 1
    drawContours(result, contours_yellow,
        -1, // draw all contours
        Scalar(0, 0, 255), // in blue
        1); // with a thickness of 1
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_Contours" << ".jpg";
    imwrite(ss.str(), result);
}


//Start to iterate to each contour founded
itb = contours_blue.begin();

vector<RotatedRect> rects;
//Remove patch that are no inside limits of aspect ratio and area.
int t = 0;
while (itb != contours_blue.end())
{
    //Create bounding rect of object
    RotatedRect mr = minAreaRect(Mat(*itb));

    //large the rect for more
    if( !verifySizes(mr))
    {
        itb = contours_blue.erase(itb);
    }
    else
    {
        ++itb;
        rects.push_back(mr);
    }
}

ity = contours_yellow.begin();
while(ity != contours_yellow.end())
{
    //Create bounding rect of object
    RotatedRect mr = minAreaRect(Mat(*ity));

    //large the rect for more
    if(!verifySizes(mr))
    {
        ity = contours_yellow.erase(ity);
    }
    else
    {
        ++ity;
        rects.push_back(mr);
    }
}
int k = 1;
for(int i=0; i< rects.size(); i++)
{
    RotatedRect minRect = rects[i];
    if(verifySizes(minRect))
    {   
        // rotated rectangle drawing 
        // Get rotation matrix
        // 旋转这部分代码确实可以将某些倾斜的车牌调整正,
        // 但是它也会误将更多正的车牌搞成倾斜!所以综合考虑,还是不使用这段代码。
        // 2014-08-14,由于新到的一批图片中发现有很多车牌是倾斜的,因此决定再次尝试
        // 这段代码。
        if(m_debug)
        { 
            Point2f rect_points[4]; 
            minRect.points( rect_points );
            for( int j = 0; j < 4; j++ )
                line( result, rect_points[j], rect_points[(j+1)%4], Scalar(0,255,255), 1, 8 );
        }

        float r = (float)minRect.size.width / (float)minRect.size.height;
        float angle = minRect.angle;
        Size rect_size = minRect.size;
        if (r < 1)
        {
            angle = 90 + angle;
            swap(rect_size.width, rect_size.height);
        }
        //如果抓取的方块旋转超过m_angle角度,则不是车牌,放弃处理
        if (angle - m_angle < 0 && angle + m_angle > 0)
        {
            //Create and rotate image
            Mat rotmat = getRotationMatrix2D(minRect.center, angle, 1);
            Mat img_rotated;
            warpAffine(src, img_rotated, rotmat, src.size(), CV_INTER_CUBIC);

            Mat resultMat;
            resultMat = showResultMat(img_rotated, rect_size, minRect.center, k++);

            resultVec.push_back(resultMat);
        }
    }
}

if(m_debug)
{ 
    stringstream ss(stringstream::in | stringstream::out);
    ss << "image/tmp/debug_result" << ".jpg";
    imwrite(ss.str(), result);
}

return 0;

}

error: invalid initialization of non-const reference of type ‘cv::Mat&’ from an rvalue of type ‘cv::Mat’

linux平台编译出现如下错误:

EasyPR/src/core/plate_locate.cpp: In member function ‘int easypr::CPlateLocate::plateLocate(cv::Mat, std::vector<cv::Mat>&, int)’:
EasyPR/src/core/plate_locate.cpp:1282:50: error: invalid initialization of non-const reference of type ‘cv::Mat&’ from an rvalue of type ‘cv::Mat’
             cv::Mat& roi = dst_blue(safeBoundRect);
                                                  ^
EasyPR/src/core/plate_locate.cpp:1336:43: error: invalid initialization of non-const reference of type ‘cv::Mat&’ from an rvalue of type ‘cv::Mat’
    cv::Mat& roi = dst_yellow(safeBoundRect);
                                           ^
CMakeFiles/EasyPR.dir/build.make:215: recipe for target 'CMakeFiles/EasyPR.dir/src/core/plate_locate.cpp.o' failed
make[2]: *** [CMakeFiles/EasyPR.dir/src/core/plate_locate.cpp.o] Error 1
CMakeFiles/Makefile2:60: recipe for target 'CMakeFiles/EasyPR.dir/all' failed
make[1]: *** [CMakeFiles/EasyPR.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2

不能在linux平台上编译

  1. src/include/features.h 与 linux 系统中 features.h 加载顺序有问题
  2. 许多源码文件中包含linux中没有的头文件objbase.h, windows.h, io.h
  3. src/train/ann_train.cpp 中 GetTickCount 函数未声明
  4. src/util/util.cpp 也不能编译成功
  5. 源文件编码建议改为 utf-8 类型

色彩定位光照处理要加强

比如黑E 苏E这种如果原点前两个汉字的地方,光照比较强,色彩判断就会因为字体白色范围比较大造成区域错误

关于最新版的一个错误

不知道有没有被提交过: 在做3.0移植的时候,偶然发现chars_recognise.h中的 CCharsRecognise::charsRecognise的两个参数的重载函数版本声明与实现不符合。
根据声明使用的是cv::String& 实现使用的是std::string&
估计是使用了using语法结果忘记大写了吧?

SVM重新训练

1.1版对SVM进行了重新训练,但从目前情况来看,SVM模型还有改进的空间。一些图片本来是车牌的,被现在的模型识别为非车牌,而一些非车牌的,会被识别为车牌。

这个原因可能在于SVM选取的特征只考虑到了直方图信息,而没有考虑颜色信息;也有数据不全的可能性。

建议改进方式为:1.强化SVM的特征;2.增加更多训练数据。

另外,关于关于Svm训练的数据尺寸可以考虑从目前的136_36改为128_32,Ratio 为 4。保留原始数据,方便回迁,可以测试改进后具体效果。

此改进建议放在 #31 之后进行。

一个小问题

我的使用环境是Windows7+VS2013+OpenCV2.4.10,编译没有出什么麻烦,不过在/bin/release下找到easypr_test.exe和libeasypr.lib后,双击运行easypr_test.exe没有出现什么问题,但是不管是哪条指令输入,都是输入错误,找不到文件或者总计图片0张,不知道是什么问题,还请各位大大给点建议。(为了保险,我把OpenCV的dll基本都放在了该程序目录下)

支持视频识别

最近做了些实验,按照openalpr的实现为EasyPR的demo加入了视频识别的支持,作者是否考虑纳入这个功能?

plate_locate.cpp 运行时错误

OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows) in Mat, file /tmp/opencv-pcqRHK/opencv-2.4.10.1/modules/core/src/matrix.cpp, line 323
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv-pcqRHK/opencv-2.4.10.1/modules/core/src/matrix.cpp:323: error: (-215) 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows in function Mat

使用如下测试图片
test

高分辨率图片的识别

识别太高分辨率图片时会出现问题,将原图片按比例缩小成600X800左右可以正常识别。这个可以在识别前加一个对图片大小的归一化来实现吧

v1.2 centos 编译出错

v1.2 centos 编译出错
环境:
2.6.32-504.1.3.el6.x86_64 #1 SMP Tue Nov 11 17:57:25 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
opencv-2.4.9

[root@v01lab EasyPR-1.2]# make
Scanning dependencies of target EasyPR
[ 5%] Building CXX object CMakeFiles/EasyPR.dir/src/main.cpp.o
In file included from /usr/local/include/opencv2/core/types_c.h:55,
from /usr/local/include/opencv2/core/core.hpp:49,
from /usr/local/include/opencv2/imgproc/imgproc.hpp:50,
from /home/pr/EasyPR-1.2/src/include/prep.h:5,
from /home/pr/EasyPR-1.2/src/include/plate_recognize.h:15,
from /home/pr/EasyPR-1.2/src/main.cpp:1:
/usr/include/assert.h:39:42: error: missing binary operator before token "("
/usr/include/assert.h:105:42: error: missing binary operator before token "("
In file included from /usr/local/include/opencv2/core/types_c.h:57,
from /usr/local/include/opencv2/core/core.hpp:49,
from /usr/local/include/opencv2/imgproc/imgproc.hpp:50,
from /home/pr/EasyPR-1.2/src/include/prep.h:5,
from /home/pr/EasyPR-1.2/src/include/plate_recognize.h:15,
from /home/pr/EasyPR-1.2/src/main.cpp:1:
/usr/include/string.h:37:42: error: missing binary operator before token "("
In file included from /usr/include/math.h:34,
from /usr/local/include/opencv2/core/types_c.h:94,
from /usr/local/include/opencv2/core/core.hpp:49,
from /usr/local/include/opencv2/imgproc/imgproc.hpp:50,
from /home/pr/EasyPR-1.2/src/include/prep.h:5,
from /home/pr/EasyPR-1.2/src/include/plate_recognize.h:15,
from /home/pr/EasyPR-1.2/src/main.cpp:1:
/usr/include/bits/huge_val.h:28:18: error: missing binary operator before token "("
/usr/include/bits/huge_val.h:30:20: error: missing binary operator before token "("
....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.