win10 PaddleOCR c++ cpu部署

  • 一、下载PaddleOCR源代码
  • 二、安装opencv
  • 三、安装paddle预测库
  • 四、cmake编译
  • 五、生成
  • 六、推理
  • 七、附件: `dirent.h`
  • 八、参考链接

一些坑:

  • 2.4版本的paddleocr存在一些问题,于是选择老的版本2.2(没有影响)
  • 存在一些缺失文件和错误的代码

一、下载PaddleOCR源代码

首先下载 PaddleOCR2.2版本

二、安装opencv

opencv链接
比如选择4.5.5版本,下载好后,解压


这样就ok了

三、安装paddle预测库

安装Paddle预测库

选择第一个cpu推理的,并下载

解压出这个样子就行了

四、cmake编译

win10 cmake的安装就不过多解释了。

源代码目录选择cpp_infer
在源代码目录中创建一个build,将build生成的目录也选择好

点击Configure,编译器选择安装的vs对应的版本,比如我的是vs2019, 64位

点击configure(注意,如果报错,记得把build文件夹中内容清空再重新configure)
配置opencv路径和paddle推理库路径

点击configure,成功后点击generate,再点击openProject

五、生成

改为Release版本

选择ALL_BUILD,直接生成的话会出现报错,找不到dirent.h

在任意地方创建一个include文件夹,创建一个dirent.h文件(内容在本文最后,复制进去)

右击项目-》属性,设置当前选定内容

选中ocr_system

项目-》属性

vc++目录-》包含目录 里面添加刚才那个dirent.h所在目录

修改ocr_system中utility.cpp中lstat修改为stat

选择项目ALL_BUILD

点击生成ALL_BUILD

六、推理

打开生成的Release

运行ocr_system.exe,发现报错,缺少paddle_inference.dll
直接将paddle推理库中paddle_inference.dll复制到Release下面

将ppocr/utils/ppocr_keys_v1.txt也复制到Release下面

再在Release下面创建一个img文件夹和inference文件夹

如下图所示


将推理模型放入inference中,下载地址(选择合适的det,cls,rec模型)

config.txt

# model load config
use_gpu 0
gpu_id  0
gpu_mem  4000
cpu_math_library_num_threads  10
use_mkldnn 0# det config
max_side_len  960
det_db_thresh  0.3
det_db_box_thresh  0.5
det_db_unclip_ratio  1.6
use_polygon_score 1
det_model_dir  ./inference/det/# cls config
use_angle_cls 0
cls_model_dir  ./inference/cls/
cls_thresh  0.9# rec config
rec_model_dir  ./inference/rec/
char_list_file   ./ppocr_keys_v1.txt# show the detection results
visualize 0# use_tensorrt
use_tensorrt 0
use_fp16   0

在Release目录下打开命令行
输入 CHCP 65001 来修改显示编码格式

运行ocr_system.exe

七、附件: dirent.h

