C++ OpenCv:车牌识别

C++ OpenCv:车牌识别,c++,opencv,image-processing,C++,Opencv,Image Processing,我一直致力于基于github存储库的车牌识别 但我需要检测小字符。但我想不出来。 我想我需要改变尺寸检查,但我想不出来 bool checkIfPossibleChar(PossibleChar&PossibleChar){ //此函数是一个“第一次通过”,对轮廓进行粗略检查,以确定它是否可能是字符, //请注意,我们还没有(尚未)将该字符与其他字符进行比较以查找组 如果(可能的话)car.boundingRect.area()>MIN\u PIXEL\u area&& possibleCh

我一直致力于基于github存储库的车牌识别

但我需要检测小字符。但我想不出来。 我想我需要改变尺寸检查,但我想不出来

bool checkIfPossibleChar(PossibleChar&PossibleChar){
//此函数是一个“第一次通过”,对轮廓进行粗略检查,以确定它是否可能是字符,
//请注意,我们还没有(尚未)将该字符与其他字符进行比较以查找组
如果(可能的话)car.boundingRect.area()>MIN\u PIXEL\u area&&
possibleChar.boundingRect.width>MIN_PIXEL_width&&possibleChar.boundingRect.height>MIN_PIXEL_height&&
最小纵横比

double dbldistancebetwenchars=两条道路之间的距离(可能的道路、可能的道路);
double DblangleBeween Chars=两个圆柱之间的夹角(可能为Echar,可能为Machingchar);
double dblChangeInArea=(double)abs(possibleMatchingChar.boundingRect.area()-possibleChar.boundingRect.area())/(double)possibleChar.boundingRect.area();
double dblChangeInWidth=(double)abs(possibleMatchingChar.boundingRect.width-possibleChar.boundingRect.width)/(double)possibleChar.boundingRect.width;
double dblChangeInHeight=(double)abs(possibleMatchingChar.boundingRect.height-possibleChar.boundingRect.height)/(double)possibleChar.boundingRect.height;
//检查字符是否匹配
如果(两列之间的DBLDistance<(可能的ECHAR.dblDiagonalSize*最大诊断大小的倍数)&&
DbLangle字符之间<字符之间的最大角度&&
dblChangeInArea<区域内的最大变化&&
dblChangeInWidth<最大变化宽度&&
DBL变化高度<最大变化高度){
vectorOfMatchingChars.push_back(可能是MatchingChar);//如果字符匹配,则将当前字符添加到匹配字符的向量中
}

非常感谢。

您应该首先调试以查看两个a、a在哪些情况下失败

  • 最小像素区域、最小像素宽度和最小像素高度可能无法容纳小尺寸A

  • 在您提供的第二个代码段中,将if语句的语法从
    if(条件1&&cond2&&…
    语法
    if(condition1){if(codition2){….}
    。这将告诉您这些条件在哪里失效

  • 最后,在第二个代码片段中,检查边界矩形是否为字符的许多条件在很大程度上取决于过去看到的字符类型。因为在您的情况下,字符AA在大小、距离和方向(垂直方向)上也不同。因此,最好为AA重新初始化,而不是使用以前的字符,或者应该添加更多的条件来验证字符。[例如,如果高度和宽度都减小]

  • 一旦您知道步骤2中哪些条件失败以及为什么失败,对步骤3进行相关更改应该很简单


    编辑: 我进一步查看了repo,并检查了函数findVectorOfVectorsOfMatchingChars和findVectorOfMatchingChars

    分析findVectorOfMatchingChars函数:此函数获取一个可能的char,并检查此char是否与任何可能的Chars向量匹配(当所有if条件通过时)。如果存在匹配项,则将所有匹配项存储在一起并返回结果

    分析匹配字符的向量FindVectorOfVectorOfMatchingChars函数:此函数从可能字符的向量中选择任何可能的字符,并使用findVectorOfMatchingChars查找所有匹配的字符。如果找到了一个好的匹配项,该函数将使用(vectorOfPossibleChars-matchedPossibleChars)调用自己

    现在,问题来了

    假设每个可能的Char是图G的一个顶点,当它们满足findVectorOfMatchingChars函数中定义的条件时,两个可能的Char之间有一条边

    现在,假设我们有一个图,其中a,B,C,D,X可能是一个顶点,X离a,B,C,D足够近,但是a,B,C,D彼此距离足够远,不能被认为是紧密匹配

    现在,让我们将FindVectorOfVectorOfMatchingChars应用于这个可能的Chars向量

    选项1:如果我们先选择X,我们会找到A、B、C、D作为其匹配的可能值,从而得到所有可能值

    选项2:如果我们选择第一个,我们会发现X可能与A匹配,但与B、C、D不匹配。因此,我们将A、X从可能字符的向量中删除,并在B、C、D上重新应用匹配字符的向量FindVectorOfVectorOfMatchingChars。现在,由于B、C、D之间没有匹配,我们最终会发现B、C或D不匹配

    纠正措施:

  • 创建一个graph类并将其中的每个可能的char注册为顶点。使用findVectorOfMatchingChars中定义的条件在每对顶点之间生成边
  • 您可能需要自定义条件以合并其他顶点和2 A顶点之间的边。为此,您应该使用更多的数据集,以便您创建或更改阈值的条件不是太通用,无法容纳非车牌字符
  • 在图中查找连接树以查找所有字符。这可能会增加所有可能的原因。为了避免这种情况,可以使用加权边限制加法

  • 谢谢你的回答!!但你对AA重新初始化是什么意思?请你帮我说得具体一点好吗。非常感谢。@user1814210:请看我编辑的答案。请放弃我给你的重新初始化的想法。对不起。更新后的答案显示了代码错误,并建议您可以走哪条路。请记住,您对条件所做的任何更改都不应基于单个图像。您应该使用一个足够大的数据库,并通过查看整个数据库的准确性的提高来测试您的更改。非常感谢。虽然我现在还不能
    bool checkIfPossibleChar(PossibleChar &possibleChar) {
            // this function is a 'first pass' that does a rough check on a contour to see if it could be a char,
            // note that we are not (yet) comparing the char to other chars to look for a group
    if (possibleChar.boundingRect.area() > MIN_PIXEL_AREA &&
    possibleChar.boundingRect.width > MIN_PIXEL_WIDTH && possibleChar.boundingRect.height > MIN_PIXEL_HEIGHT &&
        MIN_ASPECT_RATIO < possibleChar.dblAspectRatio && possibleChar.dblAspectRatio < MAX_ASPECT_RATIO) {
        return(true);
    } else {
        return(false);
    }}
    
        double dblDistanceBetweenChars = distanceBetweenChars(possibleChar,     possibleMatchingChar);
        double dblAngleBetweenChars = angleBetweenChars(possibleChar, possibleMatchingChar);
        double dblChangeInArea = (double)abs(possibleMatchingChar.boundingRect.area() - possibleChar.boundingRect.area()) / (double)possibleChar.boundingRect.area();
        double dblChangeInWidth = (double)abs(possibleMatchingChar.boundingRect.width - possibleChar.boundingRect.width) / (double)possibleChar.boundingRect.width;
        double dblChangeInHeight = (double)abs(possibleMatchingChar.boundingRect.height - possibleChar.boundingRect.height) / (double)possibleChar.boundingRect.height;
    
                // check if chars match
        if (dblDistanceBetweenChars < (possibleChar.dblDiagonalSize * MAX_DIAG_SIZE_MULTIPLE_AWAY) &&
            dblAngleBetweenChars < MAX_ANGLE_BETWEEN_CHARS &&
            dblChangeInArea < MAX_CHANGE_IN_AREA &&
            dblChangeInWidth < MAX_CHANGE_IN_WIDTH &&
            dblChangeInHeight < MAX_CHANGE_IN_HEIGHT) {
            vectorOfMatchingChars.push_back(possibleMatchingChar);      // if the chars are a match, add the current char to vector of matching chars
        }