Initial setup for CLion

This commit is contained in:
2026-03-28 16:54:11 +11:00
parent 239cc02591
commit 7b4134133c
1136 changed files with 811916 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
/*
// Line.h: interface for the C_Line class.
//////////////////////////////////////////////////////////////////////
*/
// Levenshtein.h: interface for the Levenshtein class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(LEVENSHTEIN_H)
#define LEVENSHTEIN_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <cstddef>
/// \brief une classe qui sert <20> calculer la distance entre deux chaines de caracters
/*! \class C_OCROutput
* \brief une classe qui sert <20> calculer la distance entre deux chaines de caracters
**
*/
class Levenshtein
{
public:
//****************************
// Get minimum edit (levenstein) between two strings
//****************************
[[nodiscard]] int Get (const char* a, const char* b);
[[nodiscard]] int Get (const char* a, size_t aLen, const char* b, size_t bLen);
[[nodiscard]] int Get2 (char const *s, char const *t);
[[nodiscard]] int Get2 (char const *s, size_t n, char const *t, size_t dst);
//**************************
// construct/destruct
//**************************
Levenshtein();
virtual ~Levenshtein();
private:
//****************************
// Get minimum of three values
//****************************
int Minimum (int a, int b, int c)
{
int mi = a;
if (b < mi) mi = b;
if (c < mi) mi = c;
return mi;
}
//**************************************************
// Get a pointer to the specified cell of the matrix
//**************************************************
int *GetCellPointer (int *pOrigin, size_t col, size_t row, size_t nCols)
{ return pOrigin + col + (row * (nCols + 1)); }
//*****************************************************
// Get the contents of the specified cell in the matrix
//*****************************************************
int GetAt (int *pOrigin, size_t col, size_t row, size_t nCols)
{
int *pCell = GetCellPointer (pOrigin, col, row, nCols);
return *pCell;
}
//********************************************************
// Fill the specified cell in the matrix with the value x
//********************************************************
void PutAt (int *pOrigin, size_t col, size_t row, size_t nCols, int x)
{
int *pCell = GetCellPointer (pOrigin, col, row, nCols);
*pCell = x;
}
};
#endif // !defined(LEVENSHTEIN_H)

192
ANSLPR/include/Line.h Normal file
View File

@@ -0,0 +1,192 @@
/*
// Line.h: interface for the C_Line class.
//////////////////////////////////////////////////////////////////////
*/
#if !defined(AFX_LINE_H__E3A0AA20_F151_11D5_B96A_CCFB30288840__INCLUDED_)
#define AFX_LINE_H__E3A0AA20_F151_11D5_B96A_CCFB30288840__INCLUDED_
#include <list>
#include <opencv2/opencv.hpp>
#ifdef _DEBUG
#include <cassert>
#endif //_DEBUG
//**************************
// conversion between number types
//**************************
inline float doubleToFloat(const double& value)
{
#ifdef LPR_PRINTF
if ((value > FLT_MAX) || (value < -FLT_MAX))
{
printf("Probleme de depassement lors d'un cast de DOUBLE en FLOAT\n");
}
#endif
return static_cast<float>(value);
}
inline float intToFloat(int value)
{
return static_cast<float>(value);
}
inline float int64ToFloat(const int64_t& value)
{
return static_cast<float>(value);
}
inline int floatToInt(float value)
{
#ifdef LPR_PRINTF
if ((value > INT_MAX) || (value < -INT_MAX))
{
printf("Probleme de depassement lors d'un cast de float en int\n");
}
#endif //LPR_PRINTF
return static_cast<int>(value);
}
/// \brief une classe qui modelise une droite dans un repere, donn<6E>e par son ordonn<6E>e <20> l'origine et sa pente
/*! \class C_OCROutput
* \brief a class that models a line in a frame, given by its intercept and its slope
**
*/
class C_Line
{
public:
//true if the line doesnot have too large slope and not large ordonnee a l'origine
inline bool is_valid() const
{
return (fabsf(a)<FLT_MAX && fabsf(b)<FLT_MAX);
};
//true if the line is (nearly) a vertical one
inline bool is_vertical() const
{
return fabsf(a)>FLT_MAX*0.5f;
};
void reset();
//determine si les deux droites sont paralleles
inline bool is_parallel(const C_Line & line_) const
{
const float MAX_FLT_ERROR=0.000001f;
return (fabsf(a-line_.a)<MAX_FLT_ERROR);
};
//retourne l'image de abscisse par la fonction affi,e definie par la droite
int get_image_entiere(const int abscisse) const;
//retourne l'image de abscisse par la fonction affi,e definie par la droite
float get_image(const int abscisse) const;
//retourne l'image de abscisse par la fonction affi,e definie par la droite
float get_image(const float& abscisse) const;
//retourne le coefficient directeur
inline float get_skew() const{
return a;
};
//retour l'angle de la droite par rapport a l'horizontale
inline float get_skew_angle() const{
return static_cast<float>(atanf(a));
};
//retour l'angle de la droite par rapport a l'horizontale
inline float get_skew_angle(const C_Line & l) const{
return (l.get_skew_angle()- atanf(a));
};
/**
@brief cette fonction donne l'angle de l'inclinaison d'un caractere
cette fonction sert effectueer une correction de l'inclinaison des characteres
cette fonction est utilise apres rotation de l'image de la plaque. Elle doit d'abord dterminer
si les characteres ainsi reforms prsentent un angle de slant.
cette fonction effectuee une correction de l'inclinaison des characteres
this function uses the vanishing point detection algorithm, based
on the concept of clustering line intersections based on the density of line intersections in a local region.
@return the slant angle of the line of characters
@see
*/
inline float get_slant_angle() const{
const float pi_sur_2=1.570796327f;
float slant_angle(atanf(a));
#ifdef _DEBUG
assert(slant_angle > -pi_sur_2 - .1 && slant_angle < pi_sur_2 + .1);
#endif //_DEBUG
if(slant_angle>0) {
// * *******
// * * *
// * * *
// * *******
// * *
// * *
// * *
// * *
//In that case the slant is positive
//correction
// Y'=y
// X'= x-y*cos(teta)
// X'= x-y*sin (ret)
slant_angle-=pi_sur_2;
#ifdef _DEBUG
assert(-slant_angle>-FLT_EPSILON);
#endif //_DEBUG
}
else {
// * *******
// * * *
// * * *
// * *******
// * *
// * *
// * *
// **
//In that case the slant is negative
//il faut que ret <0
slant_angle+=pi_sur_2;
#ifdef _DEBUG
assert(-slant_angle<FLT_EPSILON);
#endif //_DEBUG
}
#ifdef _DEBUG
assert(slant_angle > -pi_sur_2 - .1 && slant_angle < pi_sur_2 + .1);
#endif //_DEBUG
return -slant_angle;
};
inline bool is_x_axis() const{
if(fabsf(a)>FLT_EPSILON) return false;
else return(fabsf(b)<FLT_EPSILON);
};
//l'ordonnee a l'origine
float b;
//le coefficient directeur
float a;
//**************************
// construct/destruct
//**************************
C_Line();
C_Line(const C_Line & line_);
C_Line(const float & a_,const float & b_);
C_Line(const cv::Point2f& A, const cv::Point2f& B);
virtual ~C_Line();
//retourne le pt d'inter de C_Line avec la dte horiz y=ordonnee
float get_abs(const int ordonnee) const;
float get_abs(const float ordonnee) const;
bool is_horizontale() const
{
return(fabsf(a)<FLT_EPSILON);
};
bool is_nearly_the_same(const C_Line & right_op) const;
//returns the distance (positive or negative) of the point from its vertical projection on the line
float difference_y(const cv::Point2f& pt) const;
//retourne la distance du point a sa projection verticale sur la droite
float dist_y(const cv::Point& pt) const;
//returns the distance of the point from its vertical projection on the line
float dist_y(const cv::Point2f& pt) const;
//returns sum of distances of a list of points from their vertical projections on the line
float dist_y(const std::list<cv::Point2f>& points) const;
//returns the distance of the center point of a box from its vertical projection on the line
float dist_y_from_center(const cv::Rect& box) const;
//returns sum of distances of the center points of a list of boxes,from their vertical projections on the line
float dist_y_from_center(const std::list<cv::Rect>& boxes) const;
//returns sum of distances (which can be positive or negative) of the center points of a list of boxes,from their vertical projections on the line
float difference_y_from_center(const std::list<cv::Rect>& boxes) const;
//returns the distance (which can be positive or negative) of the center point of a box from its vertical projection on the line
float difference_y_from_center(const cv::Rect& box) const;
float dist_y(const std::list<cv::Point>& points) const;
//returns average distance of the center points of a list of boxes,from their vertical projections on the line
float error(const std::list<cv::Rect>& boxes) const;
//returns average distance of a list of points from their vertical projections on the line
float error(const std::list<cv::Point2f>& points) const;
protected:
//true if the line is nearly horizontal
bool is_nearly_horiz() const;
};
#endif // !defined(AFX_LINE_H__E3A0AA20_F151_11D5_B96A_CCFB30288840__INCLUDED_)

View File