#pragma once
/** Dirent interface for Microsoft Visual Studio** Copyright (C) 1998-2019 Toni Ronkko* This file is part of dirent.  Dirent may be freely distributed* under the MIT license.  For all details and documentation, see* https://github.com/tronkko/dirent*/
#ifndef DIRENT_H
#define DIRENT_H/* Hide warnings about unreferenced local functions */
#if defined(__clang__)
#   pragma clang diagnostic ignored "-Wunused-function"
#elif defined(_MSC_VER)
#   pragma warning(disable:4505)
#elif defined(__GNUC__)
#   pragma GCC diagnostic ignored "-Wunused-function"
#endif/** Include windows.h without Windows Sockets 1.1 to prevent conflicts with* Windows Sockets 2.0.*/
#ifndef WIN32_LEAN_AND_MEAN
#   define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <ctype.h>/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE/* Indicates that d_namlen field is available in dirent structure */
#define _DIRENT_HAVE_D_NAMLEN/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
#   define FILE_ATTRIBUTE_DEVICE 0x40
#endif/* File type and permission flags for stat(), general mask */
#if !defined(S_IFMT)
#   define S_IFMT _S_IFMT
#endif/* Directory bit */
#if !defined(S_IFDIR)
#   define S_IFDIR _S_IFDIR
#endif/* Character device bit */
#if !defined(S_IFCHR)
#   define S_IFCHR _S_IFCHR
#endif/* Pipe bit */
#if !defined(S_IFFIFO)
#   define S_IFFIFO _S_IFFIFO
#endif/* Regular file bit */
#if !defined(S_IFREG)
#   define S_IFREG _S_IFREG
#endif/* Read permission */
#if !defined(S_IREAD)
#   define S_IREAD _S_IREAD
#endif/* Write permission */
#if !defined(S_IWRITE)
#   define S_IWRITE _S_IWRITE
#endif/* Execute permission */
#if !defined(S_IEXEC)
#   define S_IEXEC _S_IEXEC
#endif/* Pipe */
#if !defined(S_IFIFO)
#   define S_IFIFO _S_IFIFO
#endif/* Block device */
#if !defined(S_IFBLK)
#   define S_IFBLK 0
#endif/* Link */
#if !defined(S_IFLNK)
#   define S_IFLNK 0
#endif/* Socket */
#if !defined(S_IFSOCK)
#   define S_IFSOCK 0
#endif/* Read user permission */
#if !defined(S_IRUSR)
#   define S_IRUSR S_IREAD
#endif/* Write user permission */
#if !defined(S_IWUSR)
#   define S_IWUSR S_IWRITE
#endif/* Execute user permission */
#if !defined(S_IXUSR)
#   define S_IXUSR 0
#endif/* Read group permission */
#if !defined(S_IRGRP)
#   define S_IRGRP 0
#endif/* Write group permission */
#if !defined(S_IWGRP)
#   define S_IWGRP 0
#endif/* Execute group permission */
#if !defined(S_IXGRP)
#   define S_IXGRP 0
#endif/* Read others permission */
#if !defined(S_IROTH)
#   define S_IROTH 0
#endif/* Write others permission */
#if !defined(S_IWOTH)
#   define S_IWOTH 0
#endif/* Execute others permission */
#if !defined(S_IXOTH)
#   define S_IXOTH 0
#endif/* Maximum length of file name */
#if !defined(PATH_MAX)
#   define PATH_MAX MAX_PATH
#endif
#if !defined(FILENAME_MAX)
#   define FILENAME_MAX MAX_PATH
#endif
#if !defined(NAME_MAX)
#   define NAME_MAX FILENAME_MAX
#endif/* File type flags for d_type */
#define DT_UNKNOWN 0
#define DT_REG S_IFREG
#define DT_DIR S_IFDIR
#define DT_FIFO S_IFIFO
#define DT_SOCK S_IFSOCK
#define DT_CHR S_IFCHR
#define DT_BLK S_IFBLK
#define DT_LNK S_IFLNK/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
#define DTTOIF(type) (type)/** File type macros.  Note that block devices, sockets and links cannot be* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are* only defined for compatibility.  These macros should always return false* on Windows.*/
#if !defined(S_ISFIFO)
#   define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISDIR)
#   define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG)
#   define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISLNK)
#   define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK)
#   define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISCHR)
#   define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISBLK)
#   define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#endif/* Return the exact length of the file name without zero terminator */
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)/* Return the maximum size of a file name */
#define _D_ALLOC_NAMLEN(p) ((PATH_MAX)+1)#ifdef __cplusplus
extern "C" {#endif/* Wide-character version */struct _wdirent {/* Always zero */long d_ino;/* File position within stream */long d_off;/* Structure size */unsigned short d_reclen;/* Length of name without \0 */size_t d_namlen;/* File type */int d_type;/* File name */wchar_t d_name[PATH_MAX + 1];};typedef struct _wdirent _wdirent;struct _WDIR {/* Current directory entry */struct _wdirent ent;/* Private file data */WIN32_FIND_DATAW data;/* True if data is valid */int cached;/* Win32 search handle */HANDLE handle;/* Initial directory name */wchar_t* patt;};typedef struct _WDIR _WDIR;/* Multi-byte character version */struct dirent {/* Always zero */long d_ino;/* File position within stream */long d_off;/* Structure size */unsigned short d_reclen;/* Length of name without \0 */size_t d_namlen;/* File type */int d_type;/* File name */char d_name[PATH_MAX + 1];};typedef struct dirent dirent;struct DIR {struct dirent ent;struct _WDIR* wdirp;};typedef struct DIR DIR;/* Dirent functions */static DIR* opendir(const char* dirname);static _WDIR* _wopendir(const wchar_t* dirname);static struct dirent* readdir(DIR* dirp);static struct _wdirent* _wreaddir(_WDIR* dirp);static int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result);static int _wreaddir_r(_WDIR* dirp, struct _wdirent* entry, struct _wdirent** result);static int closedir(DIR* dirp);static int _wclosedir(_WDIR* dirp);static void rewinddir(DIR* dirp);static void _wrewinddir(_WDIR* dirp);static int scandir(const char* dirname, struct dirent*** namelist,int (*filter)(const struct dirent*),int (*compare)(const struct dirent**, const struct dirent**));static int alphasort(const struct dirent** a, const struct dirent** b);static int versionsort(const struct dirent** a, const struct dirent** b);static int strverscmp(const char* a, const char* b);/* For compatibility with Symbian */
#define wdirent _wdirent
#define WDIR _WDIR
#define wopendir _wopendir
#define wreaddir _wreaddir
#define wclosedir _wclosedir
#define wrewinddir _wrewinddir/* Compatibility with older Microsoft compilers and non-Microsoft compilers */
#if !defined(_MSC_VER) || _MSC_VER < 1400
#   define wcstombs_s dirent_wcstombs_s
#   define mbstowcs_s dirent_mbstowcs_s
#endif/* Optimize dirent_set_errno() away on modern Microsoft compilers */
#if defined(_MSC_VER) && _MSC_VER >= 1400
#   define dirent_set_errno _set_errno
#endif/* Internal utility functions */static WIN32_FIND_DATAW* dirent_first(_WDIR* dirp);static WIN32_FIND_DATAW* dirent_next(_WDIR* dirp);#if !defined(_MSC_VER) || _MSC_VER < 1400static int dirent_mbstowcs_s(size_t* pReturnValue, wchar_t* wcstr, size_t sizeInWords,const char* mbstr, size_t count);
#endif#if !defined(_MSC_VER) || _MSC_VER < 1400static int dirent_wcstombs_s(size_t* pReturnValue, char* mbstr, size_t sizeInBytes,const wchar_t* wcstr, size_t count);
#endif#if !defined(_MSC_VER) || _MSC_VER < 1400static void dirent_set_errno(int error);
#endif/** Open directory stream DIRNAME for read and return a pointer to the* internal working area that is used to retrieve individual directory* entries.*/static _WDIR* _wopendir(const wchar_t* dirname){wchar_t* p;/* Must have directory name */if (dirname == NULL || dirname[0] == '\0') {dirent_set_errno(ENOENT);return NULL;}/* Allocate new _WDIR structure */_WDIR* dirp = (_WDIR*)malloc(sizeof(struct _WDIR));if (!dirp)return NULL;/* Reset _WDIR structure */dirp->handle = INVALID_HANDLE_VALUE;dirp->patt = NULL;dirp->cached = 0;/** Compute the length of full path plus zero terminator** Note that on WinRT there's no way to convert relative paths* into absolute paths, so just assume it is an absolute path.*/
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)/* Desktop */DWORD n = GetFullPathNameW(dirname, 0, NULL, NULL);
#else/* WinRT */size_t n = wcslen(dirname);
#endif/* Allocate room for absolute directory name and search pattern */dirp->patt = (wchar_t*)malloc(sizeof(wchar_t) * n + 16);if (dirp->patt == NULL)goto exit_closedir;/** Convert relative directory name to an absolute one.  This* allows rewinddir() to function correctly even when current* working directory is changed between opendir() and rewinddir().** Note that on WinRT there's no way to convert relative paths* into absolute paths, so just assume it is an absolute path.*/
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)/* Desktop */n = GetFullPathNameW(dirname, n, dirp->patt, NULL);if (n <= 0)goto exit_closedir;
#else/* WinRT */wcsncpy_s(dirp->patt, n + 1, dirname, n);
#endif/* Append search pattern \* to the directory name */p = dirp->patt + n;switch (p[-1]) {case '\\':case '/':case ':':/* Directory ends in path separator, e.g. c:\temp\ *//*NOP*/;break;default:/* Directory name doesn't end in path separator */*p++ = '\\';}*p++ = '*';*p = '\0';/* Open directory stream and retrieve the first entry */if (!dirent_first(dirp))goto exit_closedir;/* Success */return dirp;/* Failure */exit_closedir:_wclosedir(dirp);return NULL;}/** Read next directory entry.** Returns pointer to static directory entry which may be overwritten by* subsequent calls to _wreaddir().*/static struct _wdirent* _wreaddir(_WDIR* dirp){/** Read directory entry to buffer.  We can safely ignore the return* value as entry will be set to NULL in case of error.*/struct _wdirent* entry;(void)_wreaddir_r(dirp, &dirp->ent, &entry);/* Return pointer to statically allocated directory entry */return entry;}/** Read next directory entry.** Returns zero on success.  If end of directory stream is reached, then sets* result to NULL and returns zero.*/static int _wreaddir_r(_WDIR* dirp, struct _wdirent* entry, struct _wdirent** result){/* Read next directory entry */WIN32_FIND_DATAW* datap = dirent_next(dirp);if (!datap) {/* Return NULL to indicate end of directory */*result = NULL;return /*OK*/0;}/** Copy file name as wide-character string.  If the file name is too* long to fit in to the destination buffer, then truncate file name* to PATH_MAX characters and zero-terminate the buffer.*/size_t n = 0;while (n < PATH_MAX && datap->cFileName[n] != 0) {entry->d_name[n] = datap->cFileName[n];n++;}entry->d_name[n] = 0;/* Length of file name excluding zero terminator */entry->d_namlen = n;/* File type */DWORD attr = datap->dwFileAttributes;if ((attr & FILE_ATTRIBUTE_DEVICE) != 0)entry->d_type = DT_CHR;else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)entry->d_type = DT_DIR;elseentry->d_type = DT_REG;/* Reset dummy fields */entry->d_ino = 0;entry->d_off = 0;entry->d_reclen = sizeof(struct _wdirent);/* Set result address */*result = entry;return /*OK*/0;}/** Close directory stream opened by opendir() function.  This invalidates the* DIR structure as well as any directory entry read previously by* _wreaddir().*/static int _wclosedir(_WDIR* dirp){if (!dirp) {dirent_set_errno(EBADF);return /*failure*/-1;}/* Release search handle */if (dirp->handle != INVALID_HANDLE_VALUE)FindClose(dirp->handle);/* Release search pattern */free(dirp->patt);/* Release directory structure */free(dirp);return /*success*/0;}/** Rewind directory stream such that _wreaddir() returns the very first* file name again.*/static void _wrewinddir(_WDIR* dirp){if (!dirp)return;/* Release existing search handle */if (dirp->handle != INVALID_HANDLE_VALUE)FindClose(dirp->handle);/* Open new search handle */dirent_first(dirp);}/* Get first directory entry */static WIN32_FIND_DATAW* dirent_first(_WDIR* dirp){if (!dirp)return NULL;/* Open directory and retrieve the first entry */dirp->handle = FindFirstFileExW(dirp->patt, FindExInfoStandard, &dirp->data,FindExSearchNameMatch, NULL, 0);if (dirp->handle == INVALID_HANDLE_VALUE)goto error;/* A directory entry is now waiting in memory */dirp->cached = 1;return &dirp->data;error:/* Failed to open directory: no directory entry in memory */dirp->cached = 0;/* Set error code */DWORD errorcode = GetLastError();switch (errorcode) {case ERROR_ACCESS_DENIED:/* No read access to directory */dirent_set_errno(EACCES);break;case ERROR_DIRECTORY:/* Directory name is invalid */dirent_set_errno(ENOTDIR);break;case ERROR_PATH_NOT_FOUND:default:/* Cannot find the file */dirent_set_errno(ENOENT);}return NULL;}/* Get next directory entry */static WIN32_FIND_DATAW* dirent_next(_WDIR* dirp){/* Is the next directory entry already in cache? */if (dirp->cached) {/* Yes, a valid directory entry found in memory */dirp->cached = 0;return &dirp->data;}/* No directory entry in cache */if (dirp->handle == INVALID_HANDLE_VALUE)return NULL;/* Read the next directory entry from stream */if (FindNextFileW(dirp->handle, &dirp->data) == FALSE)goto exit_close;/* Success */return &dirp->data;/* Failure */exit_close:FindClose(dirp->handle);dirp->handle = INVALID_HANDLE_VALUE;return NULL;}/* Open directory stream using plain old C-string */static DIR* opendir(const char* dirname){/* Must have directory name */if (dirname == NULL || dirname[0] == '\0') {dirent_set_errno(ENOENT);return NULL;}/* Allocate memory for DIR structure */struct DIR* dirp = (DIR*)malloc(sizeof(struct DIR));if (!dirp)return NULL;/* Convert directory name to wide-character string */wchar_t wname[PATH_MAX + 1];size_t n;int error = mbstowcs_s(&n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1);if (error)goto exit_failure;/* Open directory stream using wide-character name */dirp->wdirp = _wopendir(wname);if (!dirp->wdirp)goto exit_failure;/* Success */return dirp;/* Failure */exit_failure:free(dirp);return NULL;}/* Read next directory entry */static struct dirent* readdir(DIR* dirp){/** Read directory entry to buffer.  We can safely ignore the return* value as entry will be set to NULL in case of error.*/struct dirent* entry;(void)readdir_r(dirp, &dirp->ent, &entry);/* Return pointer to statically allocated directory entry */return entry;}/** Read next directory entry into called-allocated buffer.** Returns zero on success.  If the end of directory stream is reached, then* sets result to NULL and returns zero.*/static int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result){/* Read next directory entry */WIN32_FIND_DATAW* datap = dirent_next(dirp->wdirp);if (!datap) {/* No more directory entries */*result = NULL;return /*OK*/0;}/* Attempt to convert file name to multi-byte string */size_t n;int error = wcstombs_s(&n, entry->d_name, PATH_MAX + 1,datap->cFileName, PATH_MAX + 1);/** If the file name cannot be represented by a multi-byte string, then* attempt to use old 8+3 file name.  This allows the program to* access files although file names may seem unfamiliar to the user.** Be ware that the code below cannot come up with a short file name* unless the file system provides one.  At least VirtualBox shared* folders fail to do this.*/if (error && datap->cAlternateFileName[0] != '\0') {error = wcstombs_s(&n, entry->d_name, PATH_MAX + 1,datap->cAlternateFileName, PATH_MAX + 1);}if (!error) {/* Length of file name excluding zero terminator */entry->d_namlen = n - 1;/* File attributes */DWORD attr = datap->dwFileAttributes;if ((attr & FILE_ATTRIBUTE_DEVICE) != 0)entry->d_type = DT_CHR;else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)entry->d_type = DT_DIR;elseentry->d_type = DT_REG;/* Reset dummy fields */entry->d_ino = 0;entry->d_off = 0;entry->d_reclen = sizeof(struct dirent);}else {/** Cannot convert file name to multi-byte string so construct* an erroneous directory entry and return that.  Note that* we cannot return NULL as that would stop the processing* of directory entries completely.*/entry->d_name[0] = '?';entry->d_name[1] = '\0';entry->d_namlen = 1;entry->d_type = DT_UNKNOWN;entry->d_ino = 0;entry->d_off = -1;entry->d_reclen = 0;}/* Return pointer to directory entry */*result = entry;return /*OK*/0;}/* Close directory stream */static int closedir(DIR* dirp){int ok;if (!dirp)goto exit_failure;/* Close wide-character directory stream */ok = _wclosedir(dirp->wdirp);dirp->wdirp = NULL;/* Release multi-byte character version */free(dirp);return ok;exit_failure:/* Invalid directory stream */dirent_set_errno(EBADF);return /*failure*/-1;}/* Rewind directory stream to beginning */static void rewinddir(DIR* dirp){if (!dirp)return;/* Rewind wide-character string directory stream */_wrewinddir(dirp->wdirp);}/* Scan directory for entries */static int scandir(const char* dirname, struct dirent*** namelist,int (*filter)(const struct dirent*),int (*compare)(const struct dirent**, const struct dirent**)){int result;/* Open directory stream */DIR* dir = opendir(dirname);if (!dir) {/* Cannot open directory */return /*Error*/ -1;}/* Read directory entries to memory */struct dirent* tmp = NULL;struct dirent** files = NULL;size_t size = 0;size_t allocated = 0;while (1) {/* Allocate room for a temporary directory entry */if (!tmp) {tmp = (struct dirent*)malloc(sizeof(struct dirent));if (!tmp)goto exit_failure;}/* Read directory entry to temporary area */struct dirent* entry;if (readdir_r(dir, tmp, &entry) != /*OK*/0)goto exit_failure;/* Stop if we already read the last directory entry */if (entry == NULL)goto exit_success;/* Determine whether to include the entry in results */if (filter && !filter(tmp))continue;/* Enlarge pointer table to make room for another pointer */if (size >= allocated) {/* Compute number of entries in the new table */size_t num_entries = size * 2 + 16;/* Allocate new pointer table or enlarge existing */void* p = realloc(files, sizeof(void*) * num_entries);if (!p)goto exit_failure;/* Got the memory */files = (dirent**)p;allocated = num_entries;}/* Store the temporary entry to ptr table */files[size++] = tmp;tmp = NULL;}exit_failure:/* Release allocated file entries */for (size_t i = 0; i < size; i++) {free(files[i]);}/* Release the pointer table */free(files);files = NULL;/* Exit with error code */result = /*error*/ -1;goto exit_status;exit_success:/* Sort directory entries */qsort(files, size, sizeof(void*),(int (*) (const void*, const void*)) compare);/* Pass pointer table to caller */if (namelist)*namelist = files;/* Return the number of directory entries read */result = (int)size;exit_status:/* Release temporary directory entry, if we had one */free(tmp);/* Close directory stream */closedir(dir);return result;}/* Alphabetical sorting */static int alphasort(const struct dirent** a, const struct dirent** b){return strcoll((*a)->d_name, (*b)->d_name);}/* Sort versions */static int versionsort(const struct dirent** a, const struct dirent** b){return strverscmp((*a)->d_name, (*b)->d_name);}/* Compare strings */static int strverscmp(const char* a, const char* b){size_t i = 0;size_t j;/* Find first difference */while (a[i] == b[i]) {if (a[i] == '\0') {/* No difference */return 0;}++i;}/* Count backwards and find the leftmost digit */j = i;while (j > 0 && isdigit(a[j - 1])) {--j;}/* Determine mode of comparison */if (a[j] == '0' || b[j] == '0') {/* Find the next non-zero digit */while (a[j] == '0' && a[j] == b[j]) {j++;}/* String with more digits is smaller, e.g 002 < 01 */if (isdigit(a[j])) {if (!isdigit(b[j])) {return -1;}}else if (isdigit(b[j])) {return 1;}}else if (isdigit(a[j]) && isdigit(b[j])) {/* Numeric comparison */size_t k1 = j;size_t k2 = j;/* Compute number of digits in each string */while (isdigit(a[k1])) {k1++;}while (isdigit(b[k2])) {k2++;}/* Number with more digits is bigger, e.g 999 < 1000 */if (k1 < k2)return -1;else if (k1 > k2)return 1;}/* Alphabetical comparison */return (int)((unsigned char)a[i]) - ((unsigned char)b[i]);}/* Convert multi-byte string to wide character string */
#if !defined(_MSC_VER) || _MSC_VER < 1400static int dirent_mbstowcs_s(size_t* pReturnValue, wchar_t* wcstr,size_t sizeInWords, const char* mbstr, size_t count){/* Older Visual Studio or non-Microsoft compiler */size_t n = mbstowcs(wcstr, mbstr, sizeInWords);if (wcstr && n >= count)return /*error*/ 1;/* Zero-terminate output buffer */if (wcstr && sizeInWords) {if (n >= sizeInWords)n = sizeInWords - 1;wcstr[n] = 0;}/* Length of multi-byte string with zero terminator */if (pReturnValue) {*pReturnValue = n + 1;}/* Success */return 0;}
#endif/* Convert wide-character string to multi-byte string */
#if !defined(_MSC_VER) || _MSC_VER < 1400static int dirent_wcstombs_s(size_t* pReturnValue, char* mbstr,size_t sizeInBytes, const wchar_t* wcstr, size_t count){/* Older Visual Studio or non-Microsoft compiler */size_t n = wcstombs(mbstr, wcstr, sizeInBytes);if (mbstr && n >= count)return /*error*/1;/* Zero-terminate output buffer */if (mbstr && sizeInBytes) {if (n >= sizeInBytes) {n = sizeInBytes - 1;}mbstr[n] = '\0';}/* Length of resulting multi-bytes string WITH zero-terminator */if (pReturnValue) {*pReturnValue = n + 1;}/* Success */return 0;}
#endif/* Set errno variable */
#if !defined(_MSC_VER) || _MSC_VER < 1400static void dirent_set_errno(int error){/* Non-Microsoft compiler or older Microsoft compiler */errno = error;}
#endif#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/

