wuxiuping_branch
www-369 1 year ago
parent d25d52f469
commit 1809748e2f

@ -809,6 +809,8 @@ namespace easypr {
return show;
}
// 对输入图像进行预处理
// 预处理包括创建一个单位矩阵,计算图像的最大维度,对输入图像进行仿射变换,然后将变换后的图像缩放到指定的字符大小
Mat preprocessChar(Mat in, int char_size) {
// Remap image
int h = in.rows; // 获取输入图像的行数
@ -831,6 +833,9 @@ namespace easypr {
return out; // 返回处理后的图像
}
// 接受一个特定的矩形然后计算新的宽度为原宽度的110%
// 新的x坐标为原x坐标减去新宽度的110%如果新的x坐标小于0将其设置为0
// 然后创建一个新的矩形,并返回
Rect GetChineseRect(const Rect rectSpe) {
int height = rectSpe.height; // 获取特定矩形的高度
float newwidth = rectSpe.width * 1.10f; // 计算新的宽度为原宽度的110%
@ -845,6 +850,7 @@ namespace easypr {
return a; // 返回新的矩形
}
// 接受一个矩形,然后计算字符的宽高比,矩形的宽高比……
bool verifyCharSizes(Rect r) {
// Char sizes 45x90
float aspect = 45.0f / 90.0f; // 计算字符的宽高比
@ -866,7 +872,9 @@ namespace easypr {
return false; // 否则返回false
}
// 计算图像宽度和最大宽度的比例,图像高度和最大高度的比例,获取宽度和高度比例中的最大值
// 计算新的宽度和新的高度,将图像缩放到新的大小,设置缩放比例
// 如果图像的大小已经小于或等于最大大小直接返回原图像设置缩放比例为1.0
Mat scaleImage(const Mat &image, const Size &maxSize, double &scale_ratio) {
Mat ret;
@ -890,49 +898,49 @@ namespace easypr {
// Scale back RotatedRect
// 将一个旋转矩形RotatedRect按照给定的缩放比例进行反向缩放返回一个新的旋转矩形
RotatedRect scaleBackRRect(const RotatedRect &rr, const float scale_ratio) {
float width = rr.size.width * scale_ratio;
float height = rr.size.height * scale_ratio;
float x = rr.center.x * scale_ratio;
float y = rr.center.y * scale_ratio;
RotatedRect mserRect(Point2f(x, y), Size2f(width, height), rr.angle);
float width = rr.size.width * scale_ratio; // 根据缩放比例计算原始宽度
float height = rr.size.height * scale_ratio; // 根据缩放比例计算原始高度
float x = rr.center.x * scale_ratio; // 根据缩放比例计算原始中心点的x坐标
float y = rr.center.y * scale_ratio; // 根据缩放比例计算原始中心点的y坐标
RotatedRect mserRect(Point2f(x, y), Size2f(width, height), rr.angle); // 创建一个新的RotatedRect对象使用原始的尺寸和角度
return mserRect;
return mserRect; // 返回新的RotatedRect对象
}
// 验证一个矩形是否符合预设的车牌尺寸包括面积和宽高比如果符合则返回true否则返回false
bool verifyPlateSize(Rect mr) {
float error = 0.6f;
float error = 0.6f; // 设置误差范围
// Spain car plate size: 52x11 aspect 4,7272
// China car plate size: 440mm*140mmaspect 3.142857
// Real car plate size: 136 * 32, aspect 4
float aspect = 3.75;
float aspect = 3.75; // 设置期望的宽高比
// Set a min and max area. All other patchs are discarded
// int min= 1*aspect*1; // minimum area
// int max= 2000*aspect*2000; // maximum area
int min = 34 * 8 * 1; // minimum area
int max = 34 * 8 * 200; // maximum area
int min = 34 * 8 * 1; // 设置最小面积
int max = 34 * 8 * 200; // 设置最大面积
// Get only patchs that match to a respect ratio.
float rmin = aspect - aspect * error;
float rmax = aspect + aspect * error;
float area = float(mr.height * mr.width);
float r = (float) mr.width / (float) mr.height;
if (r < 1) r = (float) mr.height / (float) mr.width;
float rmin = aspect - aspect * error; // 计算最小宽高比
float rmax = aspect + aspect * error; // 计算最大宽高比
// cout << "area:" << area << endl;
// cout << "r:" << r << endl;
float area = float(mr.height * mr.width); // 计算矩形的面积
float r = (float) mr.width / (float) mr.height; // 计算矩形的宽高比
if (r < 1) r = (float) mr.height / (float) mr.width; // 如果宽高比小于1取其倒数
// 判断矩形的面积和宽高比是否在指定的范围内
if ((area < min || area > max) || (r < rmin || r > rmax))
return false;
return false; // 如果不在指定范围内返回false
else
return true;
return true; // 如果在指定范围内返回true
}
// 接收一个RotatedRect对象和一个布尔值showDebug作为参数
// 该函数的主要目的是验证一个旋转矩形(通常是车牌)是否符合预设的尺寸和比例
bool verifyRotatedPlateSizes(RotatedRect mr, bool showDebug) {
float error = 0.65f;
float error = 0.65f; // 定义误差值error以及车牌的宽高比aspect
// Spain car plate size: 52x11 aspect 4,7272
// China car plate size: 440mm*140mmaspect 3.142857
@ -946,6 +954,7 @@ namespace easypr {
//int max = 34 * 8 * 200; // maximum area
// Get only patchs that match to a respect ratio.
// 计算最小和最大的面积min和max以及最小和最大的宽高比aspect_min和aspect_max
float aspect_min = aspect - aspect * error;
float aspect_max = aspect + aspect * error;
@ -954,27 +963,28 @@ namespace easypr {
float min = float(width_min * width_min / aspect_max); // minimum area
float max = float(width_max * width_max / aspect_min); // maximum area
// 获取旋转矩形的宽度、高度、面积、宽高比和角度
float width = mr.size.width;
float height = mr.size.height;
float area = width * height;
float ratio = width / height;
float angle = mr.angle;
if (ratio < 1) {
if (ratio < 1) { // 如果宽高比小于1交换宽度和高度的值并调整角度
swap(width, height);
ratio = width / height;
angle = 90.f + angle;
//std::cout << "angle:" << angle << std::endl;
}
// 定义角度的最小和最大值
float angle_min = -60.f;
float angle_max = 60.f;
//std::cout << "aspect_min:" << aspect_min << std::endl;
//std::cout << "aspect_max:" << aspect_max << std::endl;
// 通过一系列的条件判断,验证旋转矩形是否符合预设的尺寸和比例
// 如果不符合返回false如果符合返回true
if (area < min || area > max) {
if (0 && showDebug) {
std::cout << "area < min || area > max: " << area << std::endl;
@ -1007,27 +1017,30 @@ namespace easypr {
}
//! non-maximum suppression
// 该函数实现了非极大值抑制Non-Maximum SuppressionNMS的功能
// 非极大值抑制是一种常用于目标检测中的技术,用于消除多余的重叠区域
// 该函数主要删除inVec中重叠度过高的CCharacter对象只保留最具代表性的对象
void NMStoCharacter(std::vector<CCharacter> &inVec, double overlap) {
std::sort(inVec.begin(), inVec.end());
// 函数接受两个参数一个是CCharacter对象的向量inVec另一个是重叠阈值overlap
std::sort(inVec.begin(), inVec.end()); // 对inVec进行排序
// 遍历inVec中的每一个CCharacter对象
std::vector<CCharacter>::iterator it = inVec.begin();
for (; it != inVec.end(); ++it) {
CCharacter charSrc = *it;
CCharacter charSrc = *it; // 对于每一个CCharacter对象获取其位置信息rectSrc
//std::cout << "plateScore:" << plateSrc.getPlateScore() << std::endl;
Rect rectSrc = charSrc.getCharacterPos();
// 遍历当前CCharacter对象之后的所有CCharacter对象
std::vector<CCharacter>::iterator itc = it + 1;
for (; itc != inVec.end();) {
CCharacter charComp = *itc;
CCharacter charComp = *itc; // 对于每一个后续的CCharacter对象也获取其位置信息rectComp
Rect rectComp = charComp.getCharacterPos();
//Rect rectInter = rectSrc & rectComp;
//Rect rectUnion = rectSrc | rectComp;
//double r = double(rectInter.area()) / double(rectUnion.area());
// 计算当前CCharacter对象与后续CCharacter对象的交并比Intersection over UnionIoU
float iou = computeIOU(rectSrc, rectComp);
// 如果IoU大于设定的阈值overlap则删除后续的CCharacter对象。否则继续检查下一个CCharacter对象
if (iou > overlap) {
itc = inVec.erase(itc);
} else {

Loading…
Cancel
Save