@@ -0,0 +1,68 @@
/*
// Line.h: interface for the C_Line class.
*/
#if !defined(ONNX_RUNTIME_DETECTOR_H)
#define ONNX_RUNTIME_DETECTOR_H
# pragma once
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>
#include <onnxruntime_c_api.h>
#include <onnxruntime_cxx_api.h>
#ifdef ANSLPR_USE_CUDA
#include <cpu_provider_factory.h>
#endif //ANSLPR_USE_CUDA
#include "utils_alpr_detect.h"
class OnnxDetector {
public:
/***
* @brief constructor
* @param model_path - path of the TorchScript weight file
*/
OnnxDetector(Ort::Env& env, const void* model_data, size_t model_data_length, const Ort::SessionOptions& options);
OnnxDetector(Ort::Env& env, const ORTCHAR_T* model_path, const Ort::SessionOptions& options);
void dump() const;
/***
* @brief inference module
* @param img - input image
* @param conf_threshold - confidence threshold
* @param iou_threshold - IoU threshold for nms
* @return detection result - bounding box, score, class index
*/
std::vector<std::vector<Detection>>
Run(const cv::Mat& img, float conf_threshold, float iou_threshold, bool preserve_aspect_ratio);
/***
* @brief inference module
* @param img - input image
* @param conf_threshold - confidence threshold
* @param iou_threshold - IoU threshold for nms
* @return detection result - bounding box, score, class index
*/
std::list<std::vector<std::vector<Detection>>>
Run(const cv::Mat& img, float iou_threshold);
/***
* @brief
* @return the maximum size of input image (ie width or height of dnn input layer)
*/
int64_t max_image_size() const;
bool is_valid() const {
return (session.GetInputCount() > 0 && session.GetOutputCount() > 0);
}
protected:
//session options are created outside the class. The classifier access to its options through a constant reference
const Ort::SessionOptions & sessionOptions;
Ort::Session session;
//ONNX environment are created outside the class. The classifier access to its envirponment through a constant reference
const Ort::Env& env;
};
//non max suppession algorithm to select boxes
void nms(const std::vector<cv::Rect>& srcRects, std::vector<cv::Rect>& resRects, std::vector<int>& resIndexs, float thresh);
//standard scalar product
template <typename T>
T vectorProduct(const std::vector<T>& v)
{
return std::accumulate(v.begin(), v.end(), 1, std::multiplies<T>());
}
#endif // !defined(ONNX_RUNTIME_DETECTOR_H)

View File

@@ -0,0 +1,106 @@
// StatSommesX_Y_H_dbl.h: interface for the C_SumsRegLineXYHDbl class.
//
#if !defined(AFX_STATSOMMESX_Y_H_DBL_H__EA007980_0205_11D6_B96A_DB3892D34B43__INCLUDED_)
#define AFX_STATSOMMESX_Y_H_DBL_H__EA007980_0205_11D6_B96A_DB3892D34B43__INCLUDED_
#ifndef GITHUB
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Line.h"
/// class used in segmentation algo filtering method
/**cette classe sert a calculer des sommes moyennes et
variances necessaires a l'tabissement d'une droite de regresssion*/
/**cette classe sert a calculer des sommes moyennes et
variances necessaires a l'tabissement d'une droite de regresssion*/
class C_SumsRegLineXYHDbl
{
public:
//! to reset the structure.
/*!
this function reassign to the member their default value.
*/
void clear();
//gets the barycenter of the points cloud
cv::Point2f barycenter(const int nb_elements);
C_Line regression_line(const int nb_elements);
float pente(const int nb_elements) const;
#ifdef _DEBUG
bool debug(const float & somme_x_,
const float & somme_y_,
const float & produit_xy_,
const float & somme_carre_x_) const;
bool debug(const float & somme_x_,
const float & somme_y_,
const float & produit_xy_,
const float & somme_carre_x_,
const int heigth_) const;
#endif //_DEBUG
//**************************
// construct/destruct
//**************************
C_SumsRegLineXYHDbl();
C_SumsRegLineXYHDbl(const int somme_hauteurs_);
virtual ~C_SumsRegLineXYHDbl();
//sum of x coordinates of points cloud
float somme_x;
//sum of y coordinates of points cloud
float somme_y;
//sum of x by y coordinates product of points cloud
float produit_xy;
//sum of squared x coordinates of points cloud
float somme_carre_x;
//sum of heights of bouding boxes (not used in that project)
int somme_hauteurs;
inline void add(const float& x, const float& y, const int hauteur) {
somme_x += x;
somme_y += y;
produit_xy += x*y;
somme_carre_x += x*x;
somme_hauteurs += hauteur;
}
inline void operator+=(const cv::Point2f & Center) {
somme_x += Center.x;
somme_y += Center.y;
produit_xy += Center.x*Center.y;
somme_carre_x += Center.x*Center.x;
}
inline void operator-=(const cv::Point2f & Center) {
somme_x -= Center.x;
somme_y -= Center.y;
produit_xy -= Center.x*Center.y;
somme_carre_x -= Center.x*Center.x;
#ifdef _DEBUG
assert(somme_x >=0 && somme_y >=0 &&
produit_xy >=0 && somme_carre_x>=0);
#endif //_DEBUG
}
inline void substract(const float & x, const float & y, const int hauteur) {
somme_x -= x;
somme_y -= y;
produit_xy -= x*y;
somme_carre_x -=x*x;
#ifdef _DEBUG
assert(somme_x >=0 && somme_y >=0 &&
produit_xy >=0 && somme_carre_x>=0);
#endif //_DEBUG
somme_hauteurs -= hauteur;
}
inline void operator+=(const C_SumsRegLineXYHDbl & stat) {
somme_x += stat.somme_x;
somme_y += stat.somme_y;
produit_xy += stat.produit_xy;
somme_carre_x += stat.somme_carre_x;
somme_hauteurs+=stat.somme_hauteurs;
}
inline void subtract(const cv::Point2f & Center, const int hauteur) {
somme_x -= Center.x;
somme_y -= Center.y;
produit_xy -= Center.x*Center.y;
somme_carre_x-=Center.x*Center.x;
somme_hauteurs-=hauteur;
}
bool operator ==(const C_SumsRegLineXYHDbl & right_op) const;
};
#endif //GITHUB
#endif // !defined(AFX_STATSOMMESX_Y_H_DBL_H__EA007980_0205_11D6_B96A_DB3892D34B43__INCLUDED_)

View File