八、参考链接

github PaddleOCR
PaddleDetection部署c++测试图片视频 (win10+vs2017)
paddlepaddle(二) 文字识别 PaddleOCR C++部署
win10 PaddleOCR C++推理部署(CPU部署)

win10 PaddleOCR c++ cpu部署相关推荐

  1. win10 PaddleOCR C++推理部署(CPU部署)

    文章目录 一.开发准备 二.配置编译 一.开发准备 开发环境 win10家庭版. VS2019社区版,opencv3.4,cmake3.21(opencv与cmake配置环境变量) 下载 Paddle ...

  2. linux怎么让cpu不自动降频,Win10 CPU自动降频怎么办?Win10下让CPU不降频设置方法

    有一些用户反馈在Win10系统下CPU会自动降频,也就是自动降低频率以减少资源消耗,如果是平时还没有什么,但是如果你在玩游戏,那么降频给大家带来游戏性能的降低是不能接受的,游戏会变的卡顿下面小编给大家 ...

  3. 【openVINO+paddle】CPU部署新冠肺炎CT图像分类识别与病害分割

    [openVINO+paddle]CPU部署新冠肺炎CT图像分类识别与病害分割 在这个项目中是我在看到一位大佬代码生成器的项目文章时想要尝试开发的一个项目.主要是想要在飞桨上通过Cla与Seg(分类和 ...

  4. Win10怎么看cpu的温度?cpu的温度高低查看方法

    Win10怎么看cpu的温度?在这炎炎夏日,win10电脑经常自动关机重启,首先想到的是否是CPU温度过高引起的!就算有温度计也难以测量cpu温度是否过高,有什么办法可以查看呢?下文中介绍的将对你有帮 ...

  5. TF/pytorch/caffe-CV/NLP/音频-全生态CPU部署实战演示-英特尔openVINO工具套件课程总结(下)

    TF-pytorch-caffe~CV/NLP/音频-全生态CPU部署实战演示-英特尔openVINO工具套件课程总结(下) 在上中两篇中我们充分理解了openvino的基本原理以及其硬件基础,在这篇 ...

  6. Caffe在Win10上的CPU配置以及运行第一个手写体数字识别的caffemodel

    Caffe在Win10上的CPU配置: 操作系统:Windows10 编译环境(必选):Visual Studio 2013 Ultimate版(Visual Studio 2013 Ultimate ...

  7. win10关机后cpu风扇仍一直在转,解决办法

    win10关机后cpu风扇仍一直在转 遇到问题: win10电脑,之前使用一直可以正常关机,3月底的时候不知道什么原因关机后cpu风扇一直在转,显卡灯也不灭了-主机好像还在正常工作中,需要长按主机开机 ...

  8. 【OpenVINO+paddle】一切皆可二次元-CPU部署飞桨AnimeGAN实现所有照片二次元化

    [OpenVINO+paddle]一切皆可二次元-CPU部署飞桨GAN实现所有照片二次元化 在这篇文章中我将小喵咪.小姐姐.钢铁侠图片二次元化,事实上你可以尝试任何一张你感兴趣的图像.在这里你将会使用 ...

  9. win10+tensorflow CPU 部署CTPN环境

    刚弄明白CTPN部署的时候,CTPN作者刚更新了简易代码版本,看介绍是把代码优化了不需要多的配置...感觉好忧伤! 源码地址:https://github.com/eragonruan/text-de ...

最新文章

  1. c语言小程序跑马灯,微信小程序实现跑马灯效果(完整代码)
  2. golang操作文件
  3. 算法提高课-图论-单源最短路的建图方式-AcWing 1126. 最小花费:dijkstra求最长路
  4. 8瓶酒一瓶有毒,用人测试。每次测试结果8小时后才会得出,而你只有8个小时的时间。问最少需要(B)人测试?
  5. java io 视频 下载_Java下载映客主播视频回放到电脑硬盘
  6. 数据库oracle有哪些函数,Oracle函数大全
  7. scanf()正则表达式的使用
  8. Latex定宽单栏长表格(双栏环境)
  9. 2021年基于B/S的高校学生选课管理系统
  10. windows下的Oracle数据库安装教程
  11. android shell卸载应用程序,adb shell删除系统apk
  12. python算法之罗马数字转换阿拉伯数字
  13. 据说Kivy可以将Python程序弄成App来玩,所以 安装Kivy。关于安装Kivy失败后的解决方案过程
  14. 手机号 电话号码 邮箱 验证
  15. HRBUST2343 巴啦啦能量(字符串,技巧)
  16. 【元器件】2.无源晶振
  17. MATLAB散点密度图的画法三
  18. SAT阅读模拟练习题一篇
  19. user-agent:判断扫码的客户端是微信还是支付宝
  20. SRT上传文件下载文件

热门文章

  1. python创意爱情代码-python创意内容
  2. 基于 Netty + Zoookeeper 实现零配置分布式RPC框架
  3. SFML学习-写一个俄罗斯方块
  4. python爬虫实践-爬取京东商品图片
  5. 23岁生日,写给自己
  6. h5和php前景分析,H5发展前景以及优劣势分析
  7. weinre远程调试
  8. 搞钱机会来了 第二届腾讯Light 公益创新挑战赛等你来参赛
  9. 对比百度、必应、谷歌搜索结果,你还会用百度吗?
  10. java 文本的相似度_java – 文本相似度算法