2017-02-01 11 views
0

Ich möchte OpenCV lernen und es für ein Nummernschild-Erkennungssystem in einem meiner Projekte verwenden. Ich habe nach den beschriebenen Schritten gewesen:C++/Opencv Den verwendeten Datentyp verstehen

https://github.com/MicrocontrollersAndMore/OpenCV_3_License_Plate_Recognition_Cpp

Das Problem ist, dass es eine Klasse ist: PossibleChar.h, die ich meinen Kopf nicht scheinen, um zu bekommen, was Datentyp diese verwendet. Ich möchte keine Klasse in meinem Algorithmus verwenden, da dies nicht den Richtlinien entspricht, aber der Algorithmus für das Erkennen von Nummernschildern innerhalb der Szene ist, was ich tun muss. Die Klasse wie folgt aussieht:

// PossibleChar.h 

#ifndef POSSIBLE_CHAR_H 
#define POSSIBLE_CHAR_H 

#include<opencv2/core/core.hpp> 
#include<opencv2/highgui/highgui.hpp> 
#include<opencv2/imgproc/imgproc.hpp> 

class PossibleChar { 
public: 
    // member variables 
    std::vector<cv::Point> contour; 

    cv::Rect boundingRect; 

    int intCenterX; 
    int intCenterY; 

    double dblDiagonalSize; 
    double dblAspectRatio; 

    static bool sortCharsLeftToRight(const PossibleChar &pcLeft, const PossibleChar & pcRight) { 
     return(pcLeft.intCenterX < pcRight.intCenterX); 
    } 


    bool operator == (const PossibleChar& otherPossibleChar) const { 
     if (this->contour == otherPossibleChar.contour) return true; 
     else return false; 
    } 


    bool operator != (const PossibleChar& otherPossibleChar) const { 
     if (this->contour != otherPossibleChar.contour) return true; 
     else return false; 
    } 

    // function prototypes 
    PossibleChar(std::vector<cv::Point> _contour); 

}; 

#endif // POSSIBLE_CHAR_H 

PossibleChar.cpp

PossibleChar::PossibleChar(std::vector<cv::Point> _contour) { 
    contour = _contour; 

    boundingRect = cv::boundingRect(contour); 

    intCenterX = (boundingRect.x + boundingRect.x + boundingRect.width)/2; 
    intCenterY = (boundingRect.y + boundingRect.y + boundingRect.height)/2; 

    dblDiagonalSize = sqrt(pow(boundingRect.width, 2) + pow(boundingRect.height, 2)); 

    dblAspectRatio = (float)boundingRect.width/(float)boundingRect.height; 
} 

Mein erster Gedanke war, dass all diese Klasse tut ist mir cv::Point geben, was gut funktioniert, bis ich auf die Berechnung der Distanzierung zwischen den Charakteren 'verschoben auf das Nummernschild. Dies ist die Funktion in dem Algorithmus gegeben:

double distanceBetweenChars(const PossibleChar &firstChar, const PossibleChar &secondChar) { 
    int intX = abs(firstChar.intCenterX - secondChar.intCenterX); 
    int intY = abs(firstChar.intCenterY - secondChar.intCenterY); 

    return(sqrt(pow(intX, 2) + pow(intY, 2))); 
} 

Wenn ich ein, ohne PossibleChar mit:

double distanceBetweenChars(const cv::Point &firstChar, const cv::Point &secondChar) { 

    cv::Rect boundingRect; 

    boundingRect = cv::boundingRect(firstChar); 

} 

Ich halte den Fehler bekommen:

error: no viable conversion from 'const cv::Point' (aka 'const Point_<int>') to 'const cv::_InputArray' 

Was mich führt daher zu glauben dass diese Klasse nicht nur eine cv::point zurückgibt, sondern auch etwas anderes tut. Irgendwelche Ideen, wie ich das umgehen und die Entfernung berechnen könnte?

Antwort

2

