-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
As a result, the LPRNet algorithm may be used to create embedded solu…
…tions for LPR that feature high level accuracy even on challenging Chinese license plates. LPRNet is a real-time framework for high-quality license plate recognition supporting template and character independent variable-length license plates, performing LPR without character pre-segmentation, trainable end-to-end from scratch for different national license plates.
- Loading branch information
Showing
78 changed files
with
19,742 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
======================================================================== | ||
控制台应用程序:ocr_test 项目概述 | ||
======================================================================== | ||
|
||
应用程序向导已为您创建了此 ocr_test 应用程序。 | ||
|
||
本文件概要介绍组成 ocr_test 应用程序的每个文件的内容。 | ||
|
||
|
||
ocr_test.vcxproj | ||
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 | ||
|
||
ocr_test.vcxproj.filters | ||
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 | ||
|
||
ocr_test.cpp | ||
这是主应用程序源文件。 | ||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
其他标准文件: | ||
|
||
StdAfx.h, StdAfx.cpp | ||
这些文件用于生成名为 ocr_test.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 | ||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
其他注释: | ||
|
||
应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 | ||
|
||
///////////////////////////////////////////////////////////////////////////// | ||
附加库: | ||
libjpeg.lib | ||
libpng.lib | ||
zlib.lib | ||
/////////////////////////////////////////////////////////////////////// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
#include "bktree.h" | ||
|
||
static int write_string(BKTree * bktree, char * string, unsigned char len); | ||
static BKNode * write_new_record(BKTree * bktree, char * string, unsigned char len); | ||
|
||
BKTree * bktree_new(int (* distance)(char *, int, char *, int, int)) { | ||
BKTree * bktree = (BKTree *)malloc(sizeof(BKTree)); | ||
|
||
bktree->tree_size = BKTREE_TREE_SIZE; | ||
bktree->tree = (BKNode *)malloc(bktree->tree_size); | ||
bktree->tree_cursor = bktree->tree; | ||
|
||
bktree->strings_size = BKTREE_STRINGS_SIZE; | ||
bktree->strings = (char*)malloc(bktree->strings_size); | ||
bktree->strings_cursor = bktree->strings; | ||
|
||
bktree->size = 0; | ||
|
||
bktree->distance = distance; | ||
|
||
return bktree; | ||
} | ||
|
||
void bktree_destroy(BKTree * bktree) { | ||
free(bktree->tree); | ||
free(bktree->strings); | ||
free(bktree); | ||
} | ||
|
||
BKNode * bktree_add(BKTree * bktree, char * string, unsigned char len) { | ||
if(len > BKTREE_STRING_MAX || len == 0) | ||
return NULL; | ||
|
||
if(bktree->size == 0) { | ||
return write_new_record(bktree, string, len); | ||
} | ||
|
||
BKNode * node = (BKNode *) bktree->tree; | ||
while(node) { | ||
char * node_str = BKTREE_GET_STRING(bktree, node->string_offset); | ||
int node_str_len = BKTREE_GET_STRING_LEN(bktree, node->string_offset); | ||
|
||
int d = bktree->distance(node_str, node_str_len, string, len, -1); | ||
|
||
if(d == 0) | ||
return BKTREE_OK; | ||
|
||
if(node->next[d] > 0) { | ||
node = bktree->tree + node->next[d]; | ||
} else { | ||
BKNode * new_node = write_new_record(bktree, string, len); | ||
node->next[d] = new_node - bktree->tree; | ||
return new_node; | ||
} | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
// BKResult * bktree_result_new(BKResult * next, BKNode * node, int distance) { | ||
// BKResult * result = (BKResult *)malloc(sizeof(BKResult)); | ||
// result->next = next; | ||
// result->distance = distance; | ||
// result->string_offset = node->string_offset; | ||
// | ||
// return result; | ||
// } | ||
|
||
|
||
void inner_query(BKTree * bktree, BKNode * node, char * string, unsigned char len, int max, std::vector<BKResult>& res) { | ||
|
||
int d = bktree->distance(BKTREE_GET_STRING(bktree, node->string_offset), BKTREE_GET_STRING_LEN(bktree, node->string_offset), string, len, -1); | ||
|
||
int start = d - max < 1 ? 1 : d - max; | ||
int stop = d + max + 1; | ||
if(stop >= BKTREE_STRING_MAX) | ||
stop = BKTREE_STRING_MAX - 1; | ||
|
||
if(d <= max) { | ||
// *result_ptr = bktree_result_new(*result_ptr, node, d); | ||
BKResult r; | ||
r.distance = d; | ||
int len = bktree->strings[node->string_offset]; | ||
char* start = bktree->strings + node->string_offset + 1; | ||
char* end = start + len; | ||
r.str = std::string(start,end); | ||
res.push_back(r); | ||
} | ||
|
||
int i; | ||
for(i = start; i <= stop; i++) { | ||
if(node->next[i] > 0) { | ||
inner_query(bktree, bktree->tree + node->next[i], string, len, max, res); | ||
} | ||
} | ||
} | ||
|
||
std::vector<BKResult> bktree_query(BKTree * bktree, char * string, unsigned char len, int max) { | ||
std::vector<BKResult> res; | ||
inner_query(bktree, bktree->tree, string, len, max, res); | ||
return res; | ||
} | ||
|
||
void bktree_node_print(BKTree * bktree, BKNode * node) { | ||
if(bktree == NULL) { | ||
printf("bktree is null\n"); | ||
return; | ||
} | ||
|
||
if(node == NULL) { | ||
printf("node is null\n"); | ||
return; | ||
} | ||
|
||
printf("String: %s\n", BKTREE_GET_STRING(bktree, node->string_offset)); | ||
printf("Offset: %ld\n", node - bktree->tree); | ||
int i; | ||
for(i = 0; i < BKTREE_STRING_MAX; i++) | ||
printf("%d ", node->next[i]); | ||
|
||
printf("\n"); | ||
} | ||
|
||
static int write_string(BKTree * bktree, char * string, unsigned char len) { | ||
while(bktree->strings_cursor - bktree->strings + len + 2 >= bktree->strings_size) { | ||
int cursor_offset = bktree->strings_cursor - bktree->strings; | ||
|
||
char * old_strings = bktree->strings; | ||
bktree->strings = (char*)malloc(bktree->strings_size * 2); | ||
memcpy(bktree->strings, old_strings, bktree->strings_size); | ||
free(old_strings); | ||
|
||
//printf("old ptr: %p\n", old_strings); | ||
//printf("new ptr: %p\n", bktree->strings); | ||
|
||
bktree->strings_size *= 2; | ||
bktree->strings_cursor = bktree->strings + cursor_offset; | ||
} | ||
|
||
int original_offset = bktree->strings_cursor - bktree->strings; | ||
|
||
*(bktree->strings_cursor) = len; | ||
memcpy(bktree->strings_cursor + 1, string, len); | ||
*(bktree->strings_cursor + len + 1) = '\0'; | ||
bktree->strings_cursor += len + 2; | ||
|
||
return original_offset; | ||
} | ||
|
||
static BKNode * write_new_record(BKTree * bktree, char * string, unsigned char len) { | ||
BKNode * node = bktree->tree_cursor++; | ||
node->string_offset = write_string(bktree, string, len); | ||
|
||
int i; | ||
for(i = 0; i < BKTREE_STRING_MAX; i++) | ||
node->next[i] = 0; | ||
|
||
bktree->size++; | ||
|
||
return node; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#define BKTREE_STRINGS_SIZE 4096 | ||
#define BKTREE_TREE_SIZE 1147483648 | ||
|
||
#define BKTREE_STRING_MAX 24 | ||
|
||
#define BKTREE_OK 0 | ||
#define BKTREE_FAIL 1 | ||
|
||
#define BKTREE_GET_STRING(bktree, string_offset) (bktree->strings + string_offset + 1) | ||
|
||
#define BKTREE_GET_STRING_LEN(bktree, string_offset) (*(bktree->strings + string_offset)) | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
typedef struct { | ||
long string_offset; | ||
int next[BKTREE_STRING_MAX]; | ||
} BKNode; | ||
|
||
typedef struct { | ||
int size; | ||
|
||
BKNode * tree; | ||
BKNode * tree_cursor; | ||
size_t tree_size; | ||
|
||
char * strings; | ||
char * strings_cursor; | ||
size_t strings_size; | ||
|
||
// word1, len(word1), word2, len(word2), max | ||
int (* distance)(char *, int, char *, int, int); | ||
} BKTree; | ||
|
||
struct BKResult_s { | ||
int distance; | ||
std::string str; | ||
//struct BKResult_s * next; | ||
}; | ||
typedef struct BKResult_s BKResult; | ||
|
||
|
||
BKTree * bktree_new(int (* distance)(char *, int, char *, int, int)); | ||
void bktree_destroy(BKTree * bktree); | ||
BKNode * bktree_add(BKTree * bktree, char * string, unsigned char len); | ||
void bktree_node_print(BKTree * bktree, BKNode * node); | ||
|
||
std::vector<BKResult> bktree_query(BKTree * bktree, char * string, unsigned char len, int max); |
Oops, something went wrong.