Skip to content

Commit

Permalink
As a result, the LPRNet algorithm may be used to create embedded solu…
Browse files Browse the repository at this point in the history
…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
zhubenfu authored Jun 29, 2018
1 parent 830d3d9 commit 92421f0
Show file tree
Hide file tree
Showing 78 changed files with 19,742 additions and 0 deletions.
35 changes: 35 additions & 0 deletions ocr_test/ReadMe.txt
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
///////////////////////////////////////////////////////////////////////
164 changes: 164 additions & 0 deletions ocr_test/bktree.cpp
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;
}
49 changes: 49 additions & 0 deletions ocr_test/bktree.h
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);
Loading

0 comments on commit 92421f0

Please sign in to comment.