@@ -0,0 +1,810 @@
/*
// Line.h: interface for the C_Line class.
*/
#if !defined(UTILS_ALPR_ONNX_H)
#define UTILS_ALPR_ONNX_H
#pragma once
#include <opencv2/core.hpp>
#include "Levenshtein.h"
#include "Line.h"
enum Det {
tl_x = 0,
tl_y = 1,
br_x = 2,
br_y = 3,
score = 4,
class_idx = 5
};
struct Detection {
cv::Rect bbox;
float score;
int class_idx;
};
struct LPN_signature {
int nb_caracs_on_first_line;
int nb_caracs_on_second_line;
int nb_caracs_on_third_line;
};
//std::string getTrueLPN(const std::string& filename, const bool& vrai_lpn_after_underscore);
/**
@brief
//rearrange detected bounding boxes from left to right
@param[out] boxes : set of detected boxes
@param[out] confidences : confidences detected boxes
@param[out] classIds : std::list of indeces that indicate the classes of each of the above detected boxes
@return void
@see
*/
void sort_from_left_to_right(std::list<cv::Rect>& boxes, std::list<float>& confidences, std::list<int>& classIds);
/**
@brief
@param r1 : first rectangle
@param r2 : second rectangle
@return the intersection rect of the rectangles
@see
*/
cv::Rect get_inter(const cv::Rect& r1, const cv::Rect& r2);
/**
@brief
//return true if the intersection of the first argument box and the second has an interect area that is at least 90% of the box (which means box is nearly entirely in the second argument)
@param box : box a bounding box
@param rect_im : ROi or second bounding box
@return true if intersection is at least 90% of the box (which means box is nearly entirely in the second argument)
@see
*/
bool is_in_rect_if(const cv::Rect& box, const cv::Rect& rect_im);
/**
@brief
//return true if the intersection of the first argument box and the second has an interect area that is at least 90% of the box (which means box is nearly entirely in the second argument)
@param box : box a bounding box
@param rect_im : ROi or second bounding box
@return true if intersection is at least 90% of the box (which means box is nearly entirely in the second argument)
@see
*/
bool is_in_rect_if(const cv::Rect& box, const cv::Rect& rect_im, const float min_area_ratio);
/**
@brief
///from all heights of the boxes, get the median value
@param[in] boxes : set of detected boxes
@return the median height of the boxes
@see
*/
int get_median_height(const std::list<cv::Rect>& boxes);
/**
@brief
//returns the iou (intersection over union) of two boxes
@param r1 : first rectangle
@param r2 : second rectangle
@return the iou (a float value between 0 and 1)
@see
*/
float iou(const cv::Rect& r1, const cv::Rect& r2);
/**
@brief
//if two boxes have an iou (intersection over union) that is too large, then they cannot represent two adjacent characters of the license plate
//so we discard the one with the lowest confidence rate
@param[out] boxes : set of detected boxes
@param[out] confidences : confidences detected boxes
@param[out] classIds : std::list of indeces that indicate the classes of each of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@return void
@see
*/
void filter_iou2(
std::list<cv::Rect>& boxes,
std::list<float>& confidences,
std::list<int>& classIds, float nmsThreshold = 0.5f);
/** @brief get barycenters of a list of bounding boxes.
* @param[in] boxes : bounding boxes.
* @param[out] les_points : the barycenters of the above boxes.
* @return void
* @see
*/
void get_barycenters(const std::list<cv::Rect>& boxes, std::list<cv::Point2f>& les_points);
/**
@brief
//checks if the bounding boxes are ordered from left to right
@param[in] boxes : set of detected boxes
@return true if the bounding boxes are ordered from left to right
@see
*/
#ifdef _DEBUG
//cette fonction verifie que la liste est triee de gauche a droite
bool debug_left(const std::list<cv::Rect>& boxes);
#endif //_DEBUG
/**
@brief
//examines how boxes are disposed and filter out boxes with a position that are incompatible with the positions of other boxes
@param[in] boxes : set of detected boxes
@param[out] angles_with_horizontal_line : angles determined by segment joining centroids of two consecutives boxes and the horizontal line
@param[out] mean_angles_par_rapport_horiz : mean of the above angles - roughly the tilt of the license plate
@param[out] standard_deviation_consecutives_angles : standard deviation of the above angles (normally a small value, since boxes should be aligned)
@param[out] interdistances : distances between centroids of two consecutives boxes
@param[out] mean_interdistances : mean of the above distances
@param[out] standard_deviation_interdistances : standard deviation of the above distances
@param[out] mean_produit_interdistance_avec_angle : parameter produced by the algorithm
@param[out] standard_deviation_produit_interdistance_avec_angle : parameter produced by the algorithm
@return void
@see
*/
void filtre_grubbs_sides(const std::list<cv::Rect>& boxes, std::list<float>& angles_with_horizontal_line,
float& mean_angles_par_rapport_horiz,
float& standard_deviation_consecutives_angles,
std::list<int>& interdistances,
float& mean_interdistances,
float& standard_deviation_interdistances,
float& mean_produit_interdistance_avec_angle, float& standard_deviation_produit_interdistance_avec_angle);
/**
@brief
//characters on a license plate can be disposed on two lines (bi level) or on just one unique line (single level).
//anycase the ascii characters and there bouding boxes must nbe ordered in the inthe same way of the registration ascii chain.
@param[in] boxes : set of detected boxes
@param[in] l_confidences : confidences of detected boxes
@param[in] l_classIds : classes indeces of detected boxes.
@param[out] l_reordered : std list of the detected boxes when they are rearranged in the order of the registration string
@param[out] l_reordered_confidences : confidences of the above boxes
@param[out] l_reordered_classIds : classes indeces of the above boxes.
@param[out] levels : levels are int that indicates on which line of the license plate the box lies : -1 = upper line, +1 = lower line, 0 if the license plate have just one line
@return void
@see
*/
void is_bi_level_plate(const std::list<cv::Rect>& boxes, const std::list<float>& l_confidences, const std::list<int>& l_classIds,
std::list<cv::Rect>& l_reordered, std::list<float>& l_reordered_confidences, std::list<int>& l_reordered_classIds, std::list<int>& levels);
/**
@brief
//characters on a license plate can be disposed on two lines (bi level) or on just one unique line (single level).
//anycase the ascii characters and there bouding boxes must nbe ordered in the inthe same way of the registration ascii chain.
@param[in] boxes : set of detected boxes
@param[in] l_classIds : classes indeces of detected boxes.
@param[out] l_reordered : std list of the detected boxes when they are rearranged in the order of the registration string
@param[out] l_reordered_classIds : classes indeces of the above boxes.
@param[out] levels : levels are int that indicates on which line of the license plate the box lies : -1 = upper line, +1 = lower line, 0 if the license plate have just one line
@return void
@see
*/
void is_bi_level_plate(const std::list<cv::Rect>& boxes, const std::list<int>& l_classIds,
std::list<cv::Rect>& l_reordered, std::list<int>& l_reordered_classIds, std::list<int>& levels);
//returns true if we can merge two list of characters bounding boxes on a single row
bool merge_is_acceptable(const std::list<cv::Rect>& boxes_on_one_line, const std::list<cv::Rect>& boxes_on_another_line);
/**
@brief
//checks if the character of the lpn is a digit or a letter or something else (by ex examples misread carac or license plate bounding box, ...)
@param[in] input : a character (of the license plate).
@return 1 if the carac is a digit (0...9), 0 if the carac is a letter (A,B,...,Z), -1 else
@see
*/
int is_digit(const char input);
//removes from lists every box which id doenot correspond to a lp character
void filter_out_everything_but_characters(std::list<cv::Rect>& boxes,
std::list<int>& l_classIds);
//removes from lists every box which id doenot correspond to a lp character
void filter_out_everything_but_characters(std::list<cv::Rect>& boxes,
std::list<float>& l_confidences, std::list<int>& l_classIds);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@return the lpn extracted out of detections
@see
*/
std::string get_single_lpn(
const std::vector<cv::Rect>& boxes,
const std::vector<float>& confidences, const std::vector<int>& classIds,
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes,
std::vector<float>& tri_left_confidences, std::vector<int>& tri_left_classIds, float nmsThreshold = 0.5f);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@return the lpn extracted out of detections
@see
*/
std::string get_single_lpn(
const std::vector<cv::Rect>& boxes,
const std::vector<int>& classIds,
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes,
std::vector<int>& tri_left_classIds, float nmsThreshold = 0.5f);
//
/**
@brief : given the index of a bounding box, we can predict if this box is a single character or if it represents the license plate area or if it is the roi of an entire vehicle
@param[in] classId: current box class index
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return single character--> returns 1 or license plate--> returns 2 or vehicle--> returns 3 or negative index--> returns 0 must be an error
@see
*/
int is_this_box_a_character_a_license_plate_or_a_vehicle(const int classId, const int classId_last_country);
//
//classId_last_country : is the class index of the last country in the list of detected classes.
/***
* @brief
@param[in] classId: current box class index
* @param[in] number_of_characters_latin_numberplate : number of characters in a latin alphabet (usually 36 = 26 letters + 10 digits)
* @return //single character--> returns 1
//license plate--> returns 2
//negative index--> returns 0 must be an error
*/
int is_this_box_a_character(const int classId, const int number_of_characters_latin_numberplate);
/**
@brief
//groups detected boxes that correspond to the same vehicle. The separation is based on raw detections of license plates from the dnn
//it can deal with license pates that have two lines of charcaters
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void group_characters_in_the_same_license_plate(
//raw detections
const std::list<cv::Rect>& boxes,
const std::list<float>& confidences, const std::list<int>& classIds,
//detections of same lp are regrouped in a vector
std::list < std::list<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::list<float>>& l_vect_of_confidences_in_a_license_plate, std::list < std::list<int>>& l_vect_of_classIds_in_a_license_plate
, const int classId_last_country
);
/**
@brief
//groups detected boxes that correspond to the same vehicle. The separation is based on raw detections of license plates from the dnn
//it can deal with license pates that have two lines of charcaters
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void group_characters_in_the_same_license_plate(
//raw detections
const std::vector<cv::Rect>& boxes,
const std::vector<float>& confidences, const std::vector<int>& classIds,
//detections of same lp are regrouped in a vector
std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate, std::list < std::vector<int>>& l_vect_of_classIds_in_a_license_plate
, const int classId_last_country
);
/**
@brief
//groups detected boxes that correspond to the same vehicle. The separation is based on raw detections of license plates from the dnn
//it can deal with license pates that have two lines of charcaters
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void group_characters_in_the_same_license_plate(
//raw detections
const std::vector<cv::Rect>& boxes,
const std::vector<float>& confidences, const std::vector<int>& classIds,
//detections of same lp are regrouped in a vector
std::list < std::list<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::list<float>>& l_vect_of_confidences_in_a_license_plate, std::list < std::list<int>>& l_vect_of_classIds_in_a_license_plate
, const int classId_last_country
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters.
//Produces double linked lists : inside list is for characters and outside list is for plates.
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void group_characters_in_the_same_license_plate(
//raw detections
const std::list<cv::Rect>& boxes, const std::list<float>& confidences, const std::list<int>& classIds,
//detections of same lp are regrouped in a vector
std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate, std::list < std::vector<int>>& l_vect_of_classIds_in_a_license_plate, const int classId_last_country
//classId_last_country : is the class index of the last country in the list of detected classes.
);
//1;->ok
//2;->size too small
//4;->second detection is not a vehicle
//6;->detection after first two ones, is not a character
int is_detections_of_a_unique_license_plate(const std::vector<int>& classIds);
//1;->ok
//2;->size too small
//4;->second detection is not a vehicle
//6;->detection after first two ones, is not a character
int is_detections_of_a_unique_license_plate(const std::list<int>& classIds);
//From confidences of detections of all boxes of a plate, we get the average confidence.
float get_average_confidence_of_license_plate(const std::vector<int>& classIds,
const std::vector<float>& confidences);
//From confidences of detections of all boxes of a plate, we get the average confidence.
float get_average_confidence_of_license_plate(const std::list<int>& classIds,
const std::list<float>& confidences);
/**
@brief
For each plate in the image, the detections have been separated. From these, we select the detections of the plates that have have the best detection score.
//Uses double linked lists : inside list is for characters and outside list is for plates.
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] one_lp :set of detected boxes when they rearranged from left to right
@param[out] confidence_one_lp : confidences corresponding detected boxes
@param[out] classIds_one_lp : set of indeces of the above detected boxes
@return void
@see
*/
void get_best_plate(
//detections when they are separated license plates by license plates
const std::list < std::vector<int>>& classIds, const std::list < std::vector<float>>& confidences, const std::list < std::vector<cv::Rect>>& boxes
//output the list of the best (most probable/readable) lp
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp);
/**
@brief
For each plate in the image, the detections have been separated. From these, we select the detections of the plates that have have the best detection score.
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] one_lp :set of detected boxes when they rearranged from left to right
@param[out] confidence_one_lp : confidences corresponding detected boxes
@param[out] classIds_one_lp : set of indeces of the above detected boxes
@return void
@see
*/
void get_best_plate(
//detections when they are separated license plates by license plates
const std::list < std::list<int>>& classIds, const std::list < std::list<float>>& confidences, const std::list < std::list<cv::Rect>>& boxes
//output the list of the best (most probable/readable) lp
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp);//For each plate in the image, the detections have been separated. From these, we select the detections of the plates that have have the best detection score.
/**
@brief
given the boxes+confidences+classIds and given the actual lpn string in the image (ExactLPN), outputs the lpn that is closest to ExactLPN
For each plate in the image, the detections have been separated. From these, we select the detections of the plates that have have the best detection score.
@param[in] ExactLPN : the actual license plate number in the image
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] one_lp :set of detected boxes when they rearranged from left to right
@param[out] confidence_one_lp : confidences corresponding detected boxes
@param[out] classIds_one_lp : set of indeces of the above detected boxes
@return void
@see
*/
void get_best_plate(const std::string& ExactLPN,
//detections when they are separated license plates by license plates
const std::list < std::list<int>>& classIds, const std::list < std::list<float>>& confidences, const std::list < std::list<cv::Rect>>& boxes
//output the list of the best (most probable/readable) lp
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp);
/**
@brief
given the boxes+confidences+classIds and given the actual lpn string in the image (ExactLPN), outputs the lpn that is closest to ExactLPN
For each plate in the image, the detections have been separated. From these, we select the detections of the plates that have have the best detection score.
@param[in] ExactLPN : the actual license plate number in the image
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] one_lp :set of detected boxes when they rearranged from left to right
@param[out] confidence_one_lp : confidences corresponding detected boxes
@param[out] classIds_one_lp : set of indeces of the above detected boxes
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
*/
void get_best_plate(const std::string& ExactLPN,
//detections when they are separated license plates by license plates
const std::list < std::list<int>>& classIds, const std::list < std::list<float>>& confidences, const std::list < std::list<cv::Rect>>& boxes
//output the list of the best (most probable/readable) lp
, std::vector<float>& confidence_one_lp, std::vector < cv::Rect>& one_lp, std::vector<int>& classIds_one_lp);
//this function adds if they dont already exist, a roi for the licene plate (equal to the global rect englobing the boxes) and a blank rect for the vehicle box
void add_lp_and_vehicle(const std::list<cv::Rect>& boxes, const std::list<float>& confidences, const std::list<int>& classIds,
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes, std::vector<float>& tri_left_confidences, std::vector<int>& tri_left_classIds
, const int classId_last_country
);
//
/** @brief
this function adds if they dont already exist, a roi for the licene plate (equal to the global rect englobing the boxes) and a blank rect for the vehicle box
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void add_lp_and_vehicle(const std::list<cv::Rect>& boxes, const std::list<float>& confidences, const std::list<int>& classIds,
std::list<cv::Rect>& tri_left_vect_of_detected_boxes, std::list<float>& tri_left_confidences, std::list<int>& tri_left_classIds
, const int classId_last_country
);
//
/** @brief
this function adds if they dont already exist, a roi for the licene plate (equal to the global rect englobing the boxes) and a blank rect for the vehicle box
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void add_lp_and_vehicle(const std::vector<cv::Rect>& boxes, const std::vector<float>& confidences, const std::vector<int>& classIds,
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes, std::vector<float>& tri_left_confidences, std::vector<int>& tri_left_classIds
, const int classId_last_country
);
//
/** @brief
this function adds if they dont already exist, a roi for the licene plate (equal to the global rect englobing the boxes) and a blank rect for the vehicle box
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void add_lp_and_vehicle(const std::vector<cv::Rect>& boxes, const std::vector<float>& confidences, const std::vector<int>& classIds,
std::list<cv::Rect>& tri_left_vect_of_detected_boxes, std::list<float>& tri_left_confidences, std::list<int>& tri_left_classIds
, const int classId_last_country
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return the lpn extracted out of detections
@see
*/
std::string get_best_lpn(
//raw detections
const std::vector<cv::Rect>& boxes, const std::vector<float>& confidences, const std::vector<int>& classIds,
//characters inside the best lpn that have been chosen from the above double linked list
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes,
std::vector<float>& tri_left_confidences, std::vector<int>& tri_left_classIds, const float nmsThreshold = 0.5f, const int classId_last_country = 96
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences of corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return the lpn extracted out of detections
@see
*/
std::string get_best_lpn(
//raw detections
const std::list<cv::Rect>& boxes, const std::list<float>& confidences, const std::list<int>& classIds,
//characters inside the best lpn that have been chosen from the above double linked list
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes,
std::vector<float>& tri_left_confidences, std::vector<int>& tri_left_classIds, const float nmsThreshold = 0.5f, const int classId_last_country =//95
96
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] one_lp : set of detected boxes
@param[in] confidence_one_lp : confidences of each bb detected by the dnn
@param[in] classIds_one_lp : set of indeces that indicate the classes of each of these detected boxes
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return the lpn extracted out of detections
@see
*/
void get_best_lpn(const std::list<cv::Rect>& one_lp, const std::list<float>& confidence_one_lp, const std::list<int>& classIds_one_lp,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes);
//we know the true license plate number that come from a training image and we want to find the detections boxes to aautomatically annotate the image.
//We also have run the nn that produces detections, the goal of this func is to find the detections that are closest to the true lpn
/**
@brief
given the boxes+confidences+classIds and given the actual lpn string in the image (ExactLPN), outputs the lpn that is closest to ExactLPN
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classes : set of indeces that indicate the classes of each of these detected boxes
@param[in] ExactLPN : the actual license plate number in the image
@param[out] best_boxes :set of detected boxes that compose the lp that has the best confidence
@param[out] best_confidences : confidences corresponding detected boxes
@param[out] best_classes : set of indeces of the above detected boxes
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return edit distance to the actual lpn
*/
int find_nearest_plate_substitutions_allowed(const std::string& ExactLPN,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, const std::list <int>& lp_country_class, const std::list < cv::Rect>& lp_rois, const
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, const std::list < std::list<cv::Rect>>& boxes,
//output = nearest lpn + its class + its bounding box
std::string& best_lpn, int& best_country_class, cv::Rect& best_lpn_roi,
//output = characters in nearest lpn
std::list<float>& best_confidences, std::list<int>& best_classes, std::list<cv::Rect>& best_boxes);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] l_confidences : confidences of detected boxes
@param[in] l_classIds : classes indeces of detected boxes.
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@return the lpn extracted out of detections
@see
*/
std::string get_lpn(
const std::list<cv::Rect>& l_of_detected_boxes,
const std::list<float>& l_confidences, const std::list<int>& l_classIds,
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes,
std::vector<float>& tri_left_confidences, std::vector<int>& tri_left_classIds,
float nmsThreshold = 0.5f
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] l_confidences : confidences of detected boxes
@param[in] l_classIds : classes indeces of detected boxes.
@param[out] tri_left_vect_of_detected_boxes :set of detected boxes when they rearranged from left to right
@param[out] tri_left_confidences : confidences corresponding detected boxes
@param[out] tri_left_classIds : set of indeces of the above detected boxes
@param[in] nmsThreshold A threshold used in non maximum suppression.
@return the lpn extracted out of detections
@see
*/
std::string get_lpn(
const std::list<cv::Rect>& l_of_detected_boxes,
const std::list<int>& l_classIds,
std::vector<cv::Rect>& tri_left_vect_of_detected_boxes,
std::vector<int>& tri_left_classIds,
float nmsThreshold = 0.5f
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] l_classIds : classes indeces of detected boxes.
@return the lpn extracted out of detections
@see
*/
std::string get_lpn(const std::list<int>& l_classIds);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] l_classIds : classes indeces of detected boxes.
@return the lpn extracted out of detections
@see
*/
std::string get_lpn(const std::vector<int>& l_classIds);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now etracts from these boxes the license plate number.
//it can deal with license pates that have two lines of charcaters
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[out] l_vect_of_boxes_in_a_license_plate_tri_left : double list of detected boxes when they rearranged in license plates from left to right
@param[out] l_vect_of_confidences_in_a_license_plate_tri_left : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate_tri_left : double list of corresponding indeces.
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void separate_license_plates_if_necessary_add_blank_vehicles(
//raw detections
const std::vector<cv::Rect>& boxes, const std::vector<float>& confidences, const std::vector<int>& classIds,
//detections when they are separated license plates by license plates
std::list<std::string>& lpns, std::list < std::list<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::list<float>>& l_vect_of_confidences_in_a_license_plate, std::list <std::list<int>>& l_vect_of_classIds_in_a_license_plate,
//double lists (one element list for each lp detected) of detected characters inside a lp
std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate_tri_left,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate_tri_left, std::list <std::vector<int>>& l_vect_of_classIds_in_a_license_plate_tri_left,
const int classId_last_country, //classId_last_country : is the class index of the last country in the list of detected classes.
const float nmsThreshold = 0.5f
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now groups characters in the same license plate and then rearranged from left to right.
//it can deal with license pates that have two lines of charcaters.
//Produces double linked lists : inside list is for characters and outside list is for plates.
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[out] l_vect_of_boxes_in_a_license_plate_tri_left : double list of detected boxes when they rearranged in license plates from left to right
@param[out] l_vect_of_confidences_in_a_license_plate_tri_left : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate_tri_left : double list of corresponding indeces.
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
//groups detected boxes that correspond to the same vehicle. The separation is based on detected license plates by the dnn
void separate_license_plates_if_necessary_add_blank_vehicles(
//raw detections
const std::list<cv::Rect>& boxes, const std::list<float>& confidences, const std::list<int>& classIds,
//detections when they are separated license plates by license plates
std::list<std::string>& lpns, std::list < std::list<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::list<float>>& l_vect_of_confidences_in_a_license_plate, std::list <std::list<int>>& l_vect_of_classIds_in_a_license_plate,
//double lists (one element list for each lp detected) of detected characters inside a lp
std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate_tri_left,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate_tri_left, std::list <std::vector<int>>& l_vect_of_classIds_in_a_license_plate_tri_left,
const int classId_last_country, const float nmsThreshold
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now groups characters in the same license plate and then rearranged from left to right.
//it can deal with license pates that have two lines of charcaters.
//Produces double linked lists : inside list is for characters and outside list is for plates.
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[out] l_vect_of_boxes_in_a_license_plate_tri_left : double list of detected boxes when they rearranged in license plates from left to right
@param[out] l_vect_of_confidences_in_a_license_plate_tri_left : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate_tri_left : double list of corresponding indeces.
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void separate_license_plates_if_necessary_add_blank_vehicles(
//raw detections
const std::vector<cv::Rect>& boxes, const std::vector<float>& confidences, const std::vector<int>& classIds,
//detections when they are separated license plates by license plates
std::list<std::string>& lpns, std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate, std::list <std::vector<int>>& l_vect_of_classIds_in_a_license_plate,
//double lists (one element list for each lp detected) of detected characters inside a lp
std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate_tri_left,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate_tri_left, std::list <std::vector<int>>& l_vect_of_classIds_in_a_license_plate_tri_left,
const int classId_last_country, const float nmsThreshold = 0.5f
);
/**
@brief
//the dnn has detected boxes that represent characters of the license plate, this function now groups characters in the same license plate and then rearranged from left to right.
//it can deal with license pates that have two lines of charcaters.
//Produces double linked lists : inside list is for characters and outside list is for plates.
@param[in] boxes : set of detected boxes
@param[in] confidences : confidences of each bb detected by the dnn
@param[in] classIds : set of indeces that indicate the classes of each of these detected boxes
@param[out] l_vect_of_boxes_in_a_license_plate : double list of detected boxes when they are grouped. A single list contains all the boxes of a single vehicle present in image.
@param[out] l_vect_of_confidences_in_a_license_plate : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate : double list of corresponding indeces.
@param[out] l_vect_of_boxes_in_a_license_plate_tri_left : double list of detected boxes when they rearranged in license plates from left to right
@param[out] l_vect_of_confidences_in_a_license_plate_tri_left : double list of corresponding confidences.
@param[out] l_vect_of_classIds_in_a_license_plate_tri_left : double list of corresponding indeces.
@param[in] nmsThreshold A threshold used in non maximum suppression.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
@return void
@see
*/
void separate_license_plates_if_necessary_add_blank_vehicles(
//raw detections
const std::list<cv::Rect>& boxes, const std::list<float>& confidences, const std::list<int>& classIds,
//detections when they are separated license plates by license plates
std::list<std::string>& lpns, std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate, std::list <std::vector<int>>& l_vect_of_classIds_in_a_license_plate,
//double lists (one element list for each lp detected) of detected characters inside a lp
std::list < std::vector<cv::Rect>>& l_vect_of_boxes_in_a_license_plate_tri_left,
std::list < std::vector<float>>& l_vect_of_confidences_in_a_license_plate_tri_left, std::list <std::vector<int>>& l_vect_of_classIds_in_a_license_plate_tri_left,
const int classId_last_country, const float nmsThreshold = 0.5f
);
//extracts, from a test directory, all images files
//void load_images_filenames(const std::string& dir, std::list<std::string>& image_filenames);
/***
* @brief Padded resize
* @param src - input image
* @param dst - output image
* @param out_size - desired output size
* @return padding information - pad width, pad height and zoom scale
*/
std::vector<float> LetterboxImage(const cv::Mat& src, cv::Mat& dst, const cv::Size& out_size = cv::Size(640, 640));
/***
* @brief Rescale coordinates to original input image
* @param data - detection result after inference and nms
* @param pad_w - width padding
* @param pad_h - height padding
* @param scale - zoom scale
* @param img_shape - original input image shape
*/
void ScaleCoordinates(std::vector<Detection>& data, float pad_w, float pad_h,
float scale, const cv::Size& img_shape);
/***
* @brief Performs Non-Maximum Suppression (NMS) on inference results
* @note For 640x640 image, 640 / 32(max stride) = 20, sum up boxes from each yolo layer with stride (8, 16, 32) and
* 3 scales at each layer, we can get total number of boxes - (20x20 + 40x40 + 80x80) x 3 = 25200
* @param detections - inference results from the network, example [1, 25200, 85], 85 = 4(xywh) + 1(obj conf) + 80(class score)
* @param modelWidth - width of model input 640
* @param modelHeight - height of model input 640
* @param conf_threshold - object confidence(objectness) threshold
* @param iou_threshold - IoU threshold for NMS algorithm
* @return detections with shape: nx7 (batch_index, x1, y1, x2, y2, score, classification)
*/
std::vector<std::vector<Detection>> PostProcessing(
float* output, // output of onnx runtime ->>> 1,25200,85
size_t dimensionsCount,
size_t size, // 1x25200x85=2142000
int dimensions,
float modelWidth, float modelHeight, const cv::Size& img_shape,
float conf_threshold, float iou_threshold);
/***
* @brief Performs Non-Maximum Suppression (NMS) on inference results
* @note For 640x640 image, 640 / 32(max stride) = 20, sum up boxes from each yolo layer with stride (8, 16, 32) and
* 3 scales at each layer, we can get total number of boxes - (20x20 + 40x40 + 80x80) x 3 = 25200
* @param detections - inference results from the network, example [1, 25200, 85], 85 = 4(xywh) + 1(obj conf) + 80(class score)
* @param pad_w - width padding
* @param pad_h - height padding
* @param scale - zoom scale
* @param conf_threshold - object confidence(objectness) threshold
* @param iou_threshold - IoU threshold for NMS algorithm
* @return detections with shape: nx7 (batch_index, x1, y1, x2, y2, score, classification)
*/
std::vector<std::vector<Detection>> PostProcessing(
float* output, // output of onnx runtime ->>> 1,25200,85
size_t dimensionsCount,
size_t size, // 1x25200x85=2142000
int dimensions,
//pad_w is the left (and also right) border width in the square image feeded to the model
float pad_w, float pad_h, float scale, const cv::Size& img_shape,
float conf_threshold, float iou_threshold);
//if two boxes have an iou (intersection over union) that is too large, then they cannot represent two adjacent characters of the license plate
//so we discard the one with the lowest confidence rate
void filter_iou(std::vector<int>& classIds,
std::vector<float>& confidences,
std::vector<cv::Rect>& vect_of_detected_boxes, const float& nmsThreshold = 0.5f);
bool plates_types_differ_with_one_character(const std::string& type1, std::string& lpn
, const std::string& type2);
//this func extract all info from the filenames of the platesmania dataset :
std::string get_plate_sub_type(const std::string& lpn);
//this func extract all info from the filenames of the platesmania dataset :
std::string get_plate_sub_type(const std::list<char>& lpn);
std::vector<std::string> get_plates_types_labels(const std::string& filename);
#endif // !defined(UTILS_ANLR_ONNX_H)

View File

@@ -0,0 +1,40 @@
/*
// Line.h: interface for the C_Line class.
*/
#if !defined(UTILS_IMAGE_FILE_H)
#define UTILS_IMAGE_FILE_H
#pragma once
#include <list>
#include "Levenshtein.h"
#include <opencv2/core.hpp>
/**
@brief
//return the ascii character that corresponds to index class output by the dnn
@param classe : integer index = class identifier, output by the object detection dnn
@return an ascii character
@see
*/
char get_char(const int classe);
/**
@brief
//checks if the characters contained in lpn are compatible with the alphabet
@param lpn: the registration of the vehicle as a string
@return
@see
*/
bool could_be_lpn(const std::string& lpn);
/**
@brief
returns the true license plate number out of a filename
you must place the true license plate number in the image filename this way : number+underscore+license plate number,
for instance filename 0000000001_3065WWA34.jpg will be interpreted as an image with the license plate 3065WWA34 in it.
@param filename: the image filename that contains in it the true registration number
@return the lpn contained in the image filename
@see
*/
//retourne l'index du caractere LPChar
int get_index(const char LPChar);
std::string getTrueLPN(const std::string& filename, const bool& vrai_lpn_after_underscore);
//extracts from a test directory all images files
void load_images_filenames(const std::string& dir, std::list<std::string>& image_filenames);
#endif // !defined(UTILS_IMAGE_FILE_H)

View File

@@ -0,0 +1,373 @@
#if !defined(UTILS_OPEN_CV)
#define UTILS_OPEN_CV
#include "Line.h"
#include <opencv2/opencv.hpp>
//#include <opencv2/text.hpp>
#define cvGetSeqElemLPR( param1, param2, param3) cvGetSeqElem( param1, param2)
/**
@brief
//for each box in the container, check that it is nearly entirely contained in the second argument
@param box : box a bounding box
@param rect_im : ROi or second bounding box
@return true if intersection is at least 90% of the box (which means box is nearly entirely in the second argument)
@see
*/
//for each box in the container, check that it is nearly entirely contained in the second argument
bool is_in_rect_if(const std::list<cv::Rect>& boxes, const cv::Rect& rect_im);
/**
@brief
//for each box in the container, check that it is nearly entirely contained in the second argument
@param box : box a bounding box
@param rect_im : ROi or second bounding box
@return true if intersection is at least 90% of the box (which means box is nearly entirely in the second argument)
@see
*/
//for each box in the container, check that it is nearly entirely contained in the second argument
bool is_in_rect_if(const std::vector<cv::Rect>& boxes, const cv::Rect& rect_im);
/**
@brief
//returns the iou (intersection over union) of two boxes
@param r1 : first rectangle
@param r2 : second rectangle
@return the iou (a float value between 0 and 1)
@see
*/
//float iou(const cv::Rect& r1, const cv::Rect& r2);
std::list<cv::Rect> fiter_out(
const std::vector<cv::Rect>& true_boxes, // the true boxes extracted from pascal voc xml file, as a list
const std::list<cv::Rect>& detected_boxes, // the boxes detected by nn detector, stored in a list of rectagles objects
const std::list<float>& ious,
std::list<float>& out_ious);
std::list<cv::Rect> fiter_out(
const std::list<cv::Rect>& true_boxes, // the true boxes extracted from pascal voc xml file, as a list
const std::list<cv::Rect>& detected_boxes, // the boxes detected by nn detector, stored in a list of rectagles objects
const std::list<float>& ious,
std::list<float>& out_ious);
float iou(
const std::list<cv::Rect>& true_boxes, // the true boxes extracted from pascal voc xml file, as a list
const std::list<cv::Rect>& detected_boxes // the boxes detected by nn detector, stored in a list of rectagles objects
);
float iou(
const std::list<cv::Rect>& boxes, // the true boxes extracted from pascal voc xml file, as a list
const cv::Rect& box // the boxes detected by nn detector, stored in a list of rectagles objects
);
/**
@brief
//rearrange bounding boxes from left to right
cette fonction trie la liste de gauche a droite
@return reordered set of boxes
@see
*/
std::list<cv::Rect> sort_from_left_to_right(const std::list<cv::Rect>& boxes);
/**
@brief
//rearrange bounding boxes from left to right
cette fonction trie la liste de gauche a droite
*@param[in] number_of_characters_latin_numberplate : number of characters in a latin alphabet(usually 36 = 26 letters + 10 digits)
@return reordered set of boxes
@see
*/
std::list<cv::Rect> sort_from_left_to_right(const std::list<cv::Rect>& boxes, const std::list<int>& classes, std::list<int>& sorted_classes,
const int number_of_characters_latin_numberplate
//, const int index_first_mark_model
);
/**
@brief
//rearrange bounding boxes from left to right
cette fonction trie la liste de gauche a droite
@return reordered set of boxes
@see
*/
void sort_from_left_to_right(
std::list<cv::Rect>& boxes, std::list<float>& confidences,
std::list<int>& classIds_);
/**
@brief
cette fonction trie la liste de gauche a droite
//rearrange detected bounding boxes from left to right
@param[out] :std list of detected boxes
@param[out] confidences : confidences of detected boxes
@param[out] classIds : std::list of indeces that indicate the classes of each of the above detected boxes
@return void
@see
*/
void sort_from_left_to_right(
std::list<cv::Rect>& boxes,
std::list<int>& classIds_);
bool is_on_the_left(const cv::Rect& box1, const cv::Rect& box2);
//
/**
@brief cette fonction trie la liste de gauche a droite
//rearrange detected bounding boxes from left to right
@param[out] :std list of detected boxes
@param[out] confidences : confidences of detected boxes
@param[out] classIds : std::list of indeces that indicate the classes of each of the above detected boxes
@return void
@see
*/
void sort_from_left_to_right(
std::list<cv::Rect>& boxes, std::list<float>& confidences);
bool is_in_rect(const std::list<cv::Rect>& boxes, const cv::Rect& rect_im);
bool is_in_rect(const cv::Rect& box, const cv::Rect& rect_im);
bool is_in_rect(const cv::Point& pt, const cv::Rect& rect_im);
//type_of_roi_for_iou==1 large
//type_of_roi_for_iou ==2 right_side
//type_of_roi_for_iou == 3 left side
//type_of_roi_for_iou ==0 no expansion
//float detect(const cv::Mat & frame, const std::list<cv::Rect>& boxes, const cv::Rect& box, const int w, const int type_of_roi_for_iou);
void get_mean_std(const cv::Mat & frame, const cv::Rect& box, float& mean, float& standard_deviation);
bool get_upperand_lower_lines
(const std::list<cv::Rect>& boxes, C_Line& line_sup, C_Line& line_inf);
struct MSERParams
{
MSERParams(int _delta = 5, int _min_area = 60, int _max_area = 14400,
double _max_variation = 0.25, double _min_diversity = .2,
int _max_evolution = 200, double _area_threshold = 1.01,
double _min_margin = 0.003, int _edge_blur_size = 5)
{
delta = _delta;
minArea = _min_area;
maxArea = _max_area;
maxVariation = _max_variation;
minDiversity = _min_diversity;
maxEvolution = _max_evolution;
areaThreshold = _area_threshold;
minMargin = _min_margin;
edgeBlurSize = _edge_blur_size;
pass2Only = false;
}
int delta;
int minArea;
int maxArea;
double maxVariation;
double minDiversity;
bool pass2Only;
int maxEvolution;
double areaThreshold;
double minMargin;
int edgeBlurSize;
};
/*
bool trouve_la_plaque(const cv::Mat& frame
, cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_,
cv::Rect& rect_OpenLP);*/
bool trouve_la_plaque(const cv::Mat& frame, const cv::Rect& global_rect
, cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_,
cv::Rect& rect_OpenLP);
cv::Rect get_global_rect(const cv::Point& bottom_right,
const cv::Point& bottom_left, const cv::Point& top_right
, const cv::Point& top_left);
//cette fonction retourne le rect englobant la collection
//gets the reunion of all the boxes
cv::Rect get_global_rect(const std::list<cv::Rect>& l);
//cette fonction retourne le rect englobant la collection
//gets the reunion of all the boxes
cv::Rect get_global_rect(const std::vector<cv::Rect>& l);
void vector_to_list(
const std::vector<cv::Rect>& boxes,
std::list<cv::Rect>& lboxes);
bool trouve_la_plaque(const cv::Mat& frame, const cv::Rect& global_rect
, cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_,
cv::Rect& rect_OpenLP);
bool trouve_la_plaque(const cv::Mat& frame,
const std::list<int>& classes, const std::list<cv::Rect>& boxes
,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_, cv::Rect& rect_OpenLP);
bool in_quadrilatere(const cv::Point& pt,
const cv::Point& top_left, const cv::Point& top_right, const cv::Point& bottom_right, const cv::Point& bottom_left, const float& signed_distance);
bool in_quadrilatere(const cv::Point& pt, const std::vector<cv::Point >& contours, const float& signed_distance);
bool in_quadrilatere(const cv::Rect& box, const std::vector<cv::Point >& contours, const float& signed_distance);
bool in_quadrilatere(const std::list<cv::Rect>& boxes, const std::vector<cv::Point >& contours, const float& signed_distance);
#include "opencv2/imgproc/imgproc_c.h"
float cosine(const CvPoint& pt1, const CvPoint& pt2, const CvPoint& pt0);
float cosine(const CvPoint* pt1, const CvPoint* pt2, const CvPoint* summit);
bool is_2D(const CvSeq* polygone);
int zappeUnPoint(const CvSeq* polygone, CvMemStorage* storage);
float dist(const CvPoint& pt1, const CvPoint& pt2);
CvPoint moyennepond(const CvPoint& pt1, const CvPoint& pt2, const int a1, const int a2);
CvPoint moyenne(const CvPoint& pt1, const CvPoint& pt2);
CvPoint moyenne4(const CvPoint& pt1, const CvPoint& pt2, const CvPoint& pt3, const CvPoint& pt4);
CvPoint trouveleplusproche(const CvPoint& ref, const CvPoint& pt1,
const CvPoint& pt2, const CvPoint& pt3, const CvPoint& pt4);
CvSeq* sort(const CvSeq* note, CvMemStorage* storage);
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
// renvoie une seuence de 4 points encadrant la plaque
// trouveesur l'image img
// IplImage* img
// CvMemStorage* storage
//peut traiter les images sources couleur ou en niveaux de gris
CvSeq* findSquares4(IplImage* img, CvMemStorage* storage, const int nTresh, //
//le nb de composantes couleurs ex nb_composantes_color=3 pour une image RGB
const int nb_composantes_color, const int dist_min_bord,
const int hauteur_plaque_min, const float& rapport_largeur_sur_hauteur_min);
CvSeq* findSquares4
(IplImage* im_src, const cv::Rect& global_rect, CvMemStorage* storage,
const int nTresh, const int mean_carac
, const int mean_fond, //
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
CvSeq* findSquares4
(IplImage* im_src, CvMemStorage* storage,
const int nTresh, //
//le nb de composantes couleurs ex nb_composantes_color=3 pour une image RGB
const int nb_composantes_color,
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
// renvoie une seuence de 4 points encadrant la plaque
// trouveesur l'image im_src
// IplImage* im_src
// CvMemStorage* storage
//peut traiter les images sources couleur ou en niveaux de gris
CvSeq* findSquares4
(IplImage* imgR, IplImage* imgG, IplImage* imgB, CvMemStorage* storage,
const int nTresh, //
//le nb de composantes couleurs ex nb_composantes_color=3 pour une image RGB
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
CvSeq* findSquares4_multiresolution
(IplImage* im_src, CvMemStorage* storage,
const int nTresh, //
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
CvSeq* findSquares4_multiresolution(
IplImage* im_src, CvMemStorage* storage,
const int nTresh, const int mean_carac
, const int mean_fond, //
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
CvSeq* findSquares4_multiresolution
(
IplImage* im_src, const cv::Rect& global_rect, CvMemStorage* storage,
const int nTresh, const int mean_carac
, const int mean_fond, //
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min
);
CvSeq* findSquares4_multiresolution
(
IplImage* im_src, CvMemStorage* storage,
const int nTresh, //
//le nb de composantes couleurs ex nb_composantes_color=3 pour une image RGB
const int nb_composantes_color,
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min
);
CvSeq* findSquares4_multiresolution
(IplImage* imgR, IplImage* imgG, IplImage* imgB, CvMemStorage* storage,
const int nTresh, //
//le nb de composantes couleurs ex nb_composantes_color=3 pour une image RGB
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
/*
CvSeq* findSquares4
(IplImage* imgR, IplImage* imgG, IplImage* imgB, CvMemStorage* storage,
const int nTresh, //
//le nb de composantes couleurs ex nb_composantes_color=3 pour une image RGB
const int dist_min_bord,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);*/
//peut traiter les images sources couleur ou en niveaux de gris
/*
bool trouve_la_plaque(IplImage* etude, const int nTresh, const int nb_composantes_color,
int resultat[4][2], const int dist_min_bord,
const int hauteur_plaque_min, const float& rapport_largeur_sur_hauteur_min);*/
///////////////////////////////////////////////////////////////////////////////////////////
// retourne le nb de points en commun entre deux images
float percentage_match(IplImage* img1, IplImage* img2);
bool quadrilatere_is_convex(const cv::Point& pt0, const cv::Point& pt1, const cv::Point& pt2, const cv::Point& pt3);
//must be convex quadrilatere
bool width_is_larger(const cv::Point& pt0, const cv::Point& pt1, const cv::Point& pt2, const cv::Point& pt3);
//must be convex quadrilatere
bool get_corners(const cv::Point& pt0, const cv::Point& pt1, const cv::Point& pt2, const cv::Point& pt3,
cv::Point& top_left, cv::Point& top_right, cv::Point& bottom_right, cv::Point& bottom_left);
//must be convex quadrilatere
bool get_corners(const IplImage* im, const CvPoint& pt0, const CvPoint& pt1, const CvPoint& pt2, const CvPoint& pt3,
cv::Point& top_left, cv::Point& top_right, cv::Point& bottom_right, cv::Point& bottom_left);
/*
bool trouve_la_plaque(IplImage* etude, int nTresh,
cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_, cv::Rect& rect_OpenLP,
const int dist_min_bord
,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
//peut traiter les images sources couleur ou en niveaux de gris
bool trouve_la_plaque(IplImage* etude, int nTresh
, const int mean_carac
, const int mean_fond,
cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_, cv::Rect& rect_OpenLP,
const int dist_min_bord
,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
*/
//peut traiter les images sources couleur ou en niveaux de gris
bool trouve_la_plaque(IplImage* etude, const cv::Rect& global_rect, int nTresh
, const int mean_carac
, const int mean_fond,
cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_, cv::Rect& rect_OpenLP,
const int dist_min_bord
,
const int hauteur_plaque_min,
const float& rapport_largeur_sur_hauteur_min);
bool trouve_la_plaque(const cv::Mat& frame, const cv::Rect& global_rect
, cv::Point& p0, cv::Point& p1, cv::Point& p2, cv::Point& p3,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_,
cv::Rect& rect_OpenLP);
bool trouve_la_plaque(const cv::Mat& frame,
const std::list<int>& classes, const std::list<cv::Rect>& boxes
,
cv::Point& top_left_,
cv::Point& top_right_,
cv::Point& bottom_right_,
cv::Point& bottom_left_, cv::Rect& rect_OpenLP);
std::string get_plate_type(
const std::list<cv::Rect>& vect_of_detected_boxes,
const std::list<int>& classIds, const int number_of_characters_latin_numberplate
);
std::string get_plate_type(
const std::vector<cv::Rect>& vect_of_detected_boxes,
const std::vector<int>& classIds, const int number_of_characters_latin_numberplate
);
#endif // !defined UTILS_OPEN_CV
#pragma once

View File

@@ -0,0 +1,532 @@
/*
// Line.h: interface for the C_Line class.
*/
#if !defined(YOLOV5_ALPR_ONNX_DETECTOR)
#define YOLOV5_ALPR_ONNX_DETECTOR
#include "ONNX_detector.h"
class Plates_types_classifier : public OnnxDetector
{
public:
//**************************
// construct/destruct
//**************************
Plates_types_classifier(Ort::Env& env, const void* model_data, size_t model_data_length, const Ort::SessionOptions& options
, const std::vector<std::string>& labels_);
Plates_types_classifier(Ort::Env& env, const ORTCHAR_T* model_path, const Ort::SessionOptions& options
, const std::vector<std::string>& labels_);
Plates_types_classifier(Ort::Env& env, const ORTCHAR_T* model_path, const Ort::SessionOptions& options
, const std::string& labels_filename);
Plates_types_classifier(Ort::Env& env, const void* model_data, size_t model_data_length, const Ort::SessionOptions& options
, const std::string& labels_filename);
OnnxDetector& get_ref() {
return *this;
};
const Plates_types_classifier& get_const_ref() {
return *this;
};
virtual ~Plates_types_classifier();
std::string GetPlatesType(const cv::Mat& img, float& uncalibrated_confidence);
void get_best_plate(const cv::Mat& frame,
//detections when they are separated license plates by license plates
const std::list < std::list<int>>& classIds, const std::list < std::list<float>>& confidences, const std::list < std::list<cv::Rect>>& boxes
//output the list of the best (most probable/readable) lp
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp);
//nov 21 update this func with plates_types_classifier classifier
//uses double linked lists : inside list is for characters and outside list is for plates.
//For each plate in the image, the detections have been separated. From these, we select the detections of the plates that have have the best detection score.
void get_best_plate(const cv::Mat& frame,
//detections when they are separated license plates by license plates
const std::list < std::vector<int>>& classIds, const std::list < std::vector<float>>& confidences, const std::list < std::vector<cv::Rect>>& boxes
//output the list of the best (most probable/readable) lp
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp);
private:
int GetPlatesClasse(const cv::Mat& img, float& uncalibrated_confidence);
protected:
std::vector<std::string> labels;
};
class Yolov5_alpr_onxx_detector : public OnnxDetector
{
public:
//**************************
// construct/destruct
//**************************
Yolov5_alpr_onxx_detector(Ort::Env& env, const void* model_data, size_t model_data_length, const Ort::SessionOptions& options);
Yolov5_alpr_onxx_detector(Ort::Env& env, const ORTCHAR_T* model_path, const Ort::SessionOptions& options);
OnnxDetector& get_ref() {
return *this;
};
const OnnxDetector& get_const_ref() {
return *this;
};
virtual ~Yolov5_alpr_onxx_detector();
/** @brief Given the @p input frame, create input blob, run net then, from result detections, assembies license plates present in the input image.
* uses double linked lists : inside list is for characters and outside list is for plates.
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, std::list<std::vector<int>>& classIds,
std::list < std::vector<float>>& confidences, std::list < std::vector<cv::Rect>>& boxes,
float nmsThreshold);
/** @brief Given the @p input frame, create input blob, run net and return result detections.
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
void raw_detections_with_different_confidences(const cv::Mat& frame, std::list<std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes,
float nmsThreshold);
/** @brief Given the @p input frame, create input blob, run net then, from result detections, assembies license plates present in the input image.
* uses double linked lists : inside list is for characters and outside list is for plates.
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
* @param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, std::list<std::vector<int>>& classIds,
std::list < std::vector<float>>& confidences, std::list < std::vector<cv::Rect>>& boxes, std::list <std::list<std::string>>& lpns,
float nmsThreshold, const int classId_last_country//classId_last_country : is the class index of the last country in the list of detected classes.
);
/** @brief Given the @p input frame, create input blob, run net then, from result detections, assembies license plates present in the input image.
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
* @param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, std::list<std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes,
std::list <std::list<std::string>>& lpns,
float nmsThreshold, const int classId_last_country//classId_last_country : is the class index of the last country in the list of detected classes.
);
/** @brief Given the @p input frame, create input blob, run net and return result detections.
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[in] confThreshold A threshold used to filter boxes by confidences.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
void detect(const cv::Mat& frame, std::vector<int>& classIds, std::vector<float>& confidences, std::vector<cv::Rect>& boxes,
const float confThreshold = 0.7f, float nmsThreshold = 0.5f);
// Given the @p input frame, create input blob, run net and return result detections.
//this func can manage list of boxes of characters that dont have an englobing lp box (gloabal rect)
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//Produces double linked lists : inside list is for characters and outside list is for plates.
/** @brief
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
* @param[in] confThreshold A threshold used to filter boxes by confidences.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
//and remaining elements are characters
void detect_and_add_lp_and_vehicle_if_necessary(const cv::Mat& frame, std::list<std::vector<int>>& classIds,
std::list < std::vector<float>>& confidences, std::list < std::vector<cv::Rect>>& boxes,
std::list<std::string>& lpns,
const int classId_last_country,
const float confThreshold = 0.7f, float nmsThreshold = 0.5f);
// Given the @p input frame, create input blob, run net and return result detections.
//this func can manage list of boxes of characters that dont have an englobing lp box (gloabal rect)
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
/** @brief
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
* @param[in] confThreshold A threshold used to filter boxes by confidences.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
void detect_and_add_lp_and_vehicle_if_necessary(const cv::Mat& frame, std::list<std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes,
std::list<std::string>& lpns,
const int classId_last_country,
const float confThreshold = 0.7f, float nmsThreshold = 0.5f);
std::list<cv::Rect> TwoStage_LPR(Yolov5_alpr_onxx_detector& parking_detector, const cv::Mat& frame, std::string& lpn);
std::list<cv::Rect> TwoStageLPR(Yolov5_alpr_onxx_detector& parking_detector, Plates_types_classifier& plates_types_classifier, const cv::Mat& frame, std::string& lpn);
/** @brief Given the @p input frame, create input blob, run net and return result detections.
* @param[in] frame : input image.
* @param[out] classIds : classes indeces in resulting detected bounding boxes.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[in] confThreshold A threshold used to filter boxes by confidences.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
void detect(const cv::Mat& frame, std::list<int>& classIds, std::list<float>& confidences, std::list<cv::Rect>& boxes,
const float confThreshold = 0.7f, float nmsThreshold = 0.5f);
/** @brief process an image file.
* @param[in] image_filename : filename of the he input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
* @param[in] show_image : boolean if true the image will be displayed in a window with license plate in image banner
* @param[in] time_delay : time delay in ms after which the image is destroyed
@param[in] classId_last_country : is the class index of the last country in the list of detected classes.
* @return void
* @see
*/
void detect(const std::string& image_filename, std::list<std::string>& lpns, const int classId_last_country
//, const bool show_image=false, const int time_delay=0
);
/** @brief from image dir, extract license plate numbers.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] dir : directory path that contains all images files that will be proceeded.
* @return void
* @see
*/
float two_stage_lpr(const std::string& dir);
/** @brief from image dir, extract license plate numbers.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] dir : directory path that contains all images files that will be proceeded.
* @return void
* @see
*/
float two_stage_lpr(Yolov5_alpr_onxx_detector& parking_detector, const std::string& dir);
/** @brief from image dir, extract license plate numbers.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] frame : input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
@param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(Yolov5_alpr_onxx_detector& parking_detector, const cv::Mat& frame,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
/** @brief from image dir, extract license plate numbers.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] frame : input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
@param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(Yolov5_alpr_onxx_detector& parking_detector, Plates_types_classifier& plates_types_classifier, const cv::Mat& frame,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
/** @brief from image frame, extract license plate number.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] image_filename : filename of the he input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
@param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(Yolov5_alpr_onxx_detector& parking_detector, const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
/** @brief from image filename, extract license plate number.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] image_filename : filename of the he input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
* @param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
/** @brief Given the @p input frame, create input blob, run net and return result detections.
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters.
//Produces double linked lists : inside list is for characters and outside list is for plates.
* @param[in] frame : The input image.
* @param[out] classIds Class indexes in result detection.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[out] one_lp :set of detected boxes when they rearranged from left to right
* @param[out] confidence_one_lp : confidences corresponding detected boxes
* @param[out] classIds_one_lp : set of indeces of the above detected boxes
* @param[in] classId_last_country : is the class index of the last country in the list of detected classes.
* @param[in] confThreshold A threshold used to filter boxes by confidences.
* @param[in] nmsThreshold A threshold used in non maximum suppression.
*/
void detect_lpn_and_add_lp_and_vehicle_if_necessary(const cv::Mat& frame, std::list < std::vector<int>>& classIds,
std::list < std::vector<float>>& confidences, std::list < std::vector<cv::Rect>>& boxes
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp,
const int classId_last_country,
//const C_OCROutputs& availableAlpha,
const float confThreshold = 0.7f, float nmsThreshold = 0.5f);
/** @brief Given the @p input frame, create input blob, run net then, from result detections, assembies license plates present in the input image.
//it selects just one lpn although all lps have been detected and stored in double linked lists, then from these lists, selects the one that is the best
//(with best confidences of its characters and with greateast size)
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
* @param[in] frame : The input image.
* @param[out] classIds Class indexes in result detection.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[out] one_lp :set of detected boxes when they rearranged from left to right
* @param[out] confidence_one_lp : confidences corresponding detected boxes
* @param[out] classIds_one_lp : set of indeces of the above detected boxes
* @param[in] nmsThreshold A threshold used in non maximum suppression.
* @param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, std::list < std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp,
const int classId_last_country,
//const C_OCROutputs& availableAlpha,
float nmsThreshold);
//
//Given the @p input frame, create input blob, run net and return result detections.
//it selects just one lpn although all lps are detected in double linked lists
////this func can manage list of boxes of characters that dont have an englobing lp box (gloabal rect)
////output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
////and remaining elements are characters
//Produces double linked lists : inside list is for characters and outside list is for plates.
//
void detect_lpn_and_add_lp_and_vehicle_if_necessary(const cv::Mat& frame, Plates_types_classifier& plates_types_classifier, std::list < std::vector<int>>& classIds,
std::list < std::vector<float>>& confidences, std::list < std::vector<cv::Rect>>& boxes
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp,
const int classId_last_country,//classId_last_country : is the class index of the last country in the list of detected classes.We remember that ascii(latin) characters come fist(36 classes) then come the license plates countries(another 60 classses) then come a long list of vehicles classes
//const C_OCROutputs & availableAlpha,
const float confThreshold, float nmsThreshold);
//Given the @p input frame, create input blob, run net then, from result detections, assembly license plates present in the input image.
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, Plates_types_classifier& plates_types_classifier, std::list < std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp,
const int classId_last_country,//classId_last_country : is the class index of the last country in the list of detected classes.We remember that ascii(latin) characters come fist(36 classes) then come the license plates countries(another 60 classses) then come a long list of vehicles classes
//const C_OCROutputs & availableAlpha,
float nmsThreshold);
/** @brief Given the @p input frame, create input blob, run net then, from result detections, assembies license plates present in the input image.
//it selects just one lpn although all lps have been detected and stored in double linked lists, then from these lists, selects the one that is the best
//(with best confidences of its characters and with greateast size)
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
* @param[in] frame : The input image.
@param[in] ExactLPN : the actual license plate number in the image
* @param[out] classIds Class indexes in result detection.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[out] one_lp :set of detected boxes when they rearranged from left to right
* @param[out] confidence_one_lp : confidences corresponding detected boxes
* @param[out] classIds_one_lp : set of indeces of the above detected boxes
* @param[in] nmsThreshold A threshold used in non maximum suppression.
* @param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, const std::string& ExactLPN, std::list < std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes
, std::list<float>& confidence_one_lp, std::list < cv::Rect>& one_lp, std::list<int>& classIds_one_lp,
const int classId_last_country,
//const C_OCROutputs& availableAlpha,
float nmsThreshold);
/** @brief Given the @p input frame, create input blob, run net then, from result detections, assembies license plates present in the input image.
//it selects just one lpn although all lps have been detected and stored in double linked lists, then from these lists, selects the one that is the best
//(with best confidences of its characters and with greateast size)
//output lists look like : first box = license plate (either a detected box either the global rect englobing characters boxes, second element = vehicle (either a detected vehicle either (0,0,0,0)
//and remaining elements are characters
* @param[in] frame : The input image.
* @param[in] ExactLPN : the actual license plate number in the image
* @param[out] classIds Class indexes in result detection.
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : set of detected bounding boxes.
* @param[out] one_lp :set of detected boxes when they rearranged from left to right
* @param[out] confidence_one_lp : confidences corresponding detected boxes
* @param[out] classIds_one_lp : set of indeces of the above detected boxes
* @param[in] nmsThreshold A threshold used in non maximum suppression.
* @param[in] classId_last_country : is the class index of the last country in the list of detected classes.
*/
void detect_with_different_confidences_then_separate_plates(const cv::Mat& frame, const std::string& ExactLPN, std::list < std::list<int>>& classIds,
std::list < std::list<float>>& confidences, std::list < std::list<cv::Rect>>& boxes
, std::vector<float>& confidence_one_lp, std::vector < cv::Rect>& one_lp, std::vector<int>& classIds_one_lp,
const int classId_last_country,
//const C_OCROutputs& availableAlpha,
float nmsThreshold);
};
/** @brief from image filename, extract license plate number.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] freeflow_detectors : yolo detectors that detect license plates in images that are not focused and that can contain multiple license plates.
* @param[in] parking_detectors : yolo detectors that read characters in a localized and focused license plate in image
* @param[in] image_filename : filename of the he input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
* @param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& freeflow_detectors, const std::list<Yolov5_alpr_onxx_detector*>& parking_detectors,
const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
//two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& freeflow_detectors, const std::list<Yolov5_alpr_onxx_detector*>& parking_detectors
, Plates_types_classifier& plates_types_classifier,
const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
//two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& freeflow_detectors, const std::list<Yolov5_alpr_onxx_detector*>& parking_detectors
, Plates_types_classifier& plates_types_classifier,
const cv::Mat& frame,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
//make a bounding box greater (just to be sure we don t miss something in detections)
void get_larger_roi(cv::Rect& lpn_roi, const int width, const int height
);
//make a bounding box greater (just to be sure we don t miss something in detections)
void get_larger_roi(cv::Rect& lpn_roi, const int width, const int height, const float& scale_x, const float& scale_y
);
Yolov5_alpr_onxx_detector* get_detector_with_smallest_size_bigger_than_image(const std::list<Yolov5_alpr_onxx_detector*>& detectors, const int max_size);
Yolov5_alpr_onxx_detector* get_detector_with_smallest_size_bigger_than_image(const std::list<Yolov5_alpr_onxx_detector*>& detectors, const int width, const int height);
/** @brief from image frame, extract license plate number.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] freeflow_detectors : yolo detectors that detect license plates in images that are not focused and that can contain multiple license plates.
* @param[in] parking_detectors : yolo detectors that read characters in a localized and focused license plate in image
* @param[in] frame : input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
* @param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& freeflow_detectors, const std::list<Yolov5_alpr_onxx_detector*>& parking_detectors,
const cv::Mat& frame,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
/** @brief from image filename, extract license plate number.
this performs a two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
Difference between this func and detect func is that
two_stage_lpr first focus on license plate detection and secondly on its characters. This is supposed to get best results.
* @param[in] image_filename : filename of the he input image.
* @param[out] lpn : the license plate number found in the image by the dnn detector.
* @param[in] classes : set of indeces that indicate the classes of each of these detected boxes
* @param[out] confidences : detection confidences of detected bounding boxes
* @param[out] boxes : A set of bounding boxes.
* @param[out] chosen_lp_classIds : set of indeces that indicate the classes of each box of the license plate that has been chosen by engine (ie the one with the highest confidence)
* @param[out] chosen_lp_confidences : detection confidences of the corresponding boxes
* @param[out] chosen_lp_boxes : A set of bounding boxes of the license plate that has been chosen by engine (ie the one with the highest confidence)
*/
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& detectors, const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
//two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& freeflow_detectors, const std::list<Yolov5_alpr_onxx_detector*>& parking_detectors
, Plates_types_classifier& plates_types_classifier,
const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
void two_stage_lpr(Yolov5_alpr_onxx_detector& freeflow_detector, Yolov5_alpr_onxx_detector& parking_detector
, Plates_types_classifier& plates_types_classifier,
const std::string& image_filename,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
//two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
void two_stage_lpr(const std::list<Yolov5_alpr_onxx_detector*>& freeflow_detectors, const std::list<Yolov5_alpr_onxx_detector*>& parking_detectors
, Plates_types_classifier& plates_types_classifier,
const cv::Mat& frame,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
//two stage lpn detection : first a global nn detects lpn of a free flow vehicle, then a second nn focuses and reads the lpn of the previously detected lpn.
void two_stage_lpr(Yolov5_alpr_onxx_detector& freeflow_detector, Yolov5_alpr_onxx_detector& parking_detector
, Plates_types_classifier& plates_types_classifier,
const cv::Mat& frame,
//double linked lists to separate lps
std::list < std::list<float>>& confidences, std::list < std::list<int>>& classes, std::list < std::list<cv::Rect>>& boxes,
//all lps in the image given by lpn (as string), lp country ppronenace (as class index) and lp area in the image (cv::Rect)
std::list <std::string>& lpns, std::list <int>& lp_country_class, std::list < cv::Rect>& lp_rois,
//detection inside the chosen lp
std::list<int>& chosen_lp_classIds, std::list<float>& chosen_lp_confidences, std::list<cv::Rect>& chosen_lp_boxes
);
#endif // !defined(YOLOV5_ALPR_ONNX_DETECTOR)