Ein PossibleChar ist kein cv::Point. Es ist eine Klasse, um die Informationen für ein mögliche Zeichen , enthält es let'a nennen blob:

  • std::vector<cv::Point> contour; die Kontur des BLOB
  • cv::Rect boundingRect; der Begrenzungsrahmen (Achse ausgerichtet) der BLOB
  • int intCenterX; int intCenterY; die Koordinaten der Mitte des bounding box
  • double dblDiagonalSize; double dblAspectRatio; Größe und das Seitenverhältnis des bounding box

Wie Sie sehen können, ist es nicht ein Point, sondern enthält die Informationen über die Form und das Ausmaß einen gegebenen Blob, die ein Charakter sein können.

Die Funktion:

double distanceBetweenChars(const PossibleChar &firstChar, const PossibleChar &secondChar) 

gibt den euklidischen Abstand zwischen den Zentren der beiden möglichen Zeichen. Wenn Sie mit cv::Point arbeiten möchten, können Sie tun:

double distanceBetweenChars(const cv::Point &firstChar, const cv::Point &secondChar) { 
    return cv::norm(firstChar - secondChar); 
} 

, die den euklidischen Abstand zwischen den beiden Punkten zurückkehrt, wie zuvor.


Wenn Sie eine PossibleChar als cv::Point beschreiben wollen (was in der Pipeline für Sie nützlich sein kann), können Sie die Koordinaten des Zentrums betrachten können:

cv::Point getPointFromPossibleChar(const PossibleChar& pc) { 
    return cv::Point(pc.intCenterX, pc.intCenterY); 
} 
+0

Wäre es also im Allgemeinen besser, eine Klasse zu verwenden, anstatt es anders zu versuchen? Ich verstehe, dass es wichtige Informationen enthält, aber ich möchte nicht, dass dies weiter in den Algorithmus hineinkommt und ich finde, dass ich diese Informationen irgendwie brauche - Wenn das Sinn macht? – Phorce

+0

Nein, nicht viel Sinn;). Wenn Sie diese Klasse benötigen, verwenden Sie diese Klasse. Wenn Sie es nicht brauchen, benutzen Sie es nicht. Wenn Sie einen 'cv :: Point' benötigen, der einen 'PossibleChar' beschreibt, können Sie wie in meinem Edit – Miki

+0

Danke dafür tun. Wenn Sie jedoch einen Teil des Codes durchsehen, verwendet er: 'boundingRect', um die Fläche, Breite und Höhe zu erhalten. Ist dies immer noch möglich, ohne diese Klasse zu verwenden? Sie scheinen es in ein Bounding Rect zu konvertieren, um diese Werte zu erhalten – Phorce

0

Es scheint mir, dass die Art und Weise, wie sie den Abstand zwischen den beiden Zeichen berechnet haben, ist nicht optimal.

Obwohl ich denke, dass Sie cv::Point mit PossibleChar nicht mischen sollten. Sie sind verschiedene Dinge und PossibleChar hat viel mehr Informationen. Dieser Teil davon ist eine cv::Point, die das Massenzentrum von besagtem PossibleChar beschreibt.

Wenn Sie zwei cv:Point Sie die Entfernung berechnen kann:

cv::Point a(1, 3); cv::Point b(5, 6); double res = cv::norm(a-b);//Euclidian distance


Wenn Sie sich entscheiden, um die Klasse zu verwenden, und ich denke, Sie sollten nur

ändern
double distanceBetweenChars(const PossibleChar &firstChar, const PossibleChar &secondChar) { 
    int intX = abs(firstChar.intCenterX - secondChar.intCenterX); 
    int intY = abs(firstChar.intCenterY - secondChar.intCenterY); 

    return(sqrt(pow(intX, 2) + pow(intY, 2))); 
} 

zu

double distanceBetweenChars(const PossibleChar &firstChar, const PossibleChar &secondChar) { 

     cv::Point a(firstChar.intCenterX,firstChar.intCenterY); 
     cv::Point b(secondChar.intCenterX,secondChar.intCenterY); 
     return(cv::norm(a-b)); 
} 
Verwandte Themen