一.引言

文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技术的发展,文字识别技术已经成为信息管理、自动化办公和智能系统的关键组成部分。

二.简介

为了易于集成和使用,我们将文字识别OCR封装为DLL(动态链接库)。这种封装方式不仅保留了算法的性能优势,还提供了跨平台和跨语言的兼容性,目前支持编程语言如下:

  • C++
  • Python
  • 易语言
  • 1.C++头文件

    
    #ifndef _SN_SDK_H__
    #define _SN_SDK_H__
    
    
    
    #include <windows.h>
    
    
    enum SN_TRACK_MOVE_TYPE
    {
    	TRACK_MOVE_TYPE_NORMAL=0,		// 用于常规轨迹 - 普通游戏鼠标轨迹
    	TRACK_MOVE_TYPE_SLIDER,			// 用于滑块轨迹,比常规常规轨迹密度更大 - 滑块验证轨迹
    };
    
    enum SN_TRACK_POINT_TYPE
    {
    	TRACK_POINT_TYPE_NORMAL=0,		// 默认绝对坐标
    	TRACK_POINT_TYPE_RELATIVE,		// 相对坐标
    };
    
    
    //返回参数
    typedef struct SN_RESULT {
    
    	int code;			//错误码,如果为 0 表示成功,否则表示错误号
    	char message[4096];	//错误信息,如果为 "OK" 表示成功,否则返回错误信息
    
    }SN_RESULT;
    
    
    //坐标参数
    typedef struct SN_POINT
    {
    	int x;				//屏幕坐标,左上角(0,0),右下角(1920,1080 - 以实际屏幕为准)
    	int y;				//屏幕坐标,左上角(0,0),右下角(1920,1080 - 以实际屏幕为准)
    
    }SN_POINT;
    
    //轨迹参数
    typedef struct SN_POINT_PARAMS
    {
    	struct SN_POINT point;//屏幕坐标,左上角(0,0),右下角(1920,1080 - 以实际屏幕为准)
    	int delayTime;		  //延时时间(单位:毫秒),仅供参考
    
    }SN_POINT_PARAMS;
    
    
    /*创建句柄
    *
    * 参数:
    *	[in] szKey:		卡密(购买卡密:https://shop.4yuns.com/links/7C9F16B7)
    * 	[in] pOnnxFilePath:设置 onnx 模型文件路径,如果设置为 NULL,默认和 DLL文件同级目录
    * 	[out] pResult:		返回错误信息,参数pResult.code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    * 返回值:成功返回句柄,失败返回NULL
    *
    */
    HANDLE WINAPI apiSNCreateHandle(char* szKey, char* pOnnxFilePath, SN_RESULT* pResult);
    
    
    /*设置鼠标移动轨迹,默认为 0 表示普通轨迹 ; 1 表示滑块验证时移动轨迹(获得的轨迹点数比普通轨迹点数更多)
    *
    * 参数:
    *	[in] handle:		句柄(通过调用apiSNCreateHandle得到)
    *  	[in] density:		轨迹密度调节 ,必须大于或者等于 1,默认 1
    *								例如:默认1,原本为100个点,density 为 5,会得到20个点;density 为 2,会得到50个点 )
    *  	[in] type:			轨迹类型(0代表绝对普通轨迹,1代表滑块轨迹,具体参考enum SN_TRACK_MOVE_TYPE)
    *
    * 返回值:返回参数SN_RESULT.code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    */
    int WINAPI apiSNSetTrackParams(HANDLE handle, int density=1, int type=0);
    
    
    /*获取鼠标移动轨迹
    *
    * 参数:
    *	[in] handle:		句柄(通过调用apiSNCreateHandle得到)
    * 	[in] startPoint:	开始坐标,左上角(0,0),右下角(1920,1080 - 以实际屏幕为准)
    * 	[in] endPoint:		结束坐标,左上角(0,0),右下角(1920,1080 - 以实际屏幕为准)
    *  	[in] type:			轨迹坐标类型(0代表绝对坐标,1代表相对坐标,具体参考enum SN_TRACK_POINT_TYPE)
    * 	[out] points:		轨迹数组,如果数组中元素 point 出现(10000,10000),表示鼠标轨迹结束
    *
    * 返回值:返回参数SN_RESULT.code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    */
    int WINAPI apiSNMouseMove(HANDLE handle, SN_POINT *startPoint, SN_POINT *endPoint, int type, SN_POINT_PARAMS* points);
    
    
    /*获取版本号
    *
    * 参数:
    *	[in] handle:		句柄(通过调用apiSNCreateHandle得到)
    * 	[out] szVersion:	版本号
    *
    * 返回值:返回参数SN_RESULT.code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    */
    int WINAPI apiSNGetVersion(HANDLE handle, char* szVersion);
    
    
    /*获取OCR文字识别卡密到期时间
    *
    * 参数:
    *	[in]  handle:		句柄(通过调用apiSNCreateOCRHandle得到)
    * 	[out] pResult:		返回错误信息,参数pResult->code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    * 返回值:返回卡密到期时间,失败返回NULL,错误信息请查看参数 pResult->message
    *
    */
    char* WINAPI apiSNGetKeyExpiresTime(HANDLE handle, SN_RESULT* pResult);
    
    
    /*获取错误信息
    *
    * 参数:
    *	[in] handle:		句柄(通过调用apiSNCreateHandle得到)
    *
    * 返回值:返回参数SN_RESULT.code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    */
    int WINAPI apiSNGetError(HANDLE handle);
    
    
    
    /*释放句柄(内存)
    *
    * 参数:
    *	[in] handle:		句柄(通过调用apiSNCreateHandle得到)
    *
    * 返回值:返回参数SN_RESULT.code(错误码)如果为 0 表示成功,否则表示错误号;
    *
    */
    int WINAPI apiSNDestroyHandle(HANDLE handle);
    
    
    #endif // !_SN_SDK_H__
    

    2.Python调用dll接口

    from ctypes import cdll, c_char_p, Structure, byref
    import ctypes
     
    # 定义SN_STATU结构体
    class SN_STATU(Structure):
        _fields_ = [("code", ctypes.c_int),
                   ("message", c_char_p * 4096)]
     
    # 加载DLL
    lib = cdll.LoadLibrary('D://SNOCR.dll')
     
    # 设置函数参数类型
    lib.apiSNInitOCRServer.argtypes = [c_char_p, ctypes.POINTER(SN_STATU)]
    lib.apiSNInitOCRServer.restype = ctypes.c_int
     
    lib.apiSNCreateOCRHandle.argtypes = [c_char_p, c_char_p, ctypes.POINTER(SN_STATU)]
    lib.apiSNCreateOCRHandle.restype = ctypes.c_void_p
     
    lib.apiSNGetKeyExpiresTime.argtypes = [ctypes.c_void_p, ctypes.POINTER(SN_STATU)]
    lib.apiSNGetKeyExpiresTime.restype = c_char_p
     
    lib.apiSNGetOCRFromImage.argtypes = [ctypes.c_void_p, c_char_p, ctypes.POINTER(SN_STATU)]
    lib.apiSNGetOCRFromImage.restype = c_char_p
     
    lib.apiSNDestroyOCRHandle.argtypes = [ctypes.c_void_p]
    lib.apiSNDestroyOCRHandle.restype = ctypes.c_int
     
    # 初始化变量
    statu = SN_STATU()
    key = b"SNKJe9xffLhdFY7r3TcffXq44ThDVcE3BQFQFfVA9VG4"
    onnx_path = b"D://SNOCR.onnx"
    image_path = b"D://7.jpg"
     
    # 1. 启动OCR服务
    ret = lib.apiSNInitOCRServer(onnx_path, byref(statu))
    if ret < 0:
        print(f"Error:{statu.message.decode('utf-8')}")
        exit()
     
    # 2. 创建OCR句柄
    handle = lib.apiSNCreateOCRHandle(key, onnx_path, byref(statu))
    if not handle:
        print(f"Error:{statu.message.decode('utf-8')}")
        exit()
     
    # 3. 获取卡密到期时间
    expires_time = lib.apiSNGetKeyExpiresTime(handle, byref(statu))
    if not expires_time:
        print(f"Error:{statu.message.decode('utf-8')}")
        exit()
    print(f"Expires Time: {expires_time.decode('utf-8')}")
     
    # 4. 识别OCR,返回Json字符串
    ocr_result = lib.apiSNGetOCRFromImage(handle, image_path, byref(statu))
    if not ocr_result:
        print(f"Error:{statu.message.decode('utf-8')}")
        exit()
    try:
        print(f"OCR Result: {ocr_result.decode('utf-8')}")
    except UnicodeDecodeError:
        print(f"OCR Result: {ocr_result.decode('GBK')}")
     
    # 5. 释放内存
    lib.apiSNDestroyOCRHandle(handle)
     
    # 等待输入,防止程序直接退出
    input("Press Enter to exit...")

    三.效果演示

    1.图片1

    识别效果:

    {
    	"type":	0,
    	"task_id":	1,
    	"err_code":	0,
    	"ocr_result":	{
    		"single_result":	[{
    				"single_rate":	0.939104,
    				"left":	102.208336,
    				"top":	41.812500,
    				"right":	329.854156,
    				"bottom":	67.829170,
    				"single_str_utf8":	"中国建设银行"
    			}, {
    				"single_rate":	0.966887,
    				"left":	104.431534,
    				"top":	68.423492,
    				"right":	309.992828,
    				"bottom":	84.602386,
    				"single_str_utf8":	"China Construction Bank"
    			}, {
    				"single_rate":	0.968900,
    				"left":	102.672920,
    				"top":	96.168755,
    				"right":	403.258331,
    				"bottom":	111.964584,
    				"single_str_utf8":	"龙卡通(储蓄卡)LONG CARD(DEBIT CARD)"
    			}, {
    				"single_rate":	0.975151,
    				"left":	41.781921,
    				"top":	137.955643,
    				"right":	410.251556,
    				"bottom":	164.107880,
    				"single_str_utf8":	"6227 0033 2069 0222 205"
    			}, {
    				"single_rate":	0.935433,
    				"left":	20.770407,
    				"top":	210.668716,
    				"right":	77.230583,
    				"bottom":	230.122101,
    				"single_str_utf8":	"ATM"
    			}, {
    				"single_rate":	0.960131,
    				"left":	103.137505,
    				"top":	185.368759,
    				"right":	192.337509,
    				"bottom":	207.204163,
    				"single_str_utf8":	"CCB GZ"
    			}, {
    				"single_rate":	0.929293,
    				"left":	338.376495,
    				"top":	201.118103,
    				"right":	417.111450,
    				"bottom":	224.273529,
    				"single_str_utf8":	"UnionPa"
    			}, {
    				"single_rate":	0.917808,
    				"left":	367.485413,
    				"top":	220.677078,
    				"right":	413.479156,
    				"bottom":	239.260422,
    				"single_str_utf8":	"银联"
    			}],
    		"unknown_1":	446,
    		"unknown_2":	280
    	}
    }

    2.图片2

    识别效果:

    {
    	"type":	0,
    	"task_id":	1,
    	"err_code":	0,
    	"ocr_result":	{
    		"single_result":	[{
    				"single_rate":	0.919637,
    				"left":	622.061157,
    				"top":	123.251556,
    				"right":	1046.638920,
    				"bottom":	190.015121,
    				"single_str_utf8":	"马托13610000670"
    			}, {
    				"single_rate":	0.996936,
    				"left":	40.618664,
    				"top":	324.310150,
    				"right":	541.513184,
    				"bottom":	371.843231,
    				"single_str_utf8":	"广州利驰服装有限公司"
    			}, {
    				"single_rate":	0.997014,
    				"left":	624.066650,
    				"top":	218.300000,
    				"right":	1040.933350,
    				"bottom":	242.966675,
    				"single_str_utf8":	"地址:广州市海珠区赤岗路173号"
    			}, {
    				"single_rate":	0.964238,
    				"left":	624.066650,
    				"top":	251.600000,
    				"right":	844.833374,
    				"bottom":	276.266663,
    				"single_str_utf8":	"金丰大厦503室"
    			}, {
    				"single_rate":	0.979285,
    				"left":	625.300000,
    				"top":	286.133331,
    				"right":	1044.633300,
    				"bottom":	309.566681,
    				"single_str_utf8":	"厂址:广州市海珠区赤岗西路232"
    			}, {
    				"single_rate":	0.996300,
    				"left":	624.066650,
    				"top":	318.200000,
    				"right":	759.733337,
    				"bottom":	341.633331,
    				"single_str_utf8":	"号-234号"
    			}, {
    				"single_rate":	0.991057,
    				"left":	624.066650,
    				"top":	351.500000,
    				"right":	925,
    				"bottom":	374.933350,
    				"single_str_utf8":	"热线:400-688-7260"
    			}, {
    				"single_rate":	0.964125,
    				"left":	625.239319,
    				"top":	381.016510,
    				"right":	922.600220,
    				"bottom":	404.499695,
    				"single_str_utf8":	"电话:020-84022958"
    			}, {
    				"single_rate":	0.993601,
    				"left":	624.066650,
    				"top":	408.233337,
    				"right":	923.766663,
    				"bottom":	432.900000,
    				"single_str_utf8":	"传真:020-84022572"
    			}, {
    				"single_rate":	0.950434,
    				"left":	625.203430,
    				"top":	438.767609,
    				"right":	1107.616580,
    				"bottom":	464.666626,
    				"single_str_utf8":	"邮箱:kunhemwl@yahoo.com.cn"
    			}, {
    				"single_rate":	0.962023,
    				"left":	624.066650,
    				"top":	471.133331,
    				"right":	1001.466670,
    				"bottom":	494.566681,
    				"single_str_utf8":	"网址:www.hxkunhe.com"
    			}],
    		"unknown_1":	1184,
    		"unknown_2":	614
    	}
    }

    四.常见问题

    1.是否支持多线程

    支持

    五.更新日志

  • 2024.12.15 OCR 文字识别支持C++/Python/易语言
  • 六.云盘源码下载

  • 百度云盘
  • 夸克云盘
  • 123云盘
  • 作者:猿说编程

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python OCR 文字识别

    发表回复