Compare commits

..

226 Commits

Author SHA1 Message Date
yangjiaxuan b7f9a0b8e4 G300;固件版本为211124及以下的设备不支持休眠,屏蔽该功能 2024-01-19 10:04:23 +08:00
yangjiaxuan 9109a04eaa 立思辰新增G63S型号,pid为0x8630 2024-01-18 09:58:23 +08:00
yangjiaxuan d2bde90022 解决dsp100,200设备,开启区域裁切和300以上dpi,会自动取消扫描的问题;BUG-882 2024-01-17 09:12:27 +08:00
yangjiaxuan 86cd595177 增加设置固件语言模式的接口 2024-01-17 09:05:19 +08:00
yangjiaxuan f5ae44fbcb 解决064b设备的设备名称显示不对的问题 2024-01-13 17:11:09 +08:00
yangjiaxuan 0d64b48c3a 调整国产系统sane驱动的双张纸流程;
启动扫描时第一张为双张,sane_start返回值不能正常报错
2024-01-13 14:12:01 +08:00
13038267101 a9e9899319 调整锐化 在黑白之前 2024-01-12 16:43:16 +08:00
13038267101 f33d1f7df5 调整7010 下的伽马值 2024-01-10 18:09:07 +08:00
yangjiaxuan 297d5ed27b 调整中性版本英文驱动帮助文档路径; 2024-01-09 19:21:37 +08:00
yangjiaxuan 75aaa0c475 国产系统修改中性版本驱动帮助文档路径 2024-01-09 17:11:13 +08:00
yangjiaxuan fb3b6bbe74 300安卓,100,200dsp设备分辨率最小值从1调整至100 2024-01-09 15:38:38 +08:00
yangjiaxuan e8e8e484e4 解决多流输出、自动颜色识别和黑白下,锐化模糊不生效的问题 2024-01-05 14:43:30 +08:00
yangjiaxuan 9c916485ea 多流、黑白、颜色自动识别取消屏蔽锐化与模糊功能; 2024-01-05 10:08:55 +08:00
yangjiaxuan 11c902f23e CIS原图检测时关闭脏污检测功能 2024-01-05 09:19:47 +08:00
yangjiaxuan 4d53672e6e 解决保留双张后继续扫描后异常错误全都报扫描完成,安卓设备不提示双张错误的问题;BUG-876 2024-01-04 14:20:30 +08:00
yangjiaxuan 4322c14be2 解决双张保留图像后仍提示双张错误的问题;BUG-874 2024-01-03 15:12:11 +08:00
13038267101 4d93d6bb1a Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2024-01-03 14:41:31 +08:00
13038267101 5104218ace 调整除摩尔纹模式 灰度模式下的数据异常 2024-01-03 14:41:11 +08:00
yangjiaxuan eaa0fb02a6 除3399设备,增加色散算法处理 2024-01-03 11:50:45 +08:00
13038267101 6a0fd39747 app 算法之前的边缘缩进 噪点等级未生效 2024-01-02 20:15:35 +08:00
13038267101 8ee68aa7e9 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2024-01-02 13:48:57 +08:00
13038267101 e7608d308d 调整 因为G306 app导致 取图效率变低 2024-01-02 13:48:43 +08:00
yangjiaxuan e5a92d9585 调整编码格式 2023-12-22 10:57:26 +08:00
gb ddf6b6e4d1 增加扫描前无纸检测配置开关,以解决部分老设备没有无纸检测协议导致无法扫描的情况 2023-12-22 09:26:05 +08:00
yangjiaxuan 13b4327281 微调获取硬盘和内存大小接口和传参 2023-12-20 14:40:41 +08:00
yangjiaxuan 0d2c7d79f7 添加代码备注 2023-12-18 11:36:54 +08:00
13038267101 2727b272da 色彩填充版本调整 2023-12-18 09:47:09 +08:00
13038267101 924fc028f6 微调 2023-12-18 09:38:40 +08:00
13038267101 f0c1287ddb 调整G439 校正问题 2023-12-18 08:50:55 +08:00
13038267101 e2abedf820 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-12-14 17:27:51 +08:00
13038267101 d2f3a7e45a 3B0318 支持自适应 2023-12-14 17:27:38 +08:00
yangjiaxuan 6b067189ed 解决大幅面高分辨率时,扫描结束时图像丢失的问题,BUG-853 2023-12-13 14:10:06 +08:00
yangjiaxuan 38a7e40296 微调 2023-12-13 10:19:34 +08:00
yangjiaxuan 96b91254b4 解决点击重启却进入烧录模式的问题 2023-12-13 10:12:24 +08:00
yangjiaxuan ea07433491 增加中晶pid:9222和9223,分别对应139和239设备 2023-12-12 14:43:23 +08:00
yangjiaxuan 5669ff2464 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-12-11 15:50:32 +08:00
yangjiaxuan 7de448dca7 3399设备,固件3C1206及之后,开放防渗透等级 2023-12-11 15:50:15 +08:00
13038267101 913b16b21e Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-12-11 15:49:32 +08:00
13038267101 21d59af26c 调整306帧数控制 2023-12-11 15:49:11 +08:00
yangjiaxuan f3a06285ff 更新跳过空白页算法v1.10,优化算法效能 2023-12-11 11:28:53 +08:00
gb b0274c4b31 fix BUG-843: 超时就休眠一会儿,给别的线程一点访问USB的机会。 2023-12-09 17:43:10 +08:00
yangjiaxuan d8ade4c912 更新除穿孔算法,提高效能;BUG-711 2023-12-08 15:33:47 +08:00
yangjiaxuan bb4b577f14 微调 2023-12-08 13:44:38 +08:00
yangjiaxuan e3eb140fcf 解决纯色纸张扫描白色边缘填充会导致跳过空白页跳不过的问题;BUG-830 2023-12-08 10:25:50 +08:00
yangjiaxuan 90fb6f5955 解决除穿孔算法,二值化阈值传参50改为20,解决深色纸张会导致算法耗时的问题;BUG-819 2023-12-08 09:41:25 +08:00
gb 436dc23db6 fix word truncated spell error 2023-12-08 08:49:10 +08:00
yangjiaxuan bcd6475f1b 更新裁切纠偏算法,调整色彩填充问题;Bug-758 2023-12-07 18:29:26 +08:00
13038267101 c6b255a18a Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-12-07 17:01:15 +08:00
13038267101 f8cf547512 调整默认占空比 2023-12-07 17:01:03 +08:00
gb d0093d6199 图像处理异常时,保存异常图片;关闭设备之前,调用一次stop 2023-12-07 16:56:55 +08:00
gb ed5f19354b 增加图像处理错误代码,确定为内存分配失败才返回内存错误,其它返回SCANNER_ERR_IMAGE_PROC_FATAL错误 2023-12-07 16:18:31 +08:00
gb 43ef322c20 调整sane_start日志位置 2023-12-07 15:06:48 +08:00
yangjiaxuan bfe3819be3 解决多流输出时黑白阈值不生效的问题;BUG-816 2023-12-07 11:00:16 +08:00
yangjiaxuan 800fca0a0e 更新裁切纠偏算法,解决纸张尺寸比设置的尺寸小时,裁切异常的问题;BUG-815 2023-12-07 09:25:32 +08:00
gb 4f78f416b5 修改USB图片队列ID为usb_img_index_ 2023-12-07 09:03:57 +08:00
yangjiaxuan c99d07c1a4 解决取图卡顿的问题;BUG-812 2023-12-06 15:08:32 +08:00
yangjiaxuan 24cd6b5c10 微调编码格式 2023-12-06 14:54:48 +08:00
yangjiaxuan 21c0ddec8f 固件协议增加防渗透等级 2023-12-06 14:40:21 +08:00
gb 3ce9a65ae6 退出待纸扫描日志,输出do_stop错误码。 2023-12-06 13:54:57 +08:00
gb f3514d0792 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-12-06 10:50:42 +08:00
gb ecf7e2e071 添加解码失败时保存原数据功能;添加pop_first_image失败时停止扫描功能 2023-12-06 10:50:31 +08:00
13038267101 6a6b24d07a 微调 2023-12-06 10:49:12 +08:00
13038267101 fc016443cf Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-12-06 10:47:22 +08:00
13038267101 62a0dec39d 带纸扫描 在超时期间判断 设备是否还在运行当中。。 2023-12-06 10:47:11 +08:00
gb 27fa305c9a 添加pop_first_image失败日志 2023-12-06 09:10:33 +08:00
yangjiaxuan 57de6617b4 调整彩旗纠偏算法阈值,解决存在rgb均值低于该阈值导致裁切不全的问题; 2023-12-05 16:58:13 +08:00
yangjiaxuan 35999b8f16 更新裁切纠偏算法,解决固定幅面裁切纠偏位置异常的问题 2023-12-05 15:51:43 +08:00
yangjiaxuan cf1f7621e5 调整跳过空白页判断边缘阈值,优化图像边缘填充会导致跳不过的问题 2023-12-05 12:04:34 +08:00
yangjiaxuan 3c520920d2 双张校验和跳过空白页同时开启;
当双张被识别为空白页时,不做跳过空白页处理,优先提示双张校验
2023-12-05 11:38:25 +08:00
yangjiaxuan fea65386e8 调整:在取图过程中,如果usb断开则停止扫描并增加提示 2023-12-05 11:33:27 +08:00
yangjiaxuan 3fadf2de42 更新空白页算法,将纯色纸张识别为空白页 2023-12-05 10:17:52 +08:00
yangjiaxuan 7ab95e272e 更新跳过空白页算法,去掉基于文件大小跳过空白页算法,优化效能 2023-12-05 09:02:43 +08:00
yangjiaxuan b7b85e44a8 更新防渗透算法,优化效果,支持灰度图防渗透,BUG-769 2023-12-04 18:03:23 +08:00
yangjiaxuan b1b5ed44e0 更新除背景底色算法,提高效能 2023-12-04 17:54:50 +08:00
yangjiaxuan 57082a9efe 更新除穿孔算法,优化填充穿孔不全的问题,BUG-711 2023-12-04 17:52:07 +08:00
yangjiaxuan 6fc4df0550 更新多流除红算法,解决会将非红色色彩去掉的问题,BUG-798 2023-12-04 17:50:46 +08:00
gb ca041a1005 调整保存USB图像时,不在IO锁当中执行,以便在save_usb_image中可以通过休眠来让其它线程有机会获取IO锁。 2023-12-04 16:29:55 +08:00
gb 9b10e91dba sleep to switch thread in USB thread saving image if user invoke cancel 2023-12-04 15:21:08 +08:00
gb db0a5b7db3 add log before do_stop 2023-12-04 14:58:54 +08:00
gb ebd227d27d fix return value of stop action. 2023-12-04 14:52:00 +08:00
gb b78afdc9a0 add lock on do_stop command 2023-12-04 11:50:39 +08:00
gb d5325e9a4c 增加从设备描述符iProduct域中判断通信协议版本的接口 2023-12-02 17:53:25 +08:00
yangjiaxuan 7de2077960 更新答题卡除红算法,解决答题卡除红会除掉绿色和橙色等颜色 2023-12-01 18:13:13 +08:00
yangjiaxuan cfb1431efd 解决点击扫描,电机未启动之前就点击取消扫描,设备仍然继续走纸的问题,BUG-801 2023-12-01 16:28:36 +08:00
yangjiaxuan f30f227860 解决300设备真实600dpi固定尺寸扫描图像不完整的问题 2023-12-01 14:55:30 +08:00
13038267101 3d865fa895 对折背景色,设置为白色 2023-12-01 13:58:04 +08:00
13038267101 ef3792b131 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-30 10:53:24 +08:00
13038267101 e6026342bc 带纸扫描 错误情况未退出 2023-11-30 10:53:09 +08:00
yangjiaxuan 9590e61da2 更新自动颜色识别算法,提高识别率 2023-11-28 18:04:08 +08:00
yangjiaxuan a423b0c8ba 更新除穿孔算法,解决真实600dpi除穿孔失败的问题 2023-11-28 17:10:07 +08:00
yangjiaxuan 7f4bb50a57 微调 2023-11-28 16:12:45 +08:00
yangjiaxuan 9e30fa0db0 更新裁切纠偏算法到最新版本 2023-11-28 15:47:34 +08:00
13038267101 7de96f6dff 微调 2023-11-28 11:41:47 +08:00
13038267101 833048a97c 微调239带纸扫描 2023-11-28 11:38:31 +08:00
13038267101 c8e913569f Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-28 11:21:08 +08:00
13038267101 3dca020d69 清空管道休眠去掉 2023-11-28 11:20:55 +08:00
yangjiaxuan c7581c84fb 微调 2023-11-27 17:24:17 +08:00
13038267101 e5a395d1fc Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-27 16:53:59 +08:00
13038267101 0d2f75d070 调整普世 反馈退出 等待太久的时间 0439设备 2023-11-27 16:53:16 +08:00
yangjiaxuan 2d1d10f722 解决300设备除摩尔纹误被屏蔽的问题 2023-11-27 15:41:04 +08:00
13038267101 4c75e42f01 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-27 09:27:01 +08:00
13038267101 c2e438544d 调整0x439 stop退出时间 2023-11-27 09:26:49 +08:00
yangjiaxuan e6468b42c0 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-24 18:07:56 +08:00
yangjiaxuan 7333a2b964 300设备屏蔽最大扫描尺寸自动裁切 2023-11-24 18:07:44 +08:00
13038267101 cbeb2f5653 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-24 16:22:11 +08:00
13038267101 07e1c0921c 调整 断开之后的报错 2023-11-24 16:22:01 +08:00
yangjiaxuan 52097e47e7 解决待纸扫描未到时间,就提前报扫描完成的问题,获取图像超时60s改为120s 2023-11-24 15:45:24 +08:00
gb 2400239e55 fix life manager of libusb_device* 2023-11-24 15:14:15 +08:00
yangjiaxuan 89b2fc4777 解决3288-400和dsp设备600dpi除穿孔失败的问题 2023-11-24 13:53:47 +08:00
yangjiaxuan 47cf2a4ae8 解决sdk调用重启接口,传参错误导致进入了烧录模式 2023-11-23 11:36:39 +08:00
yangjiaxuan ff3a782f4e 解决去除摩尔纹,300dpi及以上时会提示不支持的问题 2023-11-23 11:11:07 +08:00
yangjiaxuan a65e1455b5 调整编码格式和乱码 2023-11-23 11:09:31 +08:00
gb 8c5cba338c 修复锁定功能崩溃问题 2023-11-23 10:39:09 +08:00
13038267101 6b53aed32e 微调设备锁定线程 2023-11-23 10:25:10 +08:00
13038267101 d0cf834b95 调整 239打开马上关闭导致的崩溃问题 2023-11-23 10:11:31 +08:00
gb e2939d5c46 fix bug-703 2023-11-22 16:53:52 +08:00
yangjiaxuan 3ff93b1dca 更新黑白阈值算法,解决黑白阈值不生效的问题 2023-11-22 15:37:50 +08:00
yangjiaxuan 0599191708 更新自动颜色识别算法,解决自动颜色识别有误差的问题 2023-11-22 14:18:34 +08:00
yangjiaxuan c0bfb66ad1 更新除背景底色算法 2023-11-22 10:53:23 +08:00
yangjiaxuan d7ec535fdd 解决固定幅面除背景色失败的问题,将除背景色阈值从1-128调至1-255,偏移量从0调至100 2023-11-22 10:12:46 +08:00
gb a41de93724 待纸扫描功能取决于三个因素:待纸扫描为真;扫描数量为-1;单张测试为假。BUG-732 2023-11-22 09:25:40 +08:00
yangjiaxuan bc6fdc836d 解决调整了亮度等参数后,勾选自定义色调曲线,亮度等仍然生效的问题 2023-11-21 18:34:16 +08:00
yangjiaxuan 6cc022191c 解决多流输出灰度加黑白扫描后,取消勾选多流仍输出灰度图 2023-11-21 17:57:36 +08:00
yangjiaxuan b3a7503be9 更新防渗透算法和调整防渗透等级 2023-11-21 17:37:16 +08:00
yangjiaxuan e79bed40dd 调整校正流程,解决校正信息采集有误的问题 2023-11-21 17:16:10 +08:00
yangjiaxuan 9ecaf00146 微调 2023-11-20 10:43:38 +08:00
yangjiaxuan 4c9dd9462b 300设备纸张尺寸屏蔽三联试卷 2023-11-20 10:36:57 +08:00
yangjiaxuan 54598d4a54 更新除穿孔算法 2023-11-20 10:03:10 +08:00
yangjiaxuan 34dd2b8178 更新偏色算法,调整饱和度系数 2023-11-20 09:34:09 +08:00
yangjiaxuan 57af551e4e 微调偏色算法,去除里面的调试代码 2023-11-17 18:02:01 +08:00
yangjiaxuan 524a9b2af7 设备休眠时做操作增加设备休眠提示 2023-11-17 17:06:04 +08:00
yangjiaxuan cb7e9ebd8e 微调编码格式 2023-11-16 17:03:22 +08:00
yangjiaxuan 7da6736e0e 300 302设备600dpi屏蔽最大扫描尺寸 2023-11-16 17:00:32 +08:00
13038267101 3faed87207 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-16 14:33:53 +08:00
13038267101 1fcd17c167 新增 7010偏色数据 2023-11-16 14:33:41 +08:00
gb 0b41d9f30a 打开设备时增加异常处理,使JSON配置异常时能够快速退出,并返回报内部数据错误 2023-11-16 09:23:06 +08:00
13038267101 49cb1e71b5 7010调整伽马到2.0 2023-11-15 17:41:57 +08:00
13038267101 2031ee25ab Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-15 11:50:32 +08:00
13038267101 ccd91dc0d6 过滤锁定日志 2023-11-15 11:50:18 +08:00
yangjiaxuan ef81bb11df 偏色算法传参增加默认参数值 2023-11-15 10:16:36 +08:00
13038267101 95f01e66d3 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-14 18:04:22 +08:00
13038267101 bcd6a7ff39 7010新增一个空包,空包作用是随错误码 一起传输 2023-11-14 18:04:10 +08:00
yangjiaxuan 18669d32ef 固件升级增加升级失败的判断 2023-11-14 15:40:54 +08:00
luoliangyi 4e99f49c72 解决编译问题 2023-11-14 13:44:46 +08:00
yangjiaxuan c5b1afb88d 解决300设备固件升级报错IO错误的问题 2023-11-14 11:42:06 +08:00
yangjiaxuan 6f363096bb 屏蔽跳过空白页(基于文件大小) 2023-11-13 17:49:19 +08:00
yangjiaxuan 0bbbe41c3e 调整偏色校正,驱动层与算法层接口一致 2023-11-13 17:21:47 +08:00
yangjiaxuan b4b363720f 调整300d8设备日志导出不全的问题 2023-11-13 17:06:31 +08:00
yangjiaxuan 36b334f3ff 300安卓设备和400-3288设备增加偏色校正 2023-11-13 11:45:34 +08:00
13038267101 28962b775c Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-10 17:09:30 +08:00
13038267101 54bc87c119 调整升级流程 2023-11-10 17:09:10 +08:00
yangjiaxuan 70fc147c6e 3399设备增加固件升级失败的返回值 2023-11-10 15:26:05 +08:00
yangjiaxuan 57814455dc 选择不支持尺寸检测的纸张尺寸时,固件协议上主动将尺寸检测设为false 2023-11-10 14:47:47 +08:00
yangjiaxuan c8354cf858 解决图像处理比较多时,点击扫描取消,界面一直等待的问题 2023-11-09 14:57:33 +08:00
yangjiaxuan 87874c6cc4 操作json配置时先判断有无该字段,解决402卡死的问题 2023-11-09 11:16:36 +08:00
yangjiaxuan 28b7395b68 背面旋转180°与对折不作互斥 2023-11-08 16:05:36 +08:00
yangjiaxuan ebaace74a1 解决待纸扫描到了时间未退出的问题 2023-11-08 15:46:33 +08:00
yangjiaxuan 142e957507 解决勾选色调曲线,但不打开窗口,出图异常的问题 2023-11-08 14:52:12 +08:00
yangjiaxuan 8cebf0d586 修改防渗透等级依次为较弱、弱... 2023-11-08 14:02:47 +08:00
yangjiaxuan 77a0c7e176 扫描无图时,如果为正常结束则返回正常状态 2023-11-07 18:19:47 +08:00
yangjiaxuan e522398781 解决脏污检测第一次勾选或取消勾选时不生效的问题 2023-11-07 17:02:51 +08:00
yangjiaxuan 4a94b460dd 校正结束时如果固件未返回信号,则通过指定字符串判断是否结束 2023-11-06 15:28:54 +08:00
yangjiaxuan d5d33d8bdb 更新基于文件大小跳过空白页的算法 2023-11-06 14:43:07 +08:00
yangjiaxuan c1d2196656 非IMG类型的错误没有记录,导致报错为扫描完成(如折角检测和尺寸检测) 2023-11-03 14:47:48 +08:00
yangjiaxuan 8aebb9c4eb 300d8设备日志,固件0430之后的直接从片上读取文件,不用协议 2023-11-03 09:44:27 +08:00
yangjiaxuan 5c19147246 调整校正超时返回错误码 2023-11-02 18:09:31 +08:00
yangjiaxuan ea2768c16d twain协议增加脏污检测 2023-11-02 15:32:22 +08:00
yangjiaxuan c746e58c82 增加配置项:“上传图像并停止扫描”,固件不支持双张校验时显示 2023-11-01 17:59:27 +08:00
13038267101 73227fd45a 调整PWM占空比 2023-11-01 15:14:02 +08:00
13038267101 5846ced765 暂时移除306一些功能项 2023-11-01 10:51:21 +08:00
13038267101 567d030f02 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-11-01 10:45:27 +08:00
13038267101 0b439c26e3 306 摩尔纹调整 2023-11-01 10:45:19 +08:00
yangjiaxuan 325f3c2888 固件不支持时,屏蔽脏污检测功能 2023-10-31 19:10:42 +08:00
yangjiaxuan 41ebdc282f 固件1025版本需要出其他功能,为避免冲突,脏污检测和双张校验功能固件版本从1021提升到1027 2023-10-31 14:47:11 +08:00
yangjiaxuan 9ea63dd1ec 更新空白页算法接口,增加跳过空白页(基于文件大小) 2023-10-31 14:41:28 +08:00
yangjiaxuan 96d7466aca 439图像处理已支持保留双张 2023-10-28 16:31:12 +08:00
gb 927b0199d3 调整sane_start/sane_stop流程,start等到一张图后返回第一张图状态或者结束状态;stop等到工作线程退出后才返回 2023-10-28 14:47:15 +08:00
13038267101 3af53b5dae Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-27 20:44:29 +08:00
13038267101 88ac5e7839 7010 屏蔽图像处理部分以及查值表保存图像代码 2023-10-27 20:40:38 +08:00
yangjiaxuan e0696bd9b6 解决获取系统时间功能代码,在linux无法使用的问题 2023-10-27 15:43:06 +08:00
13038267101 12ae6591b9 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-27 11:10:33 +08:00
13038267101 5332cc6d2a 新增占空比 2023-10-27 11:10:14 +08:00
yangjiaxuan ec7782126b 备份还原增加延时等待固件处理,300固件号判断是否支持双张 2023-10-26 17:59:28 +08:00
yangjiaxuan 382ef8be76 3399、3288设备默认板级时间校验,微调备份还原 2023-10-26 17:26:13 +08:00
yangjiaxuan ee35cf042f 图像处理先旋转再对折 2023-10-26 10:54:42 +08:00
yangjiaxuan 0db35e4b3b 备份还原和校验时间功能需要判断固件版本 2023-10-26 10:49:32 +08:00
yangjiaxuan a3334457bf 3399 和3288设备增加备份还原功能和校验板级时间功能 2023-10-26 09:45:40 +08:00
yangjiaxuan 716d5db92b 300d8设备增加镜头脏污检测 2023-10-25 19:50:29 +08:00
13038267101 d172dc3685 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-25 18:42:50 +08:00
13038267101 c4bb56fc79 调整7010色彩问题 2023-10-25 18:42:34 +08:00
yangjiaxuan bb4fd7fc3d 300d8设备增加双张保留机制功能 2023-10-25 17:57:03 +08:00
yangjiaxuan 392fc37f30 239增加镜头脏污检测功能 2023-10-25 15:00:31 +08:00
13038267101 e6080d803f Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-24 14:39:11 +08:00
13038267101 7d48f11935 删除G300 上面的7010操作 2023-10-24 14:38:58 +08:00
yangjiaxuan eb443e353f “跳过空白页”与“对折”做互斥处理 2023-10-23 17:24:38 +08:00
gb ce05ef521e including brand.h in file hg_scanner.h 2023-10-23 15:00:17 +08:00
gb d0a267adb4 调整sane_cancel日志输出位置 2023-10-23 11:26:35 +08:00
yangjiaxuan bb6c1cdf6e 更新跳过空白页算法,优化通过jpeg大小判断空白页 2023-10-23 09:28:22 +08:00
13038267101 5f1c2f45fd 调整306固件升级 2023-10-21 18:18:35 +08:00
13038267101 4592b81370 调整G306设备流程 2023-10-21 17:17:12 +08:00
13038267101 c770715397 Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-21 09:03:47 +08:00
13038267101 679cb0ffef 新增306设备 2023-10-21 09:03:26 +08:00
yangjiaxuan 34d078eb2d 更新除穿孔算法 2023-10-20 15:50:55 +08:00
gb f6ed0211ea 更改国产系统下语言包模块名称 2023-10-20 11:46:27 +08:00
gb 78f5a7baa7 更换sane/scanner/lang三个模块名称,避免与第三方APP模块名称冲突 2023-10-20 11:13:18 +08:00
gb 07d094acd0 Revert "为双张处理功能,调整三方启动逻辑"
This reverts commit af593e3376.
2023-10-18 17:09:34 +08:00
gb af593e3376 为双张处理功能,调整三方启动逻辑 2023-10-18 16:33:25 +08:00
gb 483703fa95 将is_scanning方法提升为公开可访问 2023-10-18 14:56:09 +08:00
gb 13cb6ad835 blocking during stop() call until all worker-threads exit 2023-10-18 14:49:29 +08:00
yangjiaxuan a2002ac455 微调 2023-10-17 18:23:04 +08:00
13038267101 5aecdef38a Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-16 16:25:12 +08:00
13038267101 16bd0223c0 新增除摩尔纹模式 2023-10-16 16:24:44 +08:00
gb 6e43985480 智学网在设置待纸扫描时可能要扫描单张,此时取消待纸扫描功能,待恢复到连续扫描时再恢复待纸扫描状态(中间如果用户通过协议设置了待纸扫描,则不恢复之前的状态) 2023-10-16 15:34:23 +08:00
gb dad78e3b20 双张状态从获取图片信息的接口sane_get_parameters返回: SCANNER_ERR_DEVICE_DOUBLE_FEEDING 2023-10-13 10:42:43 +08:00
yangjiaxuan cc0d64f17d 解决设备读取内存大小时如不支持则会导致卡死的问题 2023-10-13 09:56:23 +08:00
yangjiaxuan 66276e6c9f 调整部分编码格式导致中文乱码的问题 2023-10-12 13:56:04 +08:00
yangjiaxuan eaf4243787 补充双张校验功能实现 2023-10-11 17:44:16 +08:00
yangjiaxuan e5f3e22cdd 增加上传图像并校验功能,屏蔽302代码内的尺寸检测 2023-10-11 17:39:36 +08:00
yangjiaxuan 2d7d9b5e52 开放300d8设备偏色校正,更新偏色校正算法 2023-10-11 11:55:21 +08:00
yangjiaxuan 34d854cc56 调整G300设备导出设备日志超时失败 2023-10-09 11:11:10 +08:00
13038267101 f9b31130ac Merge branch 'dev' of http://192.168.10.5:8099/sane/code_device into dev 2023-10-08 18:03:26 +08:00
13038267101 7aa481f811 新增丢帧检测 2023-10-08 18:03:11 +08:00
yangjiaxuan f29ab1d599 更新图像状态相关头文件定义 2023-10-08 15:20:36 +08:00
gb a47d895109 释放加解密对象 2023-10-08 14:38:05 +08:00
gb 1b54667d92 更改SANE_Image_Status定义与固件一致 2023-10-07 16:43:24 +08:00
gb 6f5bde5cc4 添加异常图片处理协议 2023-10-07 12:41:50 +08:00
57 changed files with 4795 additions and 1590 deletions

View File

@ -4,7 +4,6 @@
#include <opencv2/imgproc/hal/hal.hpp> #include <opencv2/imgproc/hal/hal.hpp>
#include "ImageApplyDispersion.h" #include "ImageApplyDispersion.h"
#define COLOR_BACKGROUND_THRE 20
#define FRONT_TOP 70 #define FRONT_TOP 70
#define FX_FY 0.5f #define FX_FY 0.5f
@ -18,14 +17,13 @@ CImageApplyAutoCrop::CImageApplyAutoCrop()
, m_noise(8) , m_noise(8)
, m_indent(5) , m_indent(5)
, m_normalCrop(false) , m_normalCrop(false)
, m_isDispersion(true)
, m_fx(1.0) , m_fx(1.0)
, m_fy(1.0) , m_fy(1.0)
{ {
} }
CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor, CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor,
double threshold, int noise, int indent, bool normalCrop, bool dispersion, double fx, double fy) double threshold, int noise, int indent, bool normalCrop, double fx, double fy)
: m_isCrop(isCrop) : m_isCrop(isCrop)
, m_isDesaskew(isDesaskew) , m_isDesaskew(isDesaskew)
, m_isFillBlank(isFillBlank) , m_isFillBlank(isFillBlank)
@ -36,7 +34,6 @@ CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFi
, m_indent(indent) , m_indent(indent)
, m_fixedSize(fixedSize) , m_fixedSize(fixedSize)
, m_normalCrop(normalCrop) , m_normalCrop(normalCrop)
, m_isDispersion(dispersion)
, m_fx(fx) , m_fx(fx)
, m_fy(fy) , m_fy(fy)
{ {
@ -50,7 +47,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
{ {
cv::Mat dst; cv::Mat dst;
autoCrop_desaskew_fillBlank(pDib, dst, m_isCrop, m_isDesaskew, m_isFillBlank, m_fixedSize.width, m_fixedSize.height, autoCrop_desaskew_fillBlank(pDib, dst, m_isCrop, m_isDesaskew, m_isFillBlank, m_fixedSize.width, m_fixedSize.height,
m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_isDispersion, m_fx, m_fy); m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_fx, m_fy);
pDib = dst; pDib = dst;
} }
@ -99,61 +96,8 @@ void CImageApplyAutoCrop::myWarpAffine(cv::InputArray _src, cv::OutputArray _dst
M, interpolation, borderType, borderValue.val); M, interpolation, borderType, borderValue.val);
} }
cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int threshold)
{
if (image.channels() == 3)
{
uchar table[768] = { 0 };
int hist_bgr[3][256] = { 0 };
int width = image.cols, height = image.rows, bytesPerLine = image.step;
memset(table + threshold * 3, 255, 768 - threshold * 3);
unsigned char* ptr_data = image.data;
unsigned char b = 0;
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine)
for (uint j = 0, x = 0; j < width; j++, x += 3)
{
b = table[ptr_data[x] + ptr_data[x + 1] + ptr_data[x + 2]];
for (uint k = 0; k < 3; k++)
hist_bgr[k][ptr_data[x + k] & b]++;
}
int max_vals[3] = { 0 };
cv::Scalar max_indexes(0, 0, 0);
for (uint i = 5; i < 256; i++)
for (uint j = 0; j < 3; j++)
if (hist_bgr[j][i] > max_vals[j])
{
max_vals[j] = hist_bgr[j][i];
max_indexes[j] = i;
}
return max_indexes;
}
else
{
uchar table[256] = { 0 };
int hist_bgr[256] = { 0 };
int width = image.cols, height = image.rows, bytesPerLine = image.step;
memset(table + threshold, 255, 256 - threshold);
unsigned char* ptr_data = image.data;
unsigned char b = 0;
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine)
for (uint j = 0, x = 0; j < width; j++, x ++)
hist_bgr[ptr_data[x] & table[ptr_data[x]]]++;
int max_vals = 5;
for (uint i = 5; i < 256; i++)
if (hist_bgr[i] > hist_bgr[max_vals])
max_vals = i;
return cv::Scalar(max_vals);
}
}
void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight,
bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, bool dispersion, double fx, double fy) bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, double fx, double fy)
{ {
if (src.empty()) return; if (src.empty()) return;
@ -186,7 +130,7 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
hg::threshold_Mat(resizeMat, thre, threshold); hg::threshold_Mat(resizeMat, thre, threshold);
if (noise > 0) if (noise > 0)
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_RECT, cv::Size(noise * FX_FY, 1)), cv::morphologyEx(thre, thre, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_RECT, cv::Size(cv::max(static_cast<int>(noise * FX_FY), 1), 1)),
cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
std::vector<cv::Vec4i> hierarchy; std::vector<cv::Vec4i> hierarchy;
@ -213,18 +157,26 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
} }
cv::RotatedRect rect = hg::getBoundingRect(maxContour); cv::RotatedRect rect = hg::getBoundingRect(maxContour);
if (rect.size.width < 1 || rect.size.height < 1)
if (dispersion)
{ {
CImageApplyDispersion m_dispersion_apply; dst = src;
cv::Mat mat_dispersion = src(cv::boundingRect(maxContour)); return;
m_dispersion_apply.apply(mat_dispersion, 0);
} }
cv::Scalar blankColor; cv::Scalar blankColor;
if (isFillBlank) if (isFillBlank)
if (isColorBlank) if (isColorBlank)
blankColor = getBackGroudColor(resizeMat, COLOR_BACKGROUND_THRE); {
cv::Rect boudingRect = cv::boundingRect(maxContour);
boudingRect.x *= FX_FY;
boudingRect.y *= FX_FY;
boudingRect.width *= FX_FY;
boudingRect.height *= FX_FY;
cv::Mat temp_bgc;
cv::resize(resizeMat(boudingRect), temp_bgc, cv::Size(200, 200));
blankColor = hg::getBackGroundColor(temp_bgc, cv::Mat(), 10);
}
else else
blankColor = cv::Scalar::all(255); blankColor = cv::Scalar::all(255);
else else
@ -234,21 +186,27 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
if (isDesaskew) if (isDesaskew)
dst = cv::Mat(cv::Size(rect.size), src.type(), blankColor); dst = cv::Mat(cv::Size(rect.size), src.type(), blankColor);
else else
dst = cv::Mat(rect.boundingRect().size(), src.type(), blankColor); dst = cv::Mat(/*rect.boundingRect().size()*/ cv::boundingRect(maxContour).size(), src.type(), blankColor);
else else
dst = cv::Mat(dHeight, dWidth, src.type(), blankColor); dst = cv::Mat(dHeight, dWidth, src.type(), blankColor);
cv::Mat dstROI; cv::Mat dstROI;
if (isDesaskew && rect.angle != 0) if (isDesaskew && rect.angle != 0)
{ {
cv::RotatedRect rect_temp = rect;
if (rect_temp.size.width > dst.cols)
rect_temp.size.width = dst.cols;
if (rect_temp.size.height > dst.rows)
rect_temp.size.height = dst.rows;
cv::Point2f srcTri[4], dstTri[3]; cv::Point2f srcTri[4], dstTri[3];
rect.points(srcTri); rect_temp.points(srcTri);
srcTri[0].x -= 1; srcTri[0].x -= 1;
srcTri[1].x -= 1; srcTri[1].x -= 1;
srcTri[2].x -= 1; srcTri[2].x -= 1;
int w = rect.size.width; int w = rect_temp.size.width;
int h = rect.size.height; int h = rect_temp.size.height;
int x = (dst.cols - w) / 2; int x = (dst.cols - w) / 2;
int y = (dst.rows - h) / 2; int y = (dst.rows - h) / 2;
dstTri[0] = cv::Point2f(0, h); dstTri[0] = cv::Point2f(0, h);
@ -256,7 +214,7 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
dstTri[2] = cv::Point2f(w, 0); dstTri[2] = cv::Point2f(w, 0);
dstROI = dst(cv::Rect(x, y, w, h) & cv::Rect(0, 0, dst.cols, dst.rows)); dstROI = dst(cv::Rect(x, y, w, h) & cv::Rect(0, 0, dst.cols, dst.rows));
myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(0)); myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, blankColor);
} }
else else
{ {
@ -276,6 +234,8 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
dstROI = dst(cv::Rect((dst.cols - bounding.width) / 2, (dst.rows - bounding.height) / 2, bounding.width, bounding.height)); dstROI = dst(cv::Rect((dst.cols - bounding.width) / 2, (dst.rows - bounding.height) / 2, bounding.width, bounding.height));
src(bounding).copyTo(dstROI); src(bounding).copyTo(dstROI);
//cv::imwrite("dst.bmp", dst);
} }
if (isFillBlank) if (isFillBlank)
@ -300,7 +260,8 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
} }
else else
{ {
cv::Rect bounding = rect.boundingRect(); //cv::Rect bounding = rect.boundingRect();
cv::Rect bounding = cv::boundingRect(maxContour);
srcTri[0] = cv::Point(bounding.x, bounding.br().y - 1); srcTri[0] = cv::Point(bounding.x, bounding.br().y - 1);
srcTri[1] = cv::Point(bounding.x, bounding.y); srcTri[1] = cv::Point(bounding.x, bounding.y);
srcTri[2] = cv::Point(bounding.br().x - 1, bounding.y); srcTri[2] = cv::Point(bounding.br().x - 1, bounding.y);

View File

@ -2,8 +2,8 @@
* ==================================================== * ====================================================
* *
* 绿 *
* _020/4/21 * 2020/4/21
* 2020/4/21 v1.0 * 2020/4/21 v1.0
2020/7/22 v1.1 maxContourPC端暂时无需使用_ 2020/7/22 v1.1 maxContourPC端暂时无需使用_
2020/10/16 v1.2 BUG 2020/10/16 v1.2 BUG
@ -29,7 +29,15 @@
2022/10/31 v1.5 DPI缩放参数fx,fy 2022/10/31 v1.5 DPI缩放参数fx,fy
2022/11/19 v1.5.1 稿BUG 2022/11/19 v1.5.1 稿BUG
2022/11/19 v1.5.2 稿BUG 2022/11/19 v1.5.2 稿BUG
* v1.5.2 2023/03/17 v1.5.3 kSize可能为0的BUG
2023/04/19 v1.5.4
2023/05/15 v1.5.5 稿
2023/05/23 v1.5.6 BUG
2023/11/02 v1.6
2023/12/05 v1.6.1 BUG
2023/12/06 v1.6.2 BUG
2023/12/07 v1.6.3 BUG
* v1.6.3
* ==================================================== * ====================================================
*/ */
@ -39,29 +47,28 @@
#include "ImageApply.h" #include "ImageApply.h"
class CImageApplyDispersion;
class GIMGPROC_LIBRARY_API CImageApplyAutoCrop : public CImageApply class GIMGPROC_LIBRARY_API CImageApplyAutoCrop : public CImageApply
{ {
public: public:
CImageApplyAutoCrop(); CImageApplyAutoCrop();
/* /// <summary>
* isCrop [in]:使true自动裁剪false为固定裁剿 /// 构造函数
* isDesaskew [in]:使true自动纠偏false为不纠偏 /// </summary>
* isFillBlank [in]:使true为填充false为不填充 /// <param name="isCrop">自动幅面裁剪使能true自动裁剪false为固定裁切</param>
* fixedSize [in]:isCrop为false时生效fixedSize大小输出紿 /// <param name="isDesaskew">自动纠偏使能true自动纠偏false为不纠偏</param>
* isConvex [in]:,true为凸多边形填充false为凹多边形填充true /// <param name="isFillBlank">黑底填充使能true为填充false为不填充</param>
* isFillColor [in]:false为白色填充true为自适应文稿底色填充false /// <param name="fixedSize">固定幅面尺寸当isCrop为false时生效结果尺寸按fixedSize大小输出单位像素</param>
* threshold [in]:0, 255)访0 /// <param name="isConvex">黑底填充时的填充方式,true为凸多边形填充false为凹多边形填充默认true</param>
* noise [in]:noise宽度的背景竖条纹干扰访 /// <param name="isFillColor">黑底填充时采用自适应色彩填充false为白色填充true为自适应文稿底色填充默认false</param>
* indent [in]:indent像素访 /// <param name="threshold">二值化阈值,取值范囿[-1, 255]默认40。当threshold<0时采用根据背景自适应二值化。</param>
* normalCrop [in]:true时m_isCrop m_isDesaskew m_isFillBlank失效false /// <param name="noise">除噪像素能够消除noise宽度的背景竖条纹干扰默认8。</param>
* dispersion [in]:true时false时不除色散true /// <param name="indent">轮廓缩进裁剪、纠偏或者黑底填充时对探索到的纸张轮廓进行缩进indent像素默认8</param>
* fx [in]:1.0 /// <param name="normalCrop">为true时m_isCrop m_isDesaskew m_isFillBlank失效固定裁切采用最传统的裁切方式默认false</param>
* fy [in]:1.0 /// <param name="fx">横向缩放比例。默认1.0</param>
*/ /// <param name="fy">纵向缩放比例。默认1.0</param>
CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true,
bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, bool dispersion = true, double fx = 1.0, double fy = 1.0); bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, double fx = 1.0, double fy = 1.0);
virtual ~CImageApplyAutoCrop(); virtual ~CImageApplyAutoCrop();
@ -105,23 +112,18 @@ public:
void setFixedSize(cv::Size size) { m_fixedSize = size; } void setFixedSize(cv::Size size) { m_fixedSize = size; }
void setDispersion(bool enable) { m_isDispersion = enable; }
static void autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight, static void autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight,
bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false, bool dispersion = true, bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false,
double fx = 1.0, double fy = 1.0); double fx = 1.0, double fy = 1.0);
private: private:
static void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue); static void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue);
static cv::Scalar getBackGroudColor(const cv::Mat& image, int threshold);
private: private:
bool m_isCrop; bool m_isCrop;
bool m_isDesaskew; bool m_isDesaskew;
bool m_isFillBlank; bool m_isFillBlank;
bool m_isConvexHull; bool m_isConvexHull;
bool m_isFillColor; bool m_isFillColor;
bool m_isDispersion;
double m_threshold; double m_threshold;
int m_noise; int m_noise;

View File

@ -1,5 +1,7 @@
#include "ImageApplyBWBinaray.h" #include "ImageApplyBWBinaray.h"
#define THRESHOLD_LOW 30
#define THRESHOLD_UP 245
CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, int blockSize, int constant) CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, int blockSize, int constant)
: m_threshold(threshold) : m_threshold(threshold)
, m_type(type) , m_type(type)
@ -27,8 +29,6 @@ CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
delete[] m_table; delete[] m_table;
} }
#define THRESHOLD_LOW 30
#define THRESHOLD_UP 245
void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side) void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
{ {
(void)side; (void)side;
@ -40,7 +40,7 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
cv::Mat integ; cv::Mat integ;
int blockSize = m_blockSize;//邻域尺寸 int blockSize = m_blockSize;//邻域尺寸
int threshold = m_constant; int threshold = m_constant;
int low = THRESHOLD_LOW; int low = m_threshold;
int up = THRESHOLD_UP; int up = THRESHOLD_UP;
int halfSize = blockSize / 2; int halfSize = blockSize / 2;
int square_blockSize = blockSize * blockSize; int square_blockSize = blockSize * blockSize;
@ -71,13 +71,13 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
cv::threshold(pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), m_threshold, 255, cv::THRESH_BINARY); cv::threshold(pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), m_threshold, 255, cv::THRESH_BINARY);
break; break;
case ThresholdType::THRESH_OTSU: case ThresholdType::THRESH_OTSU:
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU); cv::threshold(pDib, pDib, m_threshold, 255, cv::THRESH_OTSU);
break; break;
case ThresholdType::ADAPTIVE_GAUSSIAN: case ThresholdType::ADAPTIVE_GAUSSIAN:
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, m_blockSize, m_constant); cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, m_blockSize, m_constant);
break; break;
case ThresholdType::ADAPTIVE_MEAN: case ThresholdType::ADAPTIVE_MEAN:
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, m_blockSize, m_constant); cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, m_blockSize, m_constant);
break; break;
case ThresholdType::ERROR_DIFFUSION: case ThresholdType::ERROR_DIFFUSION:
errorDiffuse(pDib); errorDiffuse(pDib);
@ -108,7 +108,7 @@ void CImageApplyBWBinaray::errorDiffuse(cv::Mat& image)
{ {
if (image.rows < 3 || image.cols < 3) if (image.rows < 3 || image.cols < 3)
{ {
cv::threshold(image, image, m_threshold, 255, CV_THRESH_BINARY); cv::threshold(image, image, m_threshold, 255, cv::THRESH_BINARY);
return; return;
} }

View File

@ -10,7 +10,8 @@
2020/12/21 v1.3.1 2020/12/21 v1.3.1
2020/12/21 v1.3.2 blockSize,5125 2020/12/21 v1.3.2 blockSize,5125
2022/05/25 v1.3.3 blockSize和constantTHRESH_BINARY同样有效 2022/05/25 v1.3.3 blockSize和constantTHRESH_BINARY同样有效
* v1.3.3 2023/11/22 v1.4 THRESH_BINARY模式时m_threshold作为THRESHOLD_LOW使用
* v1.4
* ==================================================== * ====================================================
*/ */

View File

@ -2,67 +2,152 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#define JIANG_BAOHE
#define max(a, b) ((a) > (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
constexpr auto SIZE_OF_TABLE = 256; constexpr auto SIZE_OF_TABLE = 256;
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(PreScheme ps)
: m_table_h(new uchar[SIZE_OF_TABLE])
, m_table_l(new uchar[SIZE_OF_TABLE])
, m_table_s(new uchar[SIZE_OF_TABLE])
{
std::vector<double> points_x, points_y;
switch (ps)
{
case CImageApplyColorCastCorrect::G200:
points_x = { 2, 9, 15, 18, 22, 34, 50, 63, 78, 92, 103, 114, 126, 137, 140, 147, 154, 163, 176, 200, 225, 248, 251, 254 };
points_y = { 11, 17, 24, 28, 32, 41, 56, 81, 106, 115, 119, 124, 131, 138, 141, 145, 153, 166, 186, 201, 217, 251, 259, 264 };
break;
case CImageApplyColorCastCorrect::G300:
points_x = { 1, 7, 12, 18, 33, 52, 68, 81, 91, 100, 111, 125, 138, 142, 147, 153, 161, 172, 198, 230, 248, 250, 252, 253 };
points_y = { 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252, 266, 272, 276 };
break;
case CImageApplyColorCastCorrect::G300_D8:
points_x = { 0, 2, 5, 9, 15, 20, 26, 39, 54, 70, 83, 94, 102, 113, 128, 139, 146, 151, 156, 164, 177, 199, 232, 253 };
points_y = { 11, 17, 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252 };
break;
case CImageApplyColorCastCorrect::G400_402:
points_x = { 2, 8, 15, 20, 27, 41, 50, 67, 80, 91, 99, 109, 124, 138, 145, 150, 157, 164, 177, 202, 232, 250, 252, 255 };
points_y = { 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252, 266, 272 };
break;
case CImageApplyColorCastCorrect::G400_3288:
points_x = { 2, 3, 5, 7, 11, 16, 19, 25, 40, 57, 72, 84, 95, 101, 111, 126, 144, 148, 152, 157, 165, 179, 203, 234 };
points_y = { -3, 11, 17, 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227 };
break;
case CImageApplyColorCastCorrect::Android302:
points_x = { 0, 6, 11, 19, 37, 48, 66, 79, 89, 97, 108, 122, 138, 143, 147, 150, 158, 170, 199, 233, 248, 249, 250, 252 };
points_y = { 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227, 252, 266, 272, 276 };
break;
case CImageApplyColorCastCorrect::G300_7010:
points_x = { 1, 4, 6, 9, 13, 19, 23, 29, 40, 55, 72, 86, 97, 106, 117, 133, 143, 149, 155, 160, 170, 182, 206, 233 };
points_y = { 252, 11, 17, 21, 26, 31, 33, 36, 40, 44, 56, 92, 104, 114, 126, 135, 141, 143, 146, 151, 169, 198, 218, 227 };
break;
default:
points_x = { 0, 255 };
points_y = { 0, 255 };
break;
}
createTable_h(points_x, points_y);
points_x = { 0, 180, 255 };
points_y = { 0, 175, 220 };
createTable_l(points_x, points_y);
points_x = { 0, 230, 255 };
points_y = { 0, 210, 255 };
createTable_s(points_x, points_y);
}
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::vector<double>& h_x, const std::vector<double>& h_y,
const std::vector<double>& l_x, const std::vector<double>& l_y,
const std::vector<double>& s_x, const std::vector<double>& s_y)
: m_table_h(new uchar[SIZE_OF_TABLE])
, m_table_l(new uchar[SIZE_OF_TABLE])
, m_table_s(new uchar[SIZE_OF_TABLE])
{
if (!h_x.empty() && !h_y.empty())
createTable_h(h_x, h_y);
if (!l_x.empty() && !l_y.empty())
createTable_l(l_x, l_y);
if (!s_x.empty() && !s_y.empty())
createTable_s(s_x, s_y);
}
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::vector<double>& points_x, const std::vector<double>& points_y) CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::vector<double>& points_x, const std::vector<double>& points_y)
: m_table(new uchar[SIZE_OF_TABLE]) : m_table_h(new uchar[SIZE_OF_TABLE])
, m_table_l(new uchar[SIZE_OF_TABLE])
, m_table_s(new uchar[SIZE_OF_TABLE])
{ {
createTable(points_x, points_y); createTable_h(points_x, points_y);
for (size_t i = 0; i < SIZE_OF_TABLE; i++)
m_table_l[i] = m_table_s[i] = i;
} }
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::string& fileName) CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const std::string& fileName)
: m_table(new uchar[SIZE_OF_TABLE]) : m_table_h(new uchar[SIZE_OF_TABLE])
, m_table_l(new uchar[SIZE_OF_TABLE])
, m_table_s(new uchar[SIZE_OF_TABLE])
{ {
std::fstream file(fileName, std::ios::in | std::ios::binary); std::fstream file(fileName, std::ios::in | std::ios::binary);
if (file) if (file)
file.read(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE); file.read(reinterpret_cast<char*>(m_table_h), SIZE_OF_TABLE);
file.close(); file.close();
for (size_t i = 0; i < SIZE_OF_TABLE; i++)
m_table_l[i] = m_table_s[i] = i;
} }
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const uchar* table_h) CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const uchar* table_h)
: m_table(new uchar[SIZE_OF_TABLE]) : m_table_h(new uchar[SIZE_OF_TABLE])
, m_table_l(new uchar[SIZE_OF_TABLE])
, m_table_s(new uchar[SIZE_OF_TABLE])
{ {
memcpy(m_table, table_h, SIZE_OF_TABLE); memcpy(m_table_h, table_h, SIZE_OF_TABLE);
} for (size_t i = 0; i < SIZE_OF_TABLE; i++)
m_table_l[i] = m_table_s[i] = i;
CImageApplyColorCastCorrect::CImageApplyColorCastCorrect(const int type)
: m_table(new uchar[SIZE_OF_TABLE])
{
if(type == 1)
memcpy(m_table,CIS_DN_PATCH1,SIZE_OF_TABLE);
else
memcpy(m_table,CIS_DN_PATCH2,SIZE_OF_TABLE);
} }
CImageApplyColorCastCorrect::~CImageApplyColorCastCorrect(void) CImageApplyColorCastCorrect::~CImageApplyColorCastCorrect(void)
{ {
delete[] m_table; delete[] m_table_h;
} delete[] m_table_l;
delete[] m_table_s;
void CImageApplyColorCastCorrect::setlutdata(const int type)
{
if(type == 1) memcpy(m_table,CIS_DN_PATCH1,SIZE_OF_TABLE);
else memcpy(m_table,CIS_DN_PATCH2,SIZE_OF_TABLE);
} }
void CImageApplyColorCastCorrect::apply(cv::Mat& pDib, int side) void CImageApplyColorCastCorrect::apply(cv::Mat& pDib, int side)
{ {
if (pDib.channels() != 3) if (pDib.channels() != 3)
return; return;
cv::Mat hsv; cv::Mat hsv;
cv::cvtColor(pDib, hsv, cv::COLOR_BGR2HSV_FULL); cv::cvtColor(pDib, hsv, cv::COLOR_BGR2HLS_FULL);
cv::Mat hsv_mv[3]; cv::Mat hsv_mv[3];
cv::split(hsv, hsv_mv); cv::split(hsv, hsv_mv);
cv::Mat lut(256, 1, CV_8UC1, m_table); //cv::imwrite("hsv_0.jpg", hsv_mv[0]);
cv::Mat lut(256, 1, CV_8UC1, m_table_h);
cv::LUT(hsv_mv[0], lut, hsv_mv[0]); cv::LUT(hsv_mv[0], lut, hsv_mv[0]);
#ifdef JIANG_BAOHE
//hsv_mv[2] -= 20;
//cv::imwrite("hsv_0.jpg", hsv_mv[0]);
//cv::imwrite("hsv_1.jpg", hsv_mv[1]);
//cv::imwrite("hsv_2.jpg", hsv_mv[2]);
cv::Mat lut2(256, 1, CV_8UC1, m_table_l);
cv::LUT(hsv_mv[2], lut2, hsv_mv[2]);
//hsv_mv[1] -= 20;
//cv::Mat lut3(256, 1, CV_8UC1, m_table3);
//cv::LUT(hsv_mv[1], lut3, hsv_mv[1]);
#endif
cv::merge(hsv_mv, 3, pDib); cv::merge(hsv_mv, 3, pDib);
cv::cvtColor(pDib, pDib, cv::COLOR_HSV2BGR_FULL); cv::cvtColor(pDib, pDib, cv::COLOR_HLS2BGR_FULL);
} }
void CImageApplyColorCastCorrect::apply(std::vector<cv::Mat>& mats, bool isTwoSide) void CImageApplyColorCastCorrect::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
@ -82,11 +167,11 @@ void CImageApplyColorCastCorrect::exportTableData(const std::string& fileName)
{ {
std::fstream file(fileName, std::ios::out | std::ios::binary); std::fstream file(fileName, std::ios::out | std::ios::binary);
if (file) if (file)
file.write(reinterpret_cast<char*>(m_table), SIZE_OF_TABLE); file.write(reinterpret_cast<char*>(m_table_h), SIZE_OF_TABLE);
file.close(); file.close();
} }
void CImageApplyColorCastCorrect::createTable(const std::vector<double>& points_x, const std::vector<double>& points_y) void CImageApplyColorCastCorrect::createTable_h(const std::vector<double>& points_x, const std::vector<double>& points_y)
{ {
int table_temp[256]{}; int table_temp[256]{};
@ -118,9 +203,48 @@ void CImageApplyColorCastCorrect::createTable(const std::vector<double>& points_
for (size_t j = 0; j < 256; j++) for (size_t j = 0; j < 256; j++)
if (table_temp[j] > 255) if (table_temp[j] > 255)
m_table[j] = table_temp[j] - 255; m_table_h[j] = table_temp[j] - 255;
else else
m_table[j] = table_temp[j]; m_table_h[j] = table_temp[j];
} }
} }
void CImageApplyColorCastCorrect::createTable_l(const std::vector<double>& points_x, const std::vector<double>& points_y)
{
memset(m_table_l, 255, 256);
memset(m_table_l, 0, 127);
int s = 1;
for (int i = 0; i < points_x.size() - s; i += s)
{
double low = points_y[i];
double up = points_y[i + s];
int start = points_x[i];
int end = points_x[i + s];
int length = end - start;
double step = (up - low) / length;
for (int j = 0; j < length; j++)
m_table_l[start + j] = max(0.0, min(255.0, low + j * step));
}
}
void CImageApplyColorCastCorrect::createTable_s(const std::vector<double>& points_x, const std::vector<double>& points_y)
{
memset(m_table_s, 255, 256);
memset(m_table_s, 0, 127);
int s = 1;
for (int i = 0; i < points_x.size() - s; i += s)
{
double low = points_y[i];
double up = points_y[i + s];
int start = points_x[i];
int end = points_x[i + s];
int length = end - start;
double step = (up - low) / length;
for (int j = 0; j < length; j++)
m_table_s[start + j] = max(0.0, min(255.0, low + j * step));
}
}

View File

@ -1,4 +1,4 @@
/* /*
* ==================================================== * ====================================================
* *
@ -10,7 +10,12 @@
* v1.2 2023/04/04 线CIS_DN_PATCH3 * v1.2 2023/04/04 线CIS_DN_PATCH3
* v1.3 2023/04/17 * v1.3 2023/04/17
* v2.0 2023/05/15 * v2.0 2023/05/15
* v2.0 * v2.1 2023/10/07
* v2.2 2023/11/13
* v2.2.1 2023/11/13
* v2.2.2 2023/11/17
* v2.2.3 2023/11/17
* v2.2.3
* ==================================================== * ====================================================
*/ */
@ -23,45 +28,24 @@ class GIMGPROC_LIBRARY_API CImageApplyColorCastCorrect : public CImageApply
{ {
public: public:
const uchar CIS_DN_PATCH2[256] = //摩尔纹慢速扫描色偏参数 //预设方案
enum PreScheme
{ {
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, G200,
0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, G300,
0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B, G300_D8,
0x2B, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x30, 0x30, 0x30, G300_7010,
0x31, 0x31, 0x31, 0x32, 0x33, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48, G400_402,
0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x62, 0x63, 0x65, 0x66, 0x68, G400_3288,
0x69, 0x6B, 0x6C, 0x6E, 0x6F, 0x71, 0x72, 0x74, 0x75, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x82, Android302
0x82, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89,
0x8A, 0x8A, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x90, 0x90, 0x91, 0x91,
0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x97, 0x99, 0x9B, 0x9D, 0x9F, 0xA1, 0xA3, 0xA4,
0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF,
0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5,
0xD6, 0xD8, 0xD9, 0xDA, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4,
0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE,
0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF7,
0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0x02, 0x05, 0x08, 0x0A, 0x0D
}; };
const uchar CIS_DN_PATCH1[256] = //正常扫描色偏参数 CImageApplyColorCastCorrect(PreScheme ps = G200);
{
0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, CImageApplyColorCastCorrect(const std::vector<double>& h_x, const std::vector<double>& h_y,
0x1F, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, const std::vector<double>& l_x, const std::vector<double>& l_y,
0x26, 0x26, 0x26, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2B, 0x2B, 0x2B, const std::vector<double>& s_x, const std::vector<double>& s_y);
0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x30, 0x30, 0x30, 0x31,
0x31, 0x31, 0x32, 0x32, 0x33, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48,
0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x62, 0x63, 0x65, 0x66, 0x68,
0x6A, 0x6B, 0x6D, 0x6E, 0x70, 0x72, 0x73, 0x75, 0x76, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x82, 0x82,
0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89,
0x8A, 0x8A, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8E, 0x8F, 0x90, 0x90, 0x90, 0x91, 0x91,
0x92, 0x92, 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6,
0xA8, 0xAA, 0xAC, 0xAE, 0xB2, 0xB3, 0xB4, 0xB6, 0xB7, 0xB8, 0xBA, 0xBB, 0xBC, 0xBE, 0xBF, 0xC1,
0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xD0, 0xD1, 0xD2, 0xD4, 0xD5, 0xD6,
0xD8, 0xD9, 0xDA, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 0xE4, 0xE4, 0xE5,
0xE5, 0xE6, 0xE7, 0xE7, 0xE8, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE,
0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF7, 0xF7,
0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0x02, 0x05, 0x08, 0x0A
};
/// <summary> /// <summary>
/// 用户自定义查值表 /// 用户自定义查值表
/// </summary> /// </summary>
@ -81,14 +65,6 @@ public:
/// <param name="table_h"></param> /// <param name="table_h"></param>
CImageApplyColorCastCorrect(const uchar* table_h); CImageApplyColorCastCorrect(const uchar* table_h);
/// <summary>
/// 选择设置HSV中H通道的LUT校正数据
/// </summary>
/// <param name="table_h"></param>
CImageApplyColorCastCorrect(const int type);
void setlutdata(const int type);
virtual ~CImageApplyColorCastCorrect(void); virtual ~CImageApplyColorCastCorrect(void);
virtual void apply(cv::Mat& pDib, int side); virtual void apply(cv::Mat& pDib, int side);
@ -103,9 +79,11 @@ public:
private: private:
void createTable(const std::vector<double>& points_x, const std::vector<double>& points_y); void createTable_h(const std::vector<double>& points_x, const std::vector<double>& points_y);
void createTable_l(const std::vector<double>& points_x, const std::vector<double>& points_y);
void createTable_s(const std::vector<double>& points_x, const std::vector<double>& points_y);
private: private:
uchar* m_table; uchar* m_table_h, *m_table_l, *m_table_s;
}; };
#endif #endif

View File

@ -1,45 +1,4 @@
#include "ImageApplyColorRecognition.h" #include "ImageApplyColorRecognition.h"
#include "ImageApplyHeaders.h"
//static CImageApplyBWBinaray m_bw;
//static CImageApplyAdjustColors m_ac(0, 50, 1.0f);
/// <summary>
/// 检测图像是否是彩色。当前逻辑仅针对红色像素进行判断,即存在红色像素则为彩色,否则为非彩色
/// </summary>
/// <param name="image">待测图像</param>
/// <returns>true为彩色false为非彩色</returns>
bool isColor(const cv::Mat& image)
{
if (image.channels() != 3) return false;
cv::Mat pDib_resize;
cv::resize(image, pDib_resize, cv::Size(image.cols / 4, image.rows / 4), 0, 0, cv::INTER_NEAREST);
cv::Mat hsv;
cv::cvtColor(pDib_resize, hsv, cv::COLOR_BGR2HSV_FULL);
std::vector<cv::Mat> hsv_channels;
cv::split(hsv, hsv_channels);
cv::Mat range_s1, range_s2;
cv::inRange(hsv_channels[1], 220, 255, range_s1); //饱和度在[220, 255]的像素
cv::inRange(hsv_channels[1], 50, 220, range_s2); //饱和度在[50, 220]的像素
#if 0
cv::imwrite("range_s1.bmp", range_s1);
cv::imwrite("range_s2.bmp", range_s2);
#endif
double sum = cv::sum(range_s1)[0] / 255;
double total = range_s1.total();
// if (sum / total > 0.0001)
if (sum / total > 0.001)
return true;
sum += cv::sum(range_s2)[0] / 255;
// if (sum / total > 0.001)
if (sum / total > 0.03)
return true;
return false;
}
bool isGray(const cv::Mat& image) bool isGray(const cv::Mat& image)
{ {
@ -80,6 +39,7 @@ CImageApplyColorRecognition::~CImageApplyColorRecognition(void)
{ {
} }
#define HSV_S_THRE 30
void CImageApplyColorRecognition::apply(cv::Mat& pDib, int side) void CImageApplyColorRecognition::apply(cv::Mat& pDib, int side)
{ {
if (pDib.channels() != 3) if (pDib.channels() != 3)
@ -87,7 +47,7 @@ void CImageApplyColorRecognition::apply(cv::Mat& pDib, int side)
m_result = Gray; m_result = Gray;
return; return;
} }
m_result = isColor(pDib) ? Color : Gray; m_result = isColor(pDib, HSV_S_THRE) ? Color : Gray;
if (m_result == Gray && pDib.channels() == 3) if (m_result == Gray && pDib.channels() == 3)
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY); cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
@ -153,3 +113,26 @@ std::vector<CImageApplyColorRecognition::ColorType> CImageApplyColorRecognition:
{ {
return m_results; return m_results;
} }
/// <summary>
/// 检测图像是否是彩色。当前逻辑仅针对红色像素进行判断,即存在红色像素则为彩色,否则为非彩色
/// </summary>
/// <param name="image">待测图像</param>
/// <returns>true为彩色false为非彩色</returns>
bool CImageApplyColorRecognition::isColor(const cv::Mat& image, double threshold)
{
if (image.channels() != 3) return false;
cv::Mat pDib_resize;
cv::resize(image, pDib_resize, cv::Size(200, 200), 0, 0, cv::INTER_AREA);
//cv::imwrite("pDib_resize.bmp", pDib_resize);
cv::Mat hsv;
cv::cvtColor(pDib_resize, hsv, cv::COLOR_BGR2HSV_FULL);
std::vector<cv::Mat> hsv_channels;
cv::split(hsv, hsv_channels);
double minVal, maxVal;
cv::minMaxLoc(hsv_channels[1], &minVal, &maxVal);
return maxVal > threshold;
}

View File

@ -4,12 +4,14 @@
* 242568 8 * 242568 8
* *
* 2020/7/17 * 2020/7/17
* 2021/04/19 * v1.0 2020/7/17
* v1.0 2020/7/17 * v1.1 2020/12/15
* v1.1 2020/12/15 * v1.2 2020/12/16 访
* v1.2 2020/12/16 访 * v1.3 2021/04/19 1
* v1.3 2021/04/19 1 * v1.4 2021/06/18 [90, 200][50, 200]
* v1.4 2021/06/18 [90, 200][50, 200] * v1.5 2023/11/22
* v1.5.1 2023//11/28 调整饱和度判定阈值
* v1.5.1
* ==================================================== * ====================================================
*/ */
@ -59,6 +61,9 @@ public:
/// <returns>色彩类型数组</returns> /// <returns>色彩类型数组</returns>
std::vector<ColorType> getResults(); std::vector<ColorType> getResults();
private:
bool isColor(const cv::Mat& image, double threshold = 30);
private: private:
ColorType m_result; ColorType m_result;
std::vector<ColorType> m_results; std::vector<ColorType> m_results;

View File

@ -1,11 +1,12 @@
#include "ImageApplyDiscardBlank.h" #include "ImageApplyDiscardBlank.h"
#include "ImageProcess_Public.h" #include "ImageProcess_Public.h"
CImageApplyDiscardBlank::CImageApplyDiscardBlank(double threshold, int edge, double devTh, double meanTh) CImageApplyDiscardBlank::CImageApplyDiscardBlank(double threshold, int edge, double devTh, double meanTh, int dilate)
: m_threshold(threshold) : m_threshold(threshold)
, m_edge(edge) , m_edge(edge)
, m_devTh(devTh) , m_devTh(devTh)
, m_meanTh(meanTh) , m_meanTh(meanTh)
, m_dilate(dilate)
{ {
} }
@ -15,7 +16,7 @@ CImageApplyDiscardBlank::~CImageApplyDiscardBlank(void)
void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side) void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side)
{ {
if (apply(pDib, m_threshold, m_edge, m_devTh, m_meanTh)) if (apply(pDib, m_threshold, m_edge, m_devTh, m_meanTh, m_dilate))
pDib.release(); pDib.release();
} }
@ -32,35 +33,46 @@ void CImageApplyDiscardBlank::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
} }
} }
bool scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2) bool maxMinCompare(const cv::Mat& img, const cv::Mat& mask, double devTh, double bgc)
{
for (int i = 0; i < 3; i++)
if (val1[i] > val2[i])
return false;
return true;
}
bool maxMinCompare(const cv::Mat& img, const cv::Mat& mask, double devTh, double meanTh)
{ {
double min, max; double min, max;
cv::minMaxLoc(img, &min, &max, 0, 0, mask); cv::minMaxLoc(img, &min, &max, 0, 0, mask);
if (cv::mean(img, mask)[0] < meanTh)
return false; return abs(max - bgc) < devTh && abs(min - bgc) < devTh;
return (max - min) < devTh;
} }
bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int edge, double devTh, double meanTh) static int a = 0;
bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int edge, double devTh, double meanTh, int dilate)
{ {
if (pDib.empty()) if (pDib.empty())
return true; return true;
cv::Mat img_resize; double resizeScale = 1.0;
cv::resize(pDib, img_resize, cv::Size(), 0.2, 0.2); while ((pDib.cols * resizeScale > 500) && (pDib.rows * resizeScale > 500))
resizeScale /= 2;
cv::Mat img_resize;
cv::resize(pDib, img_resize, cv::Size(), resizeScale, resizeScale, cv::INTER_LINEAR);
//cv::dilate(img_resize, img_resize, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(dilate, dilate)));
cv::blur(img_resize, img_resize, cv::Size(dilate, dilate));
cv::Scalar bgc = hg::getBackGroundColor(img_resize, cv::Mat(), 20);
if (pDib.channels() == 3)
if ((bgc[0] + bgc[1] + bgc[2]) < meanTh * 3)
return false;
if (pDib.channels() == 1)
if (bgc[0] < meanTh )
return false;
//cv::imwrite(std::to_string(a) + "r.jpg", img_resize);
cv::Mat threshold_img; cv::Mat threshold_img;
if (img_resize.channels() == 3) if (img_resize.channels() == 3)
{
cv::cvtColor(img_resize, threshold_img, cv::COLOR_BGR2GRAY); cv::cvtColor(img_resize, threshold_img, cv::COLOR_BGR2GRAY);
cv::threshold(img_resize.channels() == 3 ? threshold_img : img_resize, threshold_img, threshold, 255, cv::THRESH_BINARY); cv::threshold(threshold_img, threshold_img, threshold, 255, cv::THRESH_BINARY);
}
else
cv::threshold(img_resize, threshold_img, threshold, 255, cv::THRESH_BINARY);
std::vector<std::vector<cv::Point>> contours; std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> h1; std::vector<cv::Vec4i> h1;
@ -72,21 +84,20 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
contour.push_back(p); contour.push_back(p);
cv::RotatedRect rect = hg::getBoundingRect(contour); cv::RotatedRect rect = hg::getBoundingRect(contour);
rect.size = cv::Size2f(rect.size.width - edge / 2.5, rect.size.height - edge / 2.5); rect.size = cv::Size2f(rect.size.width - edge * resizeScale * 2, rect.size.height - edge * resizeScale * 2);
cv::Point2f box[4]; cv::Point2f box[4];
rect.points(box); rect.points(box);
contour.clear(); contour.clear();
contours.clear(); contours.clear();
for (size_t i = 0; i < 4; i++) for (size_t i = 0; i < 4; i++)
contour.push_back(box[i]); contour.push_back(box[i]);
contours.push_back(contour); contours.push_back(contour);
cv::Mat mask = cv::Mat::zeros(img_resize.size(), CV_8UC1); cv::Mat mask = cv::Mat::zeros(img_resize.size(), CV_8UC1);
hg::fillPolys(mask, contours, cv::Scalar::all(255)); hg::fillPolys(mask, contours, cv::Scalar::all(255));
int kSize = (devTh / 20) / 2 * 2 + 1; //cv::imwrite(std::to_string(a) + "m.jpg", mask);
if (kSize > 1) a++;
cv::blur(img_resize, img_resize, cv::Size(kSize, kSize));
bool b = true; bool b = true;
if (img_resize.channels() == 3) if (img_resize.channels() == 3)
{ {
@ -94,23 +105,11 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
cv::split(img_resize, bgr); cv::split(img_resize, bgr);
for (size_t i = 0; i < 3; i++) for (size_t i = 0; i < 3; i++)
{ {
b &= maxMinCompare(bgr[i], mask, devTh, meanTh); b &= maxMinCompare(bgr[i], mask, devTh, bgc[i]);
if (!b) break; if (!b) break;
} }
} }
else else
b &= maxMinCompare(img_resize, mask, devTh, meanTh); b &= maxMinCompare(img_resize, mask, devTh, bgc[0]);
/*
if (b)
{
cv::imwrite("¿Õ°×Ò³/img1/" + std::to_string(index) + ".bmp", img_resize);
cv::imwrite("¿Õ°×Ò³/mask1/" + std::to_string(index) + ".bmp", mask);
}
else
{
cv::imwrite("¿Õ°×Ò³/img2/" + std::to_string(index) + ".bmp", img_resize);
cv::imwrite("¿Õ°×Ò³/mask2/" + std::to_string(index) + ".bmp", mask);
}*/
return b; return b;
} }

View File

@ -5,20 +5,30 @@
* *
* 2020/4/21 * 2020/4/21
* 2020/4/21 v1.0 * 2020/4/21 v1.0
2020/8/12 v1.1 setIntensity和setMinAreaisNormal标识位setIntensity的设置范围[2, 20][1, 100] 2020/8/12 v1.1 setIntensity和setMinAreaisNormal标识位setIntensity的设置范围[2, 20][1, 100]
2020/8/25 v1.1.1 10020 2020/8/25 v1.1.1 10020
2020/10/16 v1.2 便 2020/10/16 v1.2 便
2020/10/19 v1.2.1 BUG 2020/10/19 v1.2.1 BUG
2021/04/13 v1.3.0 / 2021/04/13 v1.3.0 /
2021/08/12 v1.3.1 opencv版本导致计算结果存在差异的代码 2021/08/12 v1.3.1 opencv版本导致计算结果存在差异的代码
2021/12/14 v1.3.2 2021/12/14 v1.3.2
2021/12/15 v1.3.3 2021/12/15 v1.3.3
2021/12/17 v1.3.4 2021/12/17 v1.3.4
2022/09/07 v1.3.5 BUG 2022/09/07 v1.3.5 BUG
2022/09/19 v1.4 2022/09/19 v1.4
2022/09/19 v1.4.1 2022/09/19 v1.4.1
2022/11/18 v1.4.2 2022/11/18 v1.4.2
* v1.4.2 2022/11/29 v1.5
2022/12/03 v1.5.1
2023/10/12 v1.6 JEPG文件大小判断是否为空白页
2023/10/20 v1.6.1 JPEG文件大小判断空白页
2023/10/30 v1.7 JPEG文件大小判断空白页的算法接口
2023/11/04 v1.7.1 PNG二值化文件大小判断空白页的选项
2023/12/01 v1.8 JPEG/PNG文件大小判断空白页方案
2023/12/04 v1.9
2023/12/05 v1.9.1
2023/12/08 v1.10 mask精度bug
* v1.10
* ==================================================== * ====================================================
*/ */
@ -31,17 +41,16 @@
class GIMGPROC_LIBRARY_API CImageApplyDiscardBlank : public CImageApply class GIMGPROC_LIBRARY_API CImageApplyDiscardBlank : public CImageApply
{ {
public: public:
/// <summary> /// <summary>
/// 空白页识别 /// 空白页识别
/// </summary> /// </summary>
/// <param name="pDib">原图</param> /// <param name="pDib">原图</param>
/// <param name="threshold">轮廓阈值</param> /// <param name="threshold">轮廓阈值。取值范围[0, 255]</param>
/// <param name="edge">边缘缩进</param> /// <param name="edge">边缘缩进。取值范围[0, +∞]</param>
/// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。</param> /// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。取值范围[0, +∞]</param>
/// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页。</param> /// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页(当为0时纯色文稿底色不作为判定条件当为255时纯色文稿均为非空白页)取值范围[0, 255]</param>
/// <returns></returns> /// <param name="dilate">忽略纸张杂点。取值3、5、7、9...</param>
CImageApplyDiscardBlank(double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200); CImageApplyDiscardBlank(double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 0, int dilate = 3);
virtual ~CImageApplyDiscardBlank(void); virtual ~CImageApplyDiscardBlank(void);
@ -50,21 +59,23 @@ public:
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide); virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
/// <summary> /// <summary>
/// 空白页识别 /// 空白页识别。根据图像内容进行识别。
/// </summary> /// </summary>
/// <param name="pDib">原图</param> /// <param name="pDib">原图</param>
/// <param name="threshold">轮廓阈值</param> /// <param name="threshold">轮廓阈值</param>
/// <param name="edge">边缘缩进</param> /// <param name="edge">边缘缩进</param>
/// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。</param> /// <param name="devTh">笔迹判定阈值。该阈值越低,越容易判定存在笔迹。</param>
/// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页。</param> /// <param name="meanTh">文稿底色阈值。低于该阈值的文稿底色,直接视为非空白页。</param>
/// <returns></returns> /// <param name="dilate">忽略纸张杂点。≤1时不生效值越大越容易忽略杂点</param>
static bool apply(const cv::Mat& pDib, double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200); /// <returns>true为空白页false为非空白页</returns>
static bool apply(const cv::Mat& pDib, double threshold = 40, int edge = 50, double devTh = 30, double meanTh = 200, int dilate = 3);
private: private:
double m_threshold; double m_threshold;
int m_edge; int m_edge;
double m_devTh; double m_devTh;
double m_meanTh; double m_meanTh;
int m_dilate;
}; };
#endif // !IMAGE_APPLY_DISCARD_BLANK_H #endif // !IMAGE_APPLY_DISCARD_BLANK_H

View File

@ -1,17 +1,11 @@
#include "ImageApplyFadeBackGroundColor.h" #include "ImageApplyFadeBackGroundColor.h"
#include "ImageProcess_Public.h"
CImageApplyFadeBackGroudColor::CImageApplyFadeBackGroudColor(int threshold, int offset, int range) CImageApplyFadeBackGroudColor::CImageApplyFadeBackGroudColor(int threshold, int offset, int range)
: m_threshold(threshold) : m_threshold(threshold)
, m_offset(offset) , m_offset(offset)
, m_range(range) , m_range(range)
{ {
memset(m_table1, 255, 768);
memset(m_table1, 0, m_threshold * 3);
memset(m_table2, 255, 256 * 3);
for (size_t i = 0; i < 256; i++)
m_table2[i] = i;
} }
CImageApplyFadeBackGroudColor::~CImageApplyFadeBackGroudColor() CImageApplyFadeBackGroudColor::~CImageApplyFadeBackGroudColor()
@ -48,98 +42,33 @@ void CImageApplyFadeBackGroudColor::apply(cv::Mat& pDib, int side)
cv::add(pDib, cv::Scalar::all(255 + m_offset) - mean_bgr, pDib, mask); cv::add(pDib, cv::Scalar::all(255 + m_offset) - mean_bgr, pDib, mask);
#else #else
#if 0
fadeBackground(pDib.data, pDib.cols, pDib.rows, pDib.step, m_threshold, m_offset, m_range); fadeBackground(pDib.data, pDib.cols, pDib.rows, pDib.step, m_threshold, m_offset, m_range);
#else
fadeBackground(pDib, m_threshold, m_offset, m_range);
#endif
#endif #endif
} }
/// <summary> void CImageApplyFadeBackGroudColor::fadeBackground(cv::Mat& image, int threshold, int offset, int range)
/// 除文稿底色算法仅支持24位图像
/// </summary>
/// <param name="data">图像数据头指针</param>
/// <param name="bytesPerLine">每行数据大小</param>
/// <param name="height">图像高度</param>
/// <param name="threshold">阈值参考值为100</param>
/// <param name="offset">文稿底色增亮偏移量默认为0。值越大背景越白反之越暗</param>
void CImageApplyFadeBackGroudColor::fadeBackground(unsigned char* data, int width, int height, int bytesPerLine, int threshold, int offset, int range)
{ {
memset(m_table1, 255, 768); cv::Mat resizeMat;
memset(m_table1, 0, threshold * 3); cv::resize(image, resizeMat, cv::Size(200, 200));
memset(m_table2, 255, 256 * 3); cv::Mat mask;
cv::cvtColor(resizeMat, mask, cv::COLOR_BGR2GRAY);
cv::threshold(mask, mask, threshold, 255, cv::THRESH_BINARY);
for (uint i = 0; i < 256; i++) cv::Scalar bgc = hg::getBackGroundColor(resizeMat, mask, threshold);
m_table2[i] = i;
int hist_bgr[3][256] = { 0 }; std::vector<int> low, up;
for (size_t i = 0; i < 3; i++)
unsigned char* mask = new unsigned char[width * height];
unsigned char* ptr_data = data;
unsigned char* ptr_mask = mask;
unsigned char b = 0;
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width)
for (uint j = 0, x = 0; j < width; j++, x += 3)
{
b = m_table1[ptr_data[x] + ptr_data[x + 1] + ptr_data[x + 2]];
ptr_mask[j] = b;
for (uint k = 0; k < 3; k++)
hist_bgr[k][ptr_data[x + k] & b]++;
}
int max_vals[3] = { 0 };
int max_indexes[3] = { 0 };
for (uint i = 1; i < 256; i++)
for (uint j = 0; j < 3; j++)
if (hist_bgr[j][i] > max_vals[j])
{
max_vals[j] = hist_bgr[j][i];
max_indexes[j] = i;
}
uchar table_rgb[3][256] = { 0 };
for (uint i = 0; i < 3; i++)
{ {
int start = cv::max(max_indexes[i] - range, 0); low.push_back(cv::max((int)bgc[i] - range, 0));
int end = cv::min(max_indexes[i] + range, 255); up.push_back(cv::min((int)bgc[i] + range, 255));
memset(table_rgb[i] + start, 255, cv::min(end - start + 1, 256 - start));
} }
ptr_data = data; cv::inRange(image, low, up, mask);
ptr_mask = mask; cv::add(image, cv::Scalar::all(offset), image, mask);
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width)
for (uint j = 0, x = 0; j < width; j++, x += 3)
ptr_mask[j] &= table_rgb[0][ptr_data[x]] & table_rgb[1][ptr_data[x + 1]] & table_rgb[2][ptr_data[x + 2]];
unsigned char offset_rgb[3];
for (uint i = 0; i < 3; i++)
offset_rgb[i] = 255 + offset - max_indexes[i];
#if 1
ptr_data = data;
ptr_mask = mask;
for (uint i = 0; i < height; i++, ptr_data += bytesPerLine, ptr_mask += width)
for (uint j = 0, x = 0; j < width; j++, x += 3)
for (uint k = 0; k < 3; k++)
ptr_data[x + k] = m_table2[(int)ptr_data[x + k] + (offset_rgb[k] & ptr_mask[j])];
#else
for (uint c = 0; c < 3; c++)
{
ptr_data = data + c;
ptr_mask = mask;
for (uint y = 0; y < height; y++)
{
int ptr_x = 0;
for (uint x = 0; x < width; x++)
{
ptr_data[ptr_x] = m_table2[(int)ptr_data[ptr_x] + (offset_rgb[c] & ptr_mask[x])];
ptr_x += 3;
}
ptr_data += bytesPerLine;
ptr_mask += width;
}
}
#endif
delete[] mask;
} }
void CImageApplyFadeBackGroudColor::apply(std::vector<cv::Mat>& mats, bool isTwoSide) void CImageApplyFadeBackGroudColor::apply(std::vector<cv::Mat>& mats, bool isTwoSide)

View File

@ -14,7 +14,9 @@
* 2021/10/29 v3.3 range参数 * 2021/10/29 v3.3 range参数
* 2022/03/08 v3.4 BUG * 2022/03/08 v3.4 BUG
* 2022/10/22 v3.5 使opencv ROI的内存机制 * 2022/10/22 v3.5 使opencv ROI的内存机制
* v3.5 * 2023/11/22 v3.6 BUG
* 2023/12/01 v3.7
* v3.7
* ==================================================== * ====================================================
*/ */
@ -25,7 +27,6 @@
#include "ImageApply.h" #include "ImageApply.h"
class CImageApplyAdjustColors;
class GIMGPROC_LIBRARY_API CImageApplyFadeBackGroudColor : public CImageApply class GIMGPROC_LIBRARY_API CImageApplyFadeBackGroudColor : public CImageApply
{ {
public: public:
@ -42,25 +43,20 @@ public:
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide); virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
private: private:
/// <summary> /// <summary>
/// 除文稿底色算法仅支持24位图像 /// 除文稿底色算法仅支持24位图像
/// </summary> /// </summary>
/// <param name="data">图像数据头指针</param> /// <param name="image">图像</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <param name="bytesPerLine">每行数据大小</param>
/// <param name="threshold">阈值。区分文稿和黑色背景。取值范围[0, 255],参考值为100</param> /// <param name="threshold">阈值。区分文稿和黑色背景。取值范围[0, 255],参考值为100</param>
/// <param name="offset">文稿底色增亮偏移量默认为0。值越大背景越白反之越暗</param> /// <param name="offset">文稿底色增亮偏移量默认为0。值越大背景越白反之越暗</param>
/// <param name="range">背景色彩的浮动范围。要求大于等于1。值越大范围越大更多的色彩被判定为底色并除色。参考值40</param> /// <param name="range">背景色彩的浮动范围。要求大于等于1。值越大范围越大更多的色彩被判定为底色并除色。参考值40</param>
void fadeBackground(unsigned char* data, int width, int height, int bytesPerLine, int threshold, int offset, int range); void fadeBackground(cv::Mat& image, int threshold, int offset, int range);
private: private:
int m_threshold; int m_threshold;
int m_offset; int m_offset;
int m_range; int m_range;
uchar m_table1[768];
uchar m_table2[768];
uchar m_table_rgb[3][256];
}; };
#endif // !IMAGE_APPLY_FADE_BACKGROUND_COLOR_H #endif // !IMAGE_APPLY_FADE_BACKGROUND_COLOR_H

View File

@ -1,18 +1,36 @@
#include "ImageApplyHSVCorrect.h" #include "ImageApplyHSVCorrect.h"
#include <omp.h> #include <omp.h>
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr) CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr, uint alpha)
: m_table(new uint[256 * 256 * 256]) : m_table(new uint[256 * 256 * 256])
{ {
initLUT(); initLUT();
uint temp;
switch (mode) switch (mode)
{ {
case CImageApplyHSVCorrect::Red_Removal: case CImageApplyHSVCorrect::Red_Removal:
set_HSV_value(std::pair<uchar, uchar>(0, 63), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor); set_HSV_value(std::pair<uchar, uchar>(0, 10), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
set_HSV_value(std::pair<uchar, uchar>(200, 255), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor); set_HSV_value(std::pair<uchar, uchar>(200, 255), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
break; break;
case CImageApplyHSVCorrect::LowSaturation_Removal: case CImageApplyHSVCorrect::LowSaturation_Removal:
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 255), bgr, cvtColor); if (alpha < 0)
temp = 35;
else
temp = alpha;
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, temp), std::pair<uchar, uchar>(0, 255), bgr, cvtColor);
break;
case CImageApplyHSVCorrect::FXB_Color_Cast:
set_HSV_value(std::pair<uchar, uchar>(45, 105), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(180, 235), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 50), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
break;
case CImageApplyHSVCorrect::LM_Color_Cast:
set_HSV_value(std::pair<uchar, uchar>(45, 105), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(180, 235), std::pair<uchar, uchar>(0, 100), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
set_HSV_value(std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 60), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
break;
case CImageApplyHSVCorrect::RESERVE_RED:
set_HSV_value(std::pair<uchar, uchar>(45, 220), std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 255), 0x00FFFFFF, true);
break; break;
default: default:
break; break;
@ -149,7 +167,7 @@ void CImageApplyHSVCorrect::RGB_2_HSV_full(int r, int g, int b, uchar& h, uchar&
return; return;
} }
else else
s = static_cast<uchar>(delta * 255 / maxx); s = delta;
if (r == maxx) if (r == maxx)
_h = static_cast<float>(g - b) / static_cast<float>(delta); _h = static_cast<float>(g - b) / static_cast<float>(delta);

View File

@ -11,7 +11,12 @@
v1.4 2022/04/22 Deafault和LowSaturation_Removal v1.4 2022/04/22 Deafault和LowSaturation_Removal
v1.4.1 2022/04/25 访 v1.4.1 2022/04/25 访
v1.4.2 2022/06/09 v1.4.2 2022/06/09
* v1.4.2 v1.5 2022/08/22 alpha
v1.5.1 2022/09/23
v1.5.2 2022/10/26 鹿
v1.5.3 2023/03/22
v1.5.4 2023/12/01 H范围
* v1.5.4
* *
* ==================================================== * ====================================================
*/ */
@ -26,17 +31,21 @@ class GIMGPROC_LIBRARY_API CImageApplyHSVCorrect : public CImageApply
public: public:
enum CorrectOption enum CorrectOption
{ {
Deafault, //默认,无任何除色效果 Default, //默认,无任何除色效果
LowSaturation_Removal, //除掉低饱和度像素 LowSaturation_Removal, //除掉低饱和度像素
Red_Removal //除掉红色。红色定义H:[0, 85][170, 255],S:[10, 255],V:[120,255] Red_Removal, //除掉红色。红色定义H:[0, 85][170, 255],S:[10, 255],V:[120,255]
FXB_Color_Cast, //风向标消除偏色
LM_Color_Cast, //鹿鸣消除偏色
RESERVE_RED //保留红色像素
}; };
public: public:
/* /*
* mode [in]: * mode [in]:
* cvtColor [in]:使使true为灰度值false为默认值 * cvtColor [in]:使使true为灰度值false为默认值
* bgr:[in] uint表示BGR值B在低位R在高位cvtGray false时生效) * bgr [in] uint表示BGR值B在低位R在高位cvtGray false时生效)
* alpha [int] LowSaturation_Removal模式的强度alpha为负时[0, 35]alpha为非负时[0, alpha]
*/ */
CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Deafault, bool cvtColor = false, uint bgr = 0x00FFFFFF); CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Default, bool cvtColor = false, uint bgr = 0x00FFFFFF, uint alpha = -1);
virtual ~CImageApplyHSVCorrect(); virtual ~CImageApplyHSVCorrect();

View File

@ -32,4 +32,5 @@
#include "ImageApplySplit.h" #include "ImageApplySplit.h"
#include "CISTestImageProcess.h" #include "CISTestImageProcess.h"
#include "ImageApplyColorCastCorrect.h" #include "ImageApplyColorCastCorrect.h"
#include "LineContinuityDetection.h"
#endif #endif

View File

@ -1,10 +1,7 @@
#include "ImageApplyOutHole.h" #include "ImageApplyOutHole.h"
#include "ImageProcess_Public.h" #include "ImageProcess_Public.h"
//#include <QDebug>
#ifdef LOG //#define DRAW_PIC
#include "Device/filetools.h"
#endif // LOG
CImageApplyOutHole::CImageApplyOutHole(void) CImageApplyOutHole::CImageApplyOutHole(void)
: CImageApply() : CImageApply()
@ -32,10 +29,24 @@ void CImageApplyOutHole::apply(cv::Mat& pDib, int side)
(void)side; (void)side;
} }
#define MIN_CONTOUR_SIZE 10 void CImageApplyOutHole::dilateContour(std::vector<cv::Point>& contour, int distance)
{
cv::Moments mu = cv::moments(contour);
cv::Point2f center(mu.m10 / mu.m00, mu.m01 / mu.m00), p_temp;
for (size_t i = 0; i < contour.size(); i++)
{
p_temp = contour[i];
double dis = cv::sqrt(cv::pow(p_temp.x - center.x, 2) + cv::pow(p_temp.y - center.y, 2));
double scale = dis / (distance + dis);
double x = (p_temp.x - center.x) / scale + center.x;
double y = (p_temp.y - center.y) / scale + center.y;
contour[i] = cv::Point(x, y);
}
}
#define RESIZE_FIXED_WIDTH 2448.0 #define RESIZE_FIXED_WIDTH 2448.0
#define LINE_WIDTH 18 #define LINE_WIDTH 18
#define DILATE_SIZE 16
void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide) void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{ {
#ifdef LOG #ifdef LOG
@ -73,17 +84,44 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
back = mats[1]; back = mats[1];
} }
cv::Mat thumbnail;
cv::resize(front, thumbnail, cv::Size(200, 200));
cv::Scalar color_front = hg::getBackGroundColor(thumbnail, cv::Mat(), 20);
if (color_front[1] == 0)
if (color_front[0] < m_threshold)
return;
if (color_front[1] != 0)
if ((color_front[0] + color_front[1] + color_front[2]) < m_threshold * 3)
return;
cv::resize(back, thumbnail, cv::Size(200, 200));
cv::Scalar color_back = hg::getBackGroundColor(thumbnail, cv::Mat(), 20);
if (color_back[1] == 0)
if (color_back[0] < m_threshold)
return;
if (color_back[1] != 0)
if ((color_back[0] + color_back[1] + color_back[2]) < m_threshold * 3)
return;
cv::Mat front_thre, back_thre; cv::Mat front_thre, back_thre;
hg::threshold_Mat(front, front_thre, m_threshold); hg::threshold_Mat(front, front_thre, m_threshold);
hg::threshold_Mat(back, back_thre, m_threshold); hg::threshold_Mat(back, back_thre, m_threshold);
//cv::imwrite("front_thre.jpg", front_thre);
//cv::imwrite("back_thre.jpg", back_thre);
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(5 * resize_scale, 1)); #ifdef DRAW_PIC
cv::imwrite("front_thre.jpg", front_thre);
cv::imwrite("back_thre.jpg", back_thre);
#endif
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_borderSize * resize_scale / 4, 1));
cv::morphologyEx(front_thre, front_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); cv::morphologyEx(front_thre, front_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
cv::morphologyEx(back_thre, back_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0)); cv::morphologyEx(back_thre, back_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
//cv::imwrite("front_thre2.jpg", front_thre);
//cv::imwrite("back_thre2.jpg", back_thre); #ifdef DRAW_PIC
cv::imwrite("front_thre2.jpg", front_thre);
cv::imwrite("back_thre2.jpg", back_thre);
#endif
//反面二值化图像水平翻转 //反面二值化图像水平翻转
cv::flip(back_thre, back_thre, 1); //1:Horizontal cv::flip(back_thre, back_thre, 1); //1:Horizontal
@ -94,23 +132,7 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
hg::findContours(front_thre.clone(), contours_front, b1_front, cv::RETR_CCOMP); hg::findContours(front_thre.clone(), contours_front, b1_front, cv::RETR_CCOMP);
hg::findContours(back_thre.clone(), contours_back, b1_back, cv::RETR_CCOMP); hg::findContours(back_thre.clone(), contours_back, b1_back, cv::RETR_CCOMP);
//提取正反面图像最大轮廓 ////提取正反面图像最大轮廓
for (size_t i = 0; i < contours_front.size(); i++)
if (contours_front[i].size() < MIN_CONTOUR_SIZE)
{
contours_front.erase(contours_front.begin() + i);
b1_front.erase(b1_front.begin() + i);
i--;
}
for (size_t i = 0; i < contours_back.size(); i++)
if (contours_back[i].size() < MIN_CONTOUR_SIZE)
{
contours_back.erase(contours_back.begin() + i);
b1_back.erase(b1_back.begin() + i);
i--;
}
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front); std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back); std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
@ -132,26 +154,37 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分 cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分 cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
//cv::imwrite("roiMat_front.jpg", roiMat_front);
//cv::imwrite("roiMat_back.jpg", roiMat_back); #ifdef DRAW_PIC
cv::imwrite("roiMat_front.jpg", roiMat_front);
cv::imwrite("roiMat_back.jpg", roiMat_back);
#endif
//正反面二值图像做或运算真正镂空区域保留0其他地方填充为255 //正反面二值图像做或运算真正镂空区域保留0其他地方填充为255
cv::Mat mask; cv::Mat mask;
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠 cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
//cv::imwrite("mask1.jpg", mask);
#ifdef DRAW_PIC
cv::imwrite("mask1.jpg", mask);
#endif
//二值图像重叠图像颜色取反,膨胀,提取轮廓 //二值图像重叠图像颜色取反,膨胀,提取轮廓
cv::bitwise_not(mask, mask); cv::bitwise_not(mask, mask);
//cv::imwrite("mask2.jpg", mask); //反色
#ifdef DRAW_PIC
cv::imwrite("mask2.jpg", mask); //反色
#endif
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连 //为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), LINE_WIDTH * resize_scale); //绘制纸张矩形边缘 cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), LINE_WIDTH * resize_scale); //绘制纸张矩形边缘
//cv::imwrite("mask3.jpg", mask);
//膨胀算法,增大孔洞连通区域面积 #ifdef DRAW_PIC
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(DILATE_SIZE * resize_scale, DILATE_SIZE * resize_scale)); cv::imwrite("mask3.jpg", mask);
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); #endif
//cv::imwrite("mask4.jpg", mask);
#ifdef DRAW_PIC
cv::imwrite("mask4.jpg", mask);
#endif
//提取重叠图像轮廓 //提取重叠图像轮廓
std::vector<std::vector<cv::Point>> contours_mask; std::vector<std::vector<cv::Point>> contours_mask;
@ -165,7 +198,6 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
for (size_t j = 0; j < hole_contours[i].size(); j++) for (size_t j = 0; j < hole_contours[i].size(); j++)
hole_contours[i][j] /= resize_scale; hole_contours[i][j] /= resize_scale;
cv::Scalar color = getBackGroudColor(front(roi_front), rrect_front.size.area());
roi_front.x /= resize_scale; roi_front.x /= resize_scale;
roi_front.y /= resize_scale; roi_front.y /= resize_scale;
roi_front.width /= resize_scale; roi_front.width /= resize_scale;
@ -173,16 +205,17 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
for (size_t i = 0; i < hole_contours.size(); i++) for (size_t i = 0; i < hole_contours.size(); i++)
{ {
std::vector<std::vector<cv::Point>> contourss_temp; std::vector<std::vector<cv::Point>> contourss_temp;
dilateContour(hole_contours[i], cv::max(m_borderSize / 2, 5.0f));
contourss_temp.push_back(hole_contours[i]); contourss_temp.push_back(hole_contours[i]);
cv::Mat front_temp = mats[0](roi_front); cv::Mat front_temp = mats[0](roi_front);
hg::fillPolys(front_temp, contourss_temp, color); hg::fillPolys(front_temp, contourss_temp, color_front);
} }
if (isTwoSide) if (isTwoSide)
{ {
int width_ = roi_back.width; int width_ = roi_back.width;
roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转所以现在ROI也要进行相应翻转 roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转所以现在ROI也要进行相应翻转
color = getBackGroudColor(back(roi_back), rrect_back.size.area());
roi_back.x /= resize_scale; roi_back.x /= resize_scale;
roi_back.y /= resize_scale; roi_back.y /= resize_scale;
roi_back.width /= resize_scale; roi_back.width /= resize_scale;
@ -200,9 +233,10 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
} }
std::vector<std::vector<cv::Point>> contours_temp; std::vector<std::vector<cv::Point>> contours_temp;
dilateContour(hole_contour, cv::max(m_borderSize / 2, 5.0f));
contours_temp.push_back(hole_contour); contours_temp.push_back(hole_contour);
cv::Mat back_temp = mats[1](roi_back); cv::Mat back_temp = mats[1](roi_back);
hg::fillPolys(back_temp, contours_temp, color); hg::fillPolys(back_temp, contours_temp, color_back);
} }
} }
#ifdef LOG #ifdef LOG
@ -337,81 +371,4 @@ std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<s
hole_contours.push_back(contours[i]); hole_contours.push_back(contours[i]);
} }
return hole_contours; return hole_contours;
}
cv::Scalar CImageApplyOutHole::getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> pixelPoints)
{
if (pixelPoints.empty()) return cv::Scalar(255, 255, 255);
int channels = image.channels();
int temp[3] = { 0 };
for (size_t i = 0, length = pixelPoints.size(); i < length; ++i)
{
int x = cv::min(cv::max(0, pixelPoints[i].x), image.cols - 1);
int y = cv::min(cv::max(0, pixelPoints[i].y), image.rows - 1);
const unsigned char* ptr = image.ptr(y, x);
for (int j = 0; j < channels; ++j)
temp[j] += ptr[j];
}
return cv::Scalar(temp[0] / static_cast<int>(pixelPoints.size()),
temp[1] / static_cast<int>(pixelPoints.size()),
temp[2] / static_cast<int>(pixelPoints.size()));
}
cv::Scalar CImageApplyOutHole::getBackGroudColor(const cv::Mat& image, int total)
{
if (image.channels() == 3)
{
cv::Mat image_bgr[3];
cv::split(image, image_bgr);
uchar bgr[3];
for (size_t i = 0; i < 3; i++)
bgr[i] = getBackGroudChannelMean(image_bgr[i], total);
return cv::Scalar(bgr[0], bgr[1], bgr[2]);
}
else
return cv::Scalar::all(getBackGroudChannelMean(image, total));
}
uchar CImageApplyOutHole::getBackGroudChannelMean(const cv::Mat& gray, int total)
{
cv::Mat image_clone;
cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25);
int threnshold = total / 32;
int channels[] = { 0 };
int nHistSize[] = { 256 };
float range[] = { 0, 256 };
const float* fHistRanges[] = { range };
cv::Mat hist;
cv::calcHist(&image_clone, 1, channels, cv::Mat(), hist, 1, nHistSize, fHistRanges, true, false);
int hist_array[256];
for (int i = 0; i < 256; i++)
hist_array[i] = hist.at<float>(i, 0);
int length = 1;
const int length_max = 255;
while (length < length_max)
{
for (size_t i = 1; i < 256 - length; i++)
{
int count = 0;
uint pixSum = 0;
for (size_t j = 0; j < length; j++)
{
count += hist_array[j + i];
pixSum += hist_array[j + i] * (i + j);
}
if (count >= threnshold)
return pixSum / count;
}
length++;
}
return 255;
} }

View File

@ -4,28 +4,33 @@
* *
* *
* 2020/11/21 * 2020/11/21
* 2020/05/12 v1.0 * v1.0 2020/05/12
* 2020/11/17 v1.1 * v1.1 2020/11/17
* 2021/09/06 v1.2 50100 * v1.2 2021/09/06 50100
* 2021/11/03 v1.3 10穿 * v1.3 2021/11/03 10穿
* 2021/11/04 v1.4 5 * v1.4 2021/11/04 5
* 2021/11/17 v1.5 opencv版本导致的BUG * v1.5 2021/11/17 opencv版本导致的BUG
* 2022/04/18 v1.6 BUG * v1.6 2022/04/18 BUG
* 2022/05/04 v1.6.1 * v1.6.1 2022/05/04
* 2022/07/16 v1.6.2 BUG * v1.6.2 2022/07/16 BUG
* 2022/07/18 v1.6.3 mask的一些逻辑错误 * v1.6.3 2022/07/18 mask的一些逻辑错误
* 2022/07/18 v1.7 BUGborderSize逻辑,穿[borderSize, borderSize * 6] * v1.7 2022/07/18 BUGborderSize逻辑,穿[borderSize, borderSize * 6]
* 2022/07/22 v1.7.1 BUG * v1.7.1 2022/07/22 BUG
* 2022/08/02 v1.7.2 * v1.7.2 2022/08/02
* 2022/09/07 v1.8 * v1.8 2022/09/07
* 2022/09/09 v1.8.1 BUG * v1.8.1 2022/09/09 BUG
* 2022/09/15 v1.8.2 BUG * v1.8.2 2022/09/15 BUG
* 2022/09/15 v1.8.3 * v1.8.3 2022/09/15
* 2022/09/15 v1.8.4 BUG * v1.8.4 2022/09/15 BUG
* 2022/09/16 v1.9 * v1.9 2022/09/16
* 2022/09/16 v1.9.1 * v1.9.1 2022/09/16
* 2022/11/17 v1.9.2 BUG * v1.9.2 2022/11/17 BUG
* v1.9.2 * v1.9.3 2023/05/16 BUG
* v1.10 2023/11/18
* v1.10.1 2023/11/28 kSize根据borderSize调整
* v1.11 2023/12/02 稿
* v1.11.1 2023/12/08 稿<;
* v1.11.1
* ==================================================== * ====================================================
*/ */
@ -74,11 +79,7 @@ private:
std::vector<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& m, cv::RotatedRect roi, std::vector<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& m, cv::RotatedRect roi,
cv::Vec4f edgeScale, float sideLengthLow); cv::Vec4f edgeScale, float sideLengthLow);
cv::Scalar getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> pixelPoints); void dilateContour(std::vector<cv::Point>& contour, int distance);
cv::Scalar getBackGroudColor(const cv::Mat& image, int total);
uchar getBackGroudChannelMean(const cv::Mat& gray, int total);
private: private:
float m_borderSize; float m_borderSize;

View File

@ -1,52 +1,65 @@
#include "ImageApplyRefuseInflow.h" #include "ImageApplyRefuseInflow.h"
#include "ImageApplyAdjustColors.h" #include "ImageProcess_Public.h"
CImageApplyRefuseInflow::CImageApplyRefuseInflow(int constrast) CImageApplyRefuseInflow::CImageApplyRefuseInflow(int threshold, int range)
: m_adjustColor(new CImageApplyAdjustColors(0, constrast, 1.0f)) : m_threshold(threshold)
, m_range(range)
{ {
} }
CImageApplyRefuseInflow::~CImageApplyRefuseInflow() CImageApplyRefuseInflow::~CImageApplyRefuseInflow()
{ {
delete m_adjustColor;
} }
void CImageApplyRefuseInflow::apply(cv::Mat& pDib, int side) void CImageApplyRefuseInflow::apply(cv::Mat& pDib, int side)
{ {
(void)side; if (pDib.channels() == 3)
#if 0 {
static unsigned char table_contrast[] = { cv::Mat resizeMat;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cv::resize(pDib, resizeMat, cv::Size(200, 200));
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cv::Mat mask;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cv::cvtColor(resizeMat, mask, cv::COLOR_BGR2GRAY);
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cv::threshold(mask, mask, m_threshold, 255, cv::THRESH_BINARY);
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cv::Scalar bgc = hg::getBackGroundColor(resizeMat, mask, m_threshold);
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, std::vector<int> low, up;
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, for (size_t i = 0; i < 3; i++)
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, {
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, low.push_back(cv::max((int)bgc[i] - m_range, 0));
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, up.push_back(cv::min((int)bgc[i] + m_range, 255));
50, 51, 52, 53, 54, 55, 56, 57, 198, 199, }
200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 217, 218, 219, cv::inRange(pDib, low, up, mask);
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, pDib = pDib.setTo(bgc, mask);
230, 231, 232, 233, 234, 235, 236, 237, 238, 239, }
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, else
250, 251, 252, 253, 254, 255, 255, 255, 255, 255, {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, cv::Mat resizeMat;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, cv::resize(pDib, resizeMat, cv::Size(200, 200));
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, cv::Mat mask;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, cv::threshold(resizeMat, mask, m_threshold, 255, cv::THRESH_BINARY);
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, cv::Mat hist;
255, 255, 255, 255, 255, 255 }; double min, max;
static cv::Mat mat_table(1, 256, CV_8UC1, table_contrast); cv::Point maxLoc;
cv::LUT(pDib, mat_table, pDib); float range[] = { 0, 256 };
#else const float* ranges = { range };
m_adjustColor->apply(pDib, side); int histSize = 256;
#endif cv::calcHist(&resizeMat, 1, 0, mask, hist, 1, &histSize, &ranges);
int index_max = 0;
int max_value = 0;
for (size_t j = m_threshold; j < 256; j++)
if (hist.at<float>(j) > max_value)
{
index_max = j;
max_value = hist.at<float>(j);
}
cv::inRange(pDib, cv::max(index_max - m_range, 0), cv::min(index_max + m_range, 255), mask);
pDib = pDib.setTo(cv::Scalar::all(index_max), mask);
}
} }
void CImageApplyRefuseInflow::apply(std::vector<cv::Mat>& mats, bool isTwoSide) void CImageApplyRefuseInflow::apply(std::vector<cv::Mat>& mats, bool isTwoSide)

View File

@ -6,7 +6,11 @@
* 2020/4/21 * 2020/4/21
* v1.0 2020/04/21 * v1.0 2020/04/21
* v1.1 2022/05/04 * v1.1 2022/05/04
* v1.1 * v2.0 2023/08/12
* v2.1 2023/10/20 BUG
* v3.0 2023/12/02 稿
* v3.1 2023/12/04
* v3.1
* ==================================================== * ====================================================
*/ */
@ -16,11 +20,16 @@
#include "ImageApply.h" #include "ImageApply.h"
class CImageApplyAdjustColors;
class GIMGPROC_LIBRARY_API CImageApplyRefuseInflow : public CImageApply class GIMGPROC_LIBRARY_API CImageApplyRefuseInflow : public CImageApply
{ {
public: public:
CImageApplyRefuseInflow(int constrast = 15);
/// <summary>
///
/// </summary>
/// <param name="threshod">背景阈值.取值范围[0, 255]</param>
/// <param name="range">文稿底色相近范围。取值范围[0, 255]</param>
CImageApplyRefuseInflow(int threshod = 20, int range = 40);
virtual ~CImageApplyRefuseInflow(); virtual ~CImageApplyRefuseInflow();
@ -29,6 +38,7 @@ public:
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide); virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
private: private:
CImageApplyAdjustColors* m_adjustColor; int m_threshold;
int m_range;
}; };
#endif // !IMAGE_APPLY_REFUSE_INFLOW_H #endif // !IMAGE_APPLY_REFUSE_INFLOW_H

View File

@ -18,46 +18,15 @@ std::vector<cv::Mat> ImageMultiOutputRed::apply(cv::Mat& pDib)
if (pDib.empty()) if (pDib.empty())
return retMats; return retMats;
retMats.push_back(pDib); retMats.push_back(pDib);
cv::Mat mat = FilterColor(pDib, m_channelIndex); filterColor(pDib, m_channelIndex);
if (!mat.empty()) retMats.push_back(pDib);
retMats.push_back(mat);
return retMats; return retMats;
} }
cv::Mat ImageMultiOutputRed::FilterColor(cv::Mat image, short channel) void ImageMultiOutputRed::filterColor(cv::Mat& image, short channel)
{ {
cv::Mat dstImage(image.rows, image.cols, CV_8UC1); if (image.channels() == 1)
int channels = image.channels(); return;
if (channel > channels - 1)
{
return cv::Mat();
}
if ((channel == 3) && (channels != 4) && (channels != 8))
{
return cv::Mat();
}
if (channels <= 4)
{
int srcOffset = image.step - image.cols * channels;
int dstOffset = dstImage.step - dstImage.cols;
unsigned char *src = image.data;
unsigned char *dst = dstImage.data;
src += channel;
for (int y = 0; y < image.rows; y++) cv::extractChannel(image, image, channel);
{
for (int x = 0; x < image.cols; x++, src += channels, dst++)
{
unsigned short pix = *src;
if (pix >= 130)
{
pix = 255;
}
*dst = pix;
}
src += srcOffset;
dst += dstOffset;
}
}
return dstImage;
} }

View File

@ -1,3 +1,15 @@
/*
* ====================================================
*
*
* 2023/12/02
* v1.0 2023/12/02
* v1.0
* ====================================================
*/
#ifndef IMAGE_MULTI_OUTPUT_RED_H #ifndef IMAGE_MULTI_OUTPUT_RED_H
#define IMAGE_MULTI_OUTPUT_RED_H #define IMAGE_MULTI_OUTPUT_RED_H
#include "IMulti.h" #include "IMulti.h"
@ -9,9 +21,9 @@ public:
ImageMultiOutputRed(short channelIndex); ImageMultiOutputRed(short channelIndex);
virtual ~ImageMultiOutputRed(void); virtual ~ImageMultiOutputRed(void);
virtual std::vector<cv::Mat> apply(cv::Mat& pDib) override; virtual std::vector<cv::Mat> apply(cv::Mat& pDib) override;
private:
void filterColor(cv::Mat& image, short channel);
private: private:
short m_channelIndex; short m_channelIndex;
cv::Mat FilterColor(cv::Mat image, short channel);
}; };
#endif //!IMAGE_MULTI_OUTPUT_RED_H #endif //!IMAGE_MULTI_OUTPUT_RED_H

View File

@ -1,4 +1,7 @@
#include "ImageProcess_Public.h" #include "ImageProcess_Public.h"
#include <opencv2/core/core_c.h>
#include <opencv2/core/types_c.h>
#include <opencv2/imgproc/imgproc_c.h>
namespace hg namespace hg
{ {
@ -150,14 +153,11 @@ namespace hg
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset) void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
{ {
#if CV_VERSION_REVISION <= 6
CvMat c_image = src;
#else
CvMat c_image; CvMat c_image;
c_image = cvMat(src.rows, src.cols, src.type(), src.data); c_image = cvMat(src.rows, src.cols, src.type(), src.data);
c_image.step = src.step[0]; c_image.step = src.step[0];
c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG); c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
#endif
cv::MemStorage storage(cvCreateMemStorage()); cv::MemStorage storage(cvCreateMemStorage());
CvSeq* _ccontours = nullptr; CvSeq* _ccontours = nullptr;
@ -205,6 +205,52 @@ namespace hg
storage.release(); storage.release();
} }
cv::Scalar getBackGroundColor(const cv::Mat& image, const cv::Mat& mask, int threshold)
{
float range[] = { 0, 256 };
const float* ranges = { range };
int histSize = 256;
cv::Scalar bgc;
if (image.channels() == 3)
{
cv::Mat mv[3];
cv::split(image, mv);
cv::Mat hist[3];
for (int i = 0; i < 3; i++)
{
cv::calcHist(&mv[i], 1, 0, mask, hist[i], 1, &histSize, &ranges);
int index_max = 0;
int max_value = 0;
for (size_t j = threshold; j < 256; j++)
if (hist[i].at<float>(j) > max_value)
{
index_max = j;
max_value = hist[i].at<float>(j);
}
bgc[i] = index_max;
}
}
else
{
cv::Mat hist;
cv::calcHist(&image, 1, 0, mask, hist, 1, &histSize, &ranges);
int index_max = 0;
int max_value = 0;
for (size_t j = threshold; j < 256; j++)
if (hist.at<float>(j) > max_value)
{
index_max = j;
max_value = hist.at<float>(j);
}
bgc = cv::Scalar::all(index_max);
}
return bgc;
}
cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour) cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour)
{ {
if (contour.empty()) return {}; if (contour.empty()) return {};
@ -302,8 +348,11 @@ namespace hg
return dst; return dst;
} }
#define DEFAULT_THRESHOLD 30
#define THRESHOLD_OFFSET 10
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre) void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre)
{ {
cv::Mat temp;
if (src.channels() == 3) if (src.channels() == 3)
{ {
#ifdef USE_ONENCL #ifdef USE_ONENCL
@ -312,13 +361,39 @@ namespace hg
else else
#endif #endif
{ {
cv::Mat gray = transforColor(src); //temp = transforColor(src);
cv::threshold(gray, dst, thre, 255, cv::THRESH_BINARY); cv::cvtColor(src, temp, cv::COLOR_BGR2GRAY);
gray.release();
} }
} }
else else
cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY); temp = src;
if (thre > 0)
cv::threshold(temp, dst, thre, 255, cv::THRESH_BINARY);
else
{
std::vector<int> unusual_cols;
std::vector<uchar> unusual_gray;
uchar* firstLine = temp.ptr<uchar>(0);
uchar* lastLine = temp.ptr<uchar>(temp.rows - 1);
uchar temp_gray;
for (size_t i = 0, length = temp.step; i < length; i++)
{
temp_gray = cv::min(firstLine[i], lastLine[i]);
if (temp_gray > DEFAULT_THRESHOLD)
{
unusual_cols.push_back(i);
unusual_gray.push_back(temp_gray);
}
}
cv::threshold(temp, dst, DEFAULT_THRESHOLD + THRESHOLD_OFFSET, 255, cv::THRESH_BINARY);
for (size_t i = 0; i < unusual_cols.size(); i++)
dst(cv::Rect(unusual_cols[i], 0, 1, temp.rows)) = 0;
}
} }
cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat) cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat)

View File

@ -5,9 +5,14 @@
* *
* 2020/4/21 * 2020/4/21
* 2020/4/21 * 2020/4/21
* 2021/07/12 v1.1 getBoundingRect中 angle > 90 * 2021/07/12 v1.1 getBoundingRect中 angle > 90
* 2021/07/22 v1.2 convexHull中BUG * 2021/07/22 v1.2 convexHull中BUG
* v1.2 * 2023/11/02 v1.3 threshold_Mat,thre<0
* 2023/12/01 v1.4 getBackGroundColor算法
* 2023/12/02 v1.4.1 getBackGroundColor增加threshold阈值
* 2023/12/04 v1.4.2 opencv版本接口
* 2023/12/05 v1.4.3 getBackGroundColor支持单通道图像背景色识别
* v1.4.3
* ==================================================== * ====================================================
*/ */
@ -55,6 +60,15 @@ namespace hg
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0)); int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
/// <summary>
/// 获取图片文稿底色
/// </summary>
/// <param name="image">图像,三通道</param>
/// <param name="mask">掩膜</param>
/// <param name="threshold">阈值,用于排除黑色背景</param>
/// <returns>文稿底色</returns>
cv::Scalar getBackGroundColor(const cv::Mat& image, const cv::Mat& mask = cv::Mat(), int threshold = 20);
/* /*
* *
* contour: * contour:
@ -90,7 +104,7 @@ namespace hg
* : src为彩色图像时 * : src为彩色图像时
* src: * src:
* dst: * dst:
* thre: * thre: thre < 0
*/ */
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre); void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre);

View File

@ -0,0 +1,141 @@
#include "LineContinuityDetection.h"
LineContinuityDetection::LineContinuityDetection()
{
}
bool LineContinuityDetection::isContinuous(const cv::Mat& image, double area_threshold)
{
cv::Mat thre;
if (image.channels() != 1)
{
cv::cvtColor(image, thre, cv::COLOR_BGR2GRAY);
cv::threshold(thre, thre, 127, 255, cv::THRESH_OTSU);
}
else
cv::threshold(image, thre, 127, 255, cv::THRESH_OTSU);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
myFindContours(thre, contours, hierarchy, cv::RETR_TREE);
return findBlock(contours, hierarchy, area_threshold);
}
void LineContinuityDetection::myFindContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
{
#if CV_VERSION_REVISION <= 6
CvMat c_image = src;
#else
CvMat c_image;
c_image = cvMat(src.rows, src.cols, src.type(), src.data);
c_image.step = src.step[0];
c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
#endif
cv::MemStorage storage(cvCreateMemStorage());
CvSeq* _ccontours = nullptr;
#if CV_VERSION_REVISION <= 6
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
#else
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y });
#endif
if (!_ccontours)
{
contours.clear();
return;
}
cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
size_t total = all_contours.size();
contours.resize(total);
cv::SeqIterator<CvSeq*> it = all_contours.begin();
for (size_t i = 0; i < total; i++, ++it)
{
CvSeq* c = *it;
reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
int count = c->total;
int* data = new int[static_cast<size_t>(count * 2)];
cvCvtSeqToArray(c, data);
for (int j = 0; j < count; j++)
{
contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
}
delete[] data;
}
hierarchy.resize(total);
it = all_contours.begin();
for (size_t i = 0; i < total; i++, ++it)
{
CvSeq* c = *it;
int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
}
storage.release();
}
bool LineContinuityDetection::findBlock(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy, double area_threshold)
{
if (contours.empty())
return false;
std::vector<cv::RotatedRect> rects;
for (size_t i = 0; i < contours.size(); i++)
{
cv::RotatedRect rect = minAreaRect(contours[i]);
rects.push_back(rect);
}
std::vector<int> max_index;
std::vector<float> max_area;
for (size_t i = 0; i < 5; i++)
{
max_index.push_back(0);
max_area.push_back(0);
}
for (size_t i = 0; i < rects.size(); i++)
{
float area = rects[i].size.area();
for (size_t j = 0; j < 5; j++)
{
if (area > max_area[j])
{
max_index.insert(max_index.begin() + j, i);
max_area.insert(max_area.begin() + j, area);
max_index.erase(max_index.begin() + 5);
max_area.erase(max_area.begin() + 5);
break;
}
}
}
for (size_t i = 1; i < 5; i++)
{
int child_count = 0;
int index_temp = hierarchy[max_index[i]][2];
if (index_temp < 0)
return false;
child_count++;
while (hierarchy[index_temp][0] != -1)
{
if (rects[index_temp].size.area() > area_threshold)
child_count++;
index_temp = hierarchy[index_temp][0];
}
if (child_count != 4)
return false;
}
return true;
}

View File

@ -0,0 +1,29 @@
#ifndef LINE_CONTINUITY_DETECTION_H
#define LINE_CONTINUITY_DETECTION_H
#include <opencv2/opencv.hpp>
class LineContinuityDetection
{
public:
LineContinuityDetection();
static bool isContinuous(const cv::Mat& image, double area_threshold = 100);
private:
/// <summary>
/// 获取连通区域轮廓
/// </summary>
/// <param name="src">源图像</param>
/// <param name="contours">结果轮廓集</param>
/// <param name="hierarchy">轮廓集的排序关系。与contours的数量对应受retr选项不同排序会有变化</param>
/// <param name="retr">轮廓集排序方式,默认为链式排序</param>
/// <param name="method">查找算法选择,默认为普通查找</param>
/// <param name="offset">查找起始点默认为0,0点</param>
static void myFindContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
static bool findBlock(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy, double area_threshold);
};
#endif //LINE_CONTINUITY_DETECTION_H

View File

@ -318,6 +318,7 @@
#define SCANNER_NAME_LSC_G42S "LANXUMSCAN G42S" #define SCANNER_NAME_LSC_G42S "LANXUMSCAN G42S"
#define SCANNER_NAME_LSC_G52S "LANXUMSCAN G52S" #define SCANNER_NAME_LSC_G52S "LANXUMSCAN G52S"
#define SCANNER_NAME_LSC_G62S "LANXUMSCAN G62S" #define SCANNER_NAME_LSC_G62S "LANXUMSCAN G62S"
#define SCANNER_NAME_LSC_G63S "LANXUMSCAN G63S"
#define SCANNER_NAME_LSC_G73S "LANXUMSCAN G73S" #define SCANNER_NAME_LSC_G73S "LANXUMSCAN G73S"
@ -334,7 +335,9 @@
#define SCANNER_NAME_CT_138 "CUMTENN CT-138" #define SCANNER_NAME_CT_138 "CUMTENN CT-138"
#define SCANNER_NAME_CT_238 "CUMTENN CT-238" #define SCANNER_NAME_CT_238 "CUMTENN CT-238"
#define SCANNER_NAME_ZJ_6500 "Microtek A3HG Scanner" #define SCANNER_NAME_ZJ_6570 "Microtek A3HG Scanner"
#define SCANNER_NAME_ZJ_8790 "Microtek A3ES Scanner"
#define SCANNER_NAME_ZJ_500DC "Microtek A3FZ Scanner"
#define SANNNER_NAME_ZG_Q7110 "Uniscan Q7 Series" #define SANNNER_NAME_ZG_Q7110 "Uniscan Q7 Series"
#define SANNNER_NAME_ZG_Q1070 "Uniscan Q1 Series" #define SANNNER_NAME_ZG_Q1070 "Uniscan Q1 Series"
@ -342,4 +345,4 @@
#define SANNER_NAME_DL_S3000 "DELI SCAN S3000-S3110" #define SANNER_NAME_DL_S3000 "DELI SCAN S3000-S3110"
#define SANNER_NAME_DL_S3400 "DELI SCAN S3000-S3400" #define SANNER_NAME_DL_S3400 "DELI SCAN S3000-S3400"
#define SANNER_NAME_DL_S2000 "DELI SCAN S2000-S2090" #define SANNER_NAME_DL_S2000 "DELI SCAN S2000-S2090"
#define SANNER_NAME_DL_DL9000 "DELI SCAN DL9000-DL9080" #define SANNER_NAME_DL_DL9000 "DELI SCAN DL9000-DL9080"

View File

@ -1,4 +1,4 @@
#include "common_setting.h" #include "common_setting.h"
#include "sane/sane_option_definitions.h" #include "sane/sane_option_definitions.h"
#include "hg_log.h" #include "hg_log.h"
@ -69,6 +69,7 @@ g_page[] =
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_SM), PAGE_DOUBLE}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_SM), PAGE_DOUBLE},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYTY), PAGE_OMIT_EMPTY}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYTY), PAGE_OMIT_EMPTY},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYFPZ), PAGE_OMIT_EMPTY_RECEIPT}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYFPZ), PAGE_OMIT_EMPTY_RECEIPT},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_TGKBYJYWJDX), PAGE_OMIT_EMPTY_FILE_SIZE},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_DZ), PAGE_FOLIO} {MAKE_ID_AND_STR(ID_OPTION_VALUE_SMYM_DZ), PAGE_FOLIO}
}, },
@ -104,11 +105,11 @@ g_text_direction[] =
g_permeate_lv[] = g_permeate_lv[] =
{ {
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JR), PERMAEATE_WEAKER}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JR), PERMAEATE_WEAK},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_R), PERMAEATE_WEAK}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_R), PERMAEATE_WEAKER},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_YB), PERMAEATE_ORDINARY}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_YB), PERMAEATE_ORDINARY},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_Q), PERMAEATE_STRONG}, {MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_Q), PERMAEATE_STRONGER},
{MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JQ), PERMAEATE_STRONGER} {MAKE_ID_AND_STR(ID_OPTION_VALUE_FZSTDJ_JQ), PERMAEATE_STRONG}
}, },
g_img_quality[] = g_img_quality[] =
{ {
@ -504,12 +505,12 @@ int double_paper_flag_from_option_value(std::string& opt_val, bool* exact)
if (exact) if (exact)
*exact = true; *exact = true;
if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_SCTXBJXSM)) if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_SCTXBTZSM))//上传图像并停止
return DOUBLE_PAPER_CONTINUE | DOUBLE_PAPER_SAVE_IMG; return DOUBLE_PAPER_SAVE_IMG;
else if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_SCTXBTZSM)) else if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_DQTXBTZSM))//丢弃图像并停止
return DOUBLE_PAPEAR_STOP;
else if (opt_val == from_default_language(OPTION_VALUE_SZTPCL_SCTXBJY))//上传图像并校验
return DOUBLE_PAPER_SAVE_IMG; return DOUBLE_PAPER_SAVE_IMG;
else if (opt_val == hg_log::lang_load(ID_OPTION_VALUE_SZTPCL_DQTXBJXSM))
return DOUBLE_PAPER_CONTINUE;
else else
{ {
if (exact) if (exact)

View File

@ -173,12 +173,14 @@ bool is_lateral(int paper);
//#define HUAGAO_SETTING_STR_PAGE_DOUBLE "双面" //#define HUAGAO_SETTING_STR_PAGE_DOUBLE "双面"
//#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY "跳过空白页(通用)" //#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY "跳过空白页(通用)"
//#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY_RECEIPT "跳过空白页(发票纸)" //#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY_RECEIPT "跳过空白页(发票纸)"
//#define HUAGAO_SETTING_STR_PAGE_OMIT_EMPTY_FILE_SIZE "跳过空白页(基于文件大小)"
//#define HUAGAO_SETTING_STR_PAGE_FOLIO "对折" //#define HUAGAO_SETTING_STR_PAGE_FOLIO "对折"
enum { enum {
PAGE_SINGLE = 0, PAGE_SINGLE = 0,
PAGE_DOUBLE, PAGE_DOUBLE,
PAGE_OMIT_EMPTY, PAGE_OMIT_EMPTY,
PAGE_OMIT_EMPTY_RECEIPT, PAGE_OMIT_EMPTY_RECEIPT,
PAGE_OMIT_EMPTY_FILE_SIZE,
PAGE_FOLIO, PAGE_FOLIO,
}; };
int match_best_page(std::string& val, bool* exact); int match_best_page(std::string& val, bool* exact);
@ -273,6 +275,7 @@ enum
{ {
DOUBLE_PAPER_CONTINUE = 0x01, // 继续扫描 DOUBLE_PAPER_CONTINUE = 0x01, // 继续扫描
DOUBLE_PAPER_SAVE_IMG = 0x02, // 保存图片 DOUBLE_PAPER_SAVE_IMG = 0x02, // 保存图片
DOUBLE_PAPEAR_STOP = 0x03 //丢弃并停止
}; };
int double_paper_flag_from_option_value(std::string& opt_val, bool* exact); int double_paper_flag_from_option_value(std::string& opt_val, bool* exact);
std::string double_paper_flag_to_option_value(int flag); std::string double_paper_flag_to_option_value(int flag);
@ -614,6 +617,12 @@ typedef struct _scan_conf
uint8_t fold_concatmode; /**< 对折拼接模式 0左右,1上下2自动对折>*/ uint8_t fold_concatmode; /**< 对折拼接模式 0左右,1上下2自动对折>*/
int HsvFilterType; /**< 答题卡留红出杂色功能类型 暂定为0*/ int HsvFilterType; /**< 答题卡留红出杂色功能类型 暂定为0*/
bool is_colorcast; /**< 色偏校正*/ bool is_colorcast; /**< 色偏校正*/
int discare_edge; /**< 跳过空白页边缘缩进>*/
int discare_dilate; /**< 调过空白页纸张杂点阈值>*/
double discare_meanth; /**< 调过空白页文稿底色阈值>*/
bool en_contaminationdetection; /**< 脏污检测使能>*/
bool detect_size_diascard_blank; /**< 基于压缩图像大小跳过空白页使能*/
int refuseInflow_level; /**< 防止渗透等级*/
uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/ uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/
}SCANCONF ,*LPSCANCONF; }SCANCONF ,*LPSCANCONF;
//图像参数设置 -OVER //图像参数设置 -OVER
@ -632,7 +641,7 @@ namespace setting_hardware
unsigned int ultrasonic_enable : 1; // 是否进行超声波检测(双/多张进纸检测) unsigned int ultrasonic_enable : 1; // 是否进行超声波检测(双/多张进纸检测)
unsigned int staple_enbale : 1; // 是否进行钉书钉检测 unsigned int staple_enbale : 1; // 是否进行钉书钉检测
unsigned int screw_detect_enable : 1; // 是否歪斜检测 unsigned int screw_detect_enable : 1; // 是否歪斜检测
unsigned int screw_detect_level : 3; // 歪斜检测水平 unsigned int screw_detect_level : 3; // 歪斜检测水平 bit14
unsigned int iscorrect_mod : 1; // 是否自动校正 unsigned int iscorrect_mod : 1; // 是否自动校正
unsigned int is_autopaper : 1; // 是否自动进纸 unsigned int is_autopaper : 1; // 是否自动进纸
// unsigned int reserved1 : 4; // 保留 // unsigned int reserved1 : 4; // 保留
@ -641,7 +650,8 @@ namespace setting_hardware
unsigned int en_anlogic_key : 1; // unsigned int en_anlogic_key : 1; //
unsigned int en_autosize : 1; // unsigned int en_autosize : 1; //
unsigned int pc_correct : 1; // 是否在PC端校正 1:不校正 cis原图0:校正 unsigned int pc_correct : 1; // 是否在PC端校正 1:不校正 cis原图0:校正
unsigned int enable_sizecheck : 1; // 是否进行尺寸检测 //unsigned int enable_sizecheck : 1; // 是否进行尺寸检测 2023-10-11 屏蔽 此bit位变更为double_out_en
unsigned int double_out_en : 1; //true 双张纸搓出出纸口, false 卡在出纸口
unsigned int enabledsp_cache : 1; // 是否在片上缓存 unsigned int enabledsp_cache : 1; // 是否在片上缓存
unsigned int sizeerror_errorratio : 9; // 幅面检测 unsigned int sizeerror_errorratio : 9; // 幅面检测
}params_3399; }params_3399;
@ -668,37 +678,47 @@ namespace setting_hardware
typedef union hg_scanner_config_3288 typedef union hg_scanner_config_3288
{ {
unsigned int value; unsigned int value;
//struct
//{
// unsigned int pageSize : 5;
// unsigned int isColor : 1;
// unsigned int dpi : 2;
// unsigned int doubleFeeded : 1;
// unsigned int enableUV : 1;
// unsigned int enableLed : 1;
// unsigned int sizedetece : 1;
// unsigned int reversed1 : 5;
// unsigned int isCorrect : 1;
// unsigned int dstHeight : 8;
// unsigned int reversed2 : 6;
//}params;
struct // changed on 2022-07-25 struct // changed on 2022-07-25
{ {
unsigned int pageSize : 5; unsigned int pageSize : 5;
unsigned int isColor : 1; unsigned int isColor : 1;
unsigned int dpi : 2; unsigned int dpi : 2;
unsigned int doubleFeeded : 1; unsigned int doubleFeeded : 1;
unsigned int enableStable : 1; unsigned int en_doublefeed_check : 1;
unsigned int enableLed : 1; unsigned int enableLed : 1;
unsigned int enableSizeDetect : 1; unsigned int enableSizeDetect : 1;
unsigned int lutmode : 1; // 设置文本和照片模式, 0 - 文本1 - 照片。默认值为“0” unsigned int lutmode : 1; // 设置文本和照片模式, 0 - 文本1 - 照片。默认值为“0”
unsigned int moire : 1; unsigned int moire : 1;
unsigned int reversed1 : 3; unsigned int dirty_detect : 1;
unsigned int reversed1 : 2;
unsigned int isCorrect : 1; //设置0 为原图1为校正后的图 unsigned int isCorrect : 1; //设置0 为原图1为校正后的图
unsigned int dstHeight : 8; unsigned int dstHeight : 8;
unsigned int reversed2 : 6; unsigned int reversed2 : 6;
}params_3288; }params_3288;
}HGSCANCONF_3288; }HGSCANCONF_3288;
typedef union hg_scanner_config_7010
{
unsigned int value;
struct
{
unsigned int pageSize : 5;
unsigned int isColor : 1;
unsigned int dpi : 2;
unsigned int doubleFeeded : 1;
unsigned int en_doublefeed_check : 1;
unsigned int enableLed : 1;
unsigned int enableSizeDetect : 1;
unsigned int lutmode : 1; // 设置文本和照片模式, 0 - 文本1 - 照片。默认值为“0”
unsigned int moire : 1;
unsigned int reversed1 : 2;
unsigned int isCorrect : 1; //设置0 为原图1为校正后的图
unsigned int dc : 7; //设置PWM占空比
unsigned int reversed2 : 8;
}params_7010;
}HGSCANCONF_7010;
} }
//硬件协议定义 -OVER //硬件协议定义 -OVER
namespace setting3288dsp namespace setting3288dsp
@ -721,11 +741,13 @@ namespace setting3288dsp
{ {
FLAT_INFO info; FLAT_INFO info;
cv::Mat flat_lut; cv::Mat flat_lut;
float vratio;
float hratio;
}; };
struct HG_JpegCompressInfo struct HG_JpegCompressInfo
{ {
unsigned int data_type; unsigned int error_code;
unsigned int first_frame; unsigned int first_frame;
unsigned int last_frame; unsigned int last_frame;
unsigned int index_frame; unsigned int index_frame;
@ -771,9 +793,11 @@ namespace setting3288dsp
USB_DISCONNECTED = 200, //USB 未连接 USB_DISCONNECTED = 200, //USB 未连接
USER_STOP = 201, //用户点击停止 USER_STOP = 201, //用户点击停止
AUTO_FLAT_FINISHED = 202, //自动校正完成 AUTO_FLAT_FINISHED = 202, //自动校正完成
USB_CONNECTED, //USB已连接 SCANNER_ACTIVED=0x10, //设备未休眠 休眠返回0x100 未休眠返回0x10
HAVE_PAPER, DOUBLE_FEED_IMAGE=203,//双张校验图像
DEVICE_OFF_LINE, //USB链接断开 IMAGE_DIRTY_BAND=204,//图像脏污
IMAGE_DIRTY_CIS = 205
} UsbSupported, * PUsbSupported; } UsbSupported, * PUsbSupported;
// //
//设备状态 - OVER //设备状态 - OVER
@ -936,6 +960,12 @@ namespace setting3288dsp
GETMOTORPARMLEN = 0x203, GETMOTORPARMLEN = 0x203,
SETMOTORPARAM = 0x204, SETMOTORPARAM = 0x204,
SETMOTORPARAMLEN = 0x205, SETMOTORPARAMLEN = 0x205,
SET_BACKUP_CONFIG = 0x304,
SET_RECOVERY = 0x305,
GET_BACKUP_STATUS = 0x306,
GET_RECOVERY_STATUS = 0x307,
GET_DATETIME,
SET_DATETIME,
DEVICES_7010 = 0x7010 DEVICES_7010 = 0x7010
}; };
typedef enum tagUsbKeyWords UsbKeyWords, * PUsbKeyWords; typedef enum tagUsbKeyWords UsbKeyWords, * PUsbKeyWords;
@ -1057,6 +1087,7 @@ namespace setting3399
SR_GET_TOKEN_LENGHT, SR_GET_TOKEN_LENGHT,
SR_DECODE_TOKEN, SR_DECODE_TOKEN,
SR_CLEAN_PAPER_ROAD, //清理纸道 SR_CLEAN_PAPER_ROAD, //清理纸道
SR_BACKUP_RESTORES_HUAGODIR=67,
SR_GET_CUO_ERROR = 0x50, SR_GET_CUO_ERROR = 0x50,
SR_GET_DOU_ERROR, SR_GET_DOU_ERROR,
SR_GET_JAM_ERROR, SR_GET_JAM_ERROR,
@ -1076,6 +1107,11 @@ namespace setting3399
SR_SET_H_600_RATIO, SR_SET_H_600_RATIO,
SR_GET_V_600_RATIO, SR_GET_V_600_RATIO,
SR_SET_V_600_RATIO, SR_SET_V_600_RATIO,
SR_GET_ARM_DATETIME=101,
SR_GET_ARM_DATETIME_LENGHT=102,
SR_SET_ARM_DATETIME=103,
SR_SET_LCD_LANGUAGE = 106,
SR_GET_LCD_LANGUAGE = 107,
SR_UPDATA_START = 0x100, SR_UPDATA_START = 0x100,
SR_UPDATA_STAUTUS = 0x101, SR_UPDATA_STAUTUS = 0x101,
SR_UPDATA_MD5_RELUST = 0x102, SR_UPDATA_MD5_RELUST = 0x102,
@ -1113,11 +1149,24 @@ namespace setting3399
AutoCorrect, AutoCorrect,
STOPSCAN, STOPSCAN,
}; };
enum Image_Status
{
Image_Status_OK = 0, // normal
Image_Status_Double = 1 << 0, // double-feeded paper
Image_Status_Jammed = 1 << 1, // jammed paper
Image_Status_Staple = 1 << 2, // staples on the paper
Image_Status_Size_Error = 1 << 3, // size check failed
Image_Status_Dogear = 1 << 4, // paper has dogear - common
Image_Status_Partial = 1 << 5, // dogear - scanned partial
Image_Status_Blank = 1 << 6 // blank image
};
struct HGEIntInfo struct HGEIntInfo
{ {
HGType From; HGType From;
unsigned int Code; unsigned int Code;
unsigned int Img_Index; unsigned int Img_Index;
Image_Status Img_Status;
}; };
enum PaperSize_ //239 302 402 enum PaperSize_ //239 302 402
{ {
@ -1333,10 +1382,10 @@ namespace setting3399
#ifdef UOS #ifdef UOS
#define HELP_PATH "../../entries/help/NeuScan_scanSettings_Help_manual.pdf"; #define HELP_PATH "../../entries/help/NeuScan_scanSettings_Help_manual.pdf";
#define HELP_PATH_EN "" #define HELP_PATH_EN "../../entries/help/NeuScan_scanSettings_Help_manual_EN.pdf"
#elif KYLIN #elif KYLIN
#define HELP_PATH "../doc/NeuScan_scanSettings_Help_manual.pdf"; #define HELP_PATH "../doc/NeuScan_scanSettings_Help_manual.pdf";
#define HELP_PATH_EN "" #define HELP_PATH_EN "../doc/NeuScan_scanSettings_Help_manual_EN.pdf"
#endif #endif
#elif defined(OEM_DELI) #elif defined(OEM_DELI)
@ -1409,7 +1458,7 @@ namespace setting3399
#define IMGPRC_LIBNANE "NEUImgProc.dll" #define IMGPRC_LIBNANE "NEUImgProc.dll"
#define HGBASE_LIBNAME "NEUBase.dll" #define HGBASE_LIBNAME "NEUBase.dll"
#define HELP_PATH "NeuScan_scanSettings_Help_manual.pdf" #define HELP_PATH "NeuScan_scanSettings_Help_manual.pdf"
#define HELP_PATH_EN "" #define HELP_PATH_EN "NeuScan_scanSettings_Help_manual_EN.pdf"
#elif defined(OEM_DELI) #elif defined(OEM_DELI)
#define HGVERSION_LIBNANE "DLVersion.dll" #define HGVERSION_LIBNANE "DLVersion.dll"

View File

@ -639,7 +639,7 @@ tiny_buffer::tiny_buffer(unsigned int size
, const char* name_leading , const char* name_leading
, const char* ext , const char* ext
, unsigned int uniq_id) , unsigned int uniq_id)
: size_(size), buf_(nullptr), img_statu_(SANE_Image_Statu_OK) : size_(size), buf_(nullptr), img_statu_(IMG_STATUS_OK)
{ {
init(tmp_path, name_leading, ext, uniq_id); init(tmp_path, name_leading, ext, uniq_id);
} }
@ -785,7 +785,7 @@ void final_img_queue::clear(void)
mem_usage_ = 0; mem_usage_ = 0;
queue_.clear(); queue_.clear();
} }
bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes, int statu
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id) , const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id)
{ {
IMGDT imgd; IMGDT imgd;
@ -799,6 +799,7 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
imgd.header.line_bytes = line_bytes; imgd.header.line_bytes = line_bytes;
imgd.header.width = w; imgd.header.width = w;
imgd.header.src_id = id; imgd.header.src_id = id;
imgd.header.statu = statu;
imgd.offset = 0; imgd.offset = 0;
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind)); imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));

View File

@ -213,6 +213,7 @@ typedef struct _img_header
int bits; int bits;
int channels; int channels;
int line_bytes; int line_bytes;
int statu; // SANE_Image_Statu
unsigned bytes; unsigned bytes;
uint32_t src_id; uint32_t src_id;
}IMH; }IMH;
@ -236,7 +237,7 @@ public:
unsigned long long mem_usage(void); unsigned long long mem_usage(void);
size_t size(void); size_t size(void);
void clear(void); void clear(void);
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes, int statu
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id); , const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id);
bool front(IMH* header); bool front(IMH* header);
void fetch_front(void* buf, int* len, bool* over); void fetch_front(void* buf, int* len, bool* over);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
// hg_scanner is the base class of kinds of scanners // hg_scanner is the base class of kinds of scanners
// //
@ -31,6 +31,7 @@
#include <unistd.h> #include <unistd.h>
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include "../../../sdk/include/huagao/brand.h"
#ifndef WIN32 #ifndef WIN32
@ -129,7 +130,8 @@ class hg_scanner
void working_begin(void*); void working_begin(void*);
void working_done(void*); void working_done(void*);
void image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id); void save_exception_image(std::shared_ptr<tiny_buffer>& buffer, int sn, const char* desc);
bool image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id); // 返回true - continue; false - exit and invoked do_stop
void reset_custom_area_range(int paper); void reset_custom_area_range(int paper);
float reset_custom_area_jsn_value(const char* name, double& var, float range_l, float range_u, float value_l, float value_u); // return cur value float reset_custom_area_jsn_value(const char* name, double& var, float range_l, float range_u, float value_l, float value_u); // return cur value
int set_color_change(void); int set_color_change(void);
@ -241,6 +243,8 @@ protected:
int setting_get_motor_ver(void* data, long* len); int setting_get_motor_ver(void* data, long* len);
int setting_get_initial_boot_time(void* data, long* len); int setting_get_initial_boot_time(void* data, long* len);
int setting_set_discardblank(void* data, long* len); int setting_set_discardblank(void* data, long* len);
int setting_detect_lens_dirty(void* data, long* len);
int setting_set_period(void* data, long* len);
virtual void on_device_reconnected(void); virtual void on_device_reconnected(void);
virtual int on_scanner_closing(bool force); virtual int on_scanner_closing(bool force);
@ -260,6 +264,9 @@ protected:
virtual int on_pick_paper_threshold(double threshold) = 0; //设置搓纸阈值 virtual int on_pick_paper_threshold(double threshold) = 0; //设置搓纸阈值
virtual int on_is_auto_paper(bool isautopaper) = 0; //待纸扫描 virtual int on_is_auto_paper(bool isautopaper) = 0; //待纸扫描
virtual int on_cis_get_image(bool type) = 0; virtual int on_cis_get_image(bool type) = 0;
virtual int on_process_double_paper(bool type) = 0; //双张图像校验
virtual int on_detect_lens_dirty(bool &type); //检测镜头脏污
virtual int on_set_period(int val); //PWM占空比
protected: protected:
virtual int set_setting_value(const char* name, void* data, long* len); virtual int set_setting_value(const char* name, void* data, long* len);
@ -273,6 +280,7 @@ protected:
void adjust_color(hg_imgproc::HIMGPRC handle); void adjust_color(hg_imgproc::HIMGPRC handle);
hg_imgproc::IMGPRCPARAM get_image_process_object(int model); hg_imgproc::IMGPRCPARAM get_image_process_object(int model);
SANE_Image_Statu last_usb_image_statu(int err); SANE_Image_Statu last_usb_image_statu(int err);
bool is_auto_scan(void); // BUG-732
hg_imgproc::HIMGPRC ImagePrc_pHandle_; hg_imgproc::HIMGPRC ImagePrc_pHandle_;
protected: protected:
ScannerSerial serial_; ScannerSerial serial_;
@ -296,8 +304,9 @@ protected:
std::vector<std::string> jsn_children_; std::vector<std::string> jsn_children_;
std::vector<string> erase_depend_; //需要删除父依赖项 std::vector<string> erase_depend_; //需要删除父依赖项
json setting_jsn_; json setting_jsn_;
IMGPRCFIXPARAM image_prc_param_; IMGPRCFIXPARAM image_prc_param_;
int erase_bkg_range_; // 背景移除像素范围 int erase_bkg_range_; // 背景移除像素范围
int noise_range_; // 噪点优化尺寸 int noise_range_; // 噪点优化尺寸
TwSS paper_size_; TwSS paper_size_;
@ -316,16 +325,13 @@ protected:
int is_quality_; // 画质设置 0 - 速度优先1 - 画质优先 int is_quality_; // 画质设置 0 - 速度优先1 - 画质优先
bool is_color_fill; // 色彩填充 bool is_color_fill; // 色彩填充
bool is_multiout; // 多流输出 bool is_multiout; // 多流输出
int bw_threshold_; // 黑白图像阈值 added on 2022-06-28 int bw_threshold_; // 黑白图像阈值 added on 2022-06-28
int feedmode_; // 分纸强度 int feedmode_; // 分纸强度
int sleeptime_; // 睡眠时间 int sleeptime_; // 睡眠时间
bool is_auto_paper_scan; // 待纸扫描 bool is_auto_paper_scan; // 待纸扫描
bool size_check; // 尺寸检测 bool size_check; // 尺寸检测
bool save_feedmode_type_; //保存分支强度狀態 bool save_feedmode_type_; //保存分支强度狀態
bool save_sleeptime_type_; //保存休眠時間 bool save_sleeptime_type_; //保存休眠時間
bool isremove_left_hole; //设置左边除穿孔 bool isremove_left_hole; //设置左边除穿孔
bool isremove_right_hole; //设置右边除穿孔 bool isremove_right_hole; //设置右边除穿孔
bool isremove_top_hole; //设置上边除穿孔 bool isremove_top_hole; //设置上边除穿孔
@ -343,37 +349,19 @@ protected:
int is_auto_paper_scan_exit_time; //待纸扫描退出时间 int is_auto_paper_scan_exit_time; //待纸扫描退出时间
bool is_auto_feedmode_; //是否启用自动分纸强度 bool is_auto_feedmode_; //是否启用自动分纸强度
bool is_discardblank; //是否启动跳过空白页 bool is_discardblank; //是否启动跳过空白页
bool is_lens_dirty; //是否检测镜头脏污
int split3399_; //3399设备正面和反面图像是相对的所以对折时反面需要进行特殊处理
int pid_;
SANE_DISTORTION_VAL distortion_val; //畸变修正结构体保存 SANE_DISTORTION_VAL distortion_val; //畸变修正结构体保存
int split3399_; //3399设备正面和反面图像是相对的所以对折时反面需要进行特殊处理
int pid_;
/////////不同的固件号版本支持 /////////不同的固件号版本支持
//bool is_kernelsnap_239_220830_; //此版本支持,手动睡眠唤醒,分纸强度
//bool is_kernelsnap_239_211209_; //获取固件版本号是否是新旧版本
//bool is_kernelsnap_239_221027_; //此版本一下不支持拆分模式 pc实现
//bool is_kernelsnap3288_221106_; //G300 3288 在221106版本支持真实300dpi
//bool is_kernelsnap3288_230210_; //G300 3288 在230210版本支持真实600dpi
//bool is_kernelsnap3288_230303_; //G300 3288 支持清除历史扫描张数
//bool is_kernelsnap_devsislock; //支持设备锁的版本
//bool is_kernelsnap_239_3C_; //支持偏色校正的版本,自适应配置
//bool is_kernelsnap_439_3C0606; //支持偏色校正的版本
//bool is_kernelsnap_239_220500_; //支持双张保留的版本
//bool is_kernelsnap_239_220429_; //第一个安陆版本,支持设备日志导出
//bool is_kernelsnap_239_220430_; //待纸扫描
// bool is_kernelsnap_211227_; //此版本以下不支持真实dpi 只设置1下去
bool firmware_sup_wait_paper_; //固件支持 待纸扫描 139 239-3B0431, 439-3B0629 bool firmware_sup_wait_paper_; //固件支持 待纸扫描 139 239-3B0431, 439-3B0629
bool firmware_sup_pick_strength_; //固件支持 分纸强度 139 239-3B0830 bool firmware_sup_pick_strength_; //固件支持 分纸强度 139 239-3B0830
bool firmware_sup_log_export_; //固件支持 日志导出 139 239-3B0429 bool firmware_sup_log_export_; //固件支持 日志导出 139 239-3B0429
bool firmware_sup_log_export_G300_; //固件支持 不用协议,直接读片上文件,设备日志导出 300 - 0430
bool firmware_sup_color_corr_; //固件支持 偏色校正 139 239 439-3C bool firmware_sup_color_corr_; //固件支持 偏色校正 139 239 439-3C
bool firmware_sup_wake_device_; //固件支持 唤醒设备 139 239-3B0830 bool firmware_sup_wake_device_; //固件支持 唤醒设备 139 239-3B0830
bool firmware_sup_double_img; //固件支持 双张保留 139 239-3C bool firmware_sup_double_img; //固件支持 双张保留 139 239-3C
@ -384,7 +372,14 @@ protected:
bool firmware_sup_morr_; //固件支持 摩尔纹 139 239-3C0518 bool firmware_sup_morr_; //固件支持 摩尔纹 139 239-3C0518
bool firmware_sup_color_fill_; //固件支持 色彩填充 139 239 439 -3C bool firmware_sup_color_fill_; //固件支持 色彩填充 139 239 439 -3C
bool firmware_sup_history_cnt; //固件支持 清除历史张数 3288 G300 220303 bool firmware_sup_history_cnt; //固件支持 清除历史张数 3288 G300 220303
bool firmware_sup_double_check; //固件支持 双张校验 231027
bool firmware_sup_dirty_check; //固件支持 脏污检测 231027
bool firmware_sup_backup_restore; //固件支持 备份还原 231021
bool firmware_sup_boardTime; //固件支持 板级时间校验 231021
bool firmware_sup_permeation_level; //固件支持 防渗透等级 3399-3C1206
bool firmware_sup_device_7010; //G300 设备但是7010 2023/9/21 bool firmware_sup_device_7010; //G300 设备但是7010 2023/9/21
bool firmware_sup_firmware_language_;//固件支持 设置或获取固件语言模式 仅139 239有固件语言功能3C1229及之后支持
bool firmware_sup_300device_D8_; //G300 固件211124及以前是3288设备之后是D8设备
int mat_width; int mat_width;
int mat_height; int mat_height;
@ -399,6 +394,7 @@ protected:
unsigned long memory_size_; // MB unsigned long memory_size_; // MB
unsigned long wait_mem_seconds_; // wait up to wait_mem_seconds_ if memory usage is great than memory_size_ unsigned long wait_mem_seconds_; // wait up to wait_mem_seconds_ if memory usage is great than memory_size_
bool isx86_Advan_; bool isx86_Advan_;
bool no_paper_check_ = false; // 扫描前是否检测无纸状态;可以通过配置[func]no-paper-chk=1开启
int stop_fatal_; int stop_fatal_;
BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_; BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_;
@ -408,6 +404,7 @@ protected:
void change_setting_language(bool init); void change_setting_language(bool init);
void erase_option(const char* name); void erase_option(const char* name);
void erase_range(const char* name, const char* opt_name);
void init_settings(const char* json_setting_text); void init_settings(const char* json_setting_text);
int init_settings(int pid); int init_settings(int pid);
void change_string_2_lang_id(const char* name, const char* key); void change_string_2_lang_id(const char* name, const char* key);
@ -426,14 +423,7 @@ protected:
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1); int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1);
void adjust_filling_hole(LPSCANCONF conf); void adjust_filling_hole(LPSCANCONF conf);
int wait_one_image_from_start(bool& handled);
enum thread_running
{
THREAD_RUNNING_IDLE = 0,
THREAD_RUNNING_USB = 1 << 0,
THREAD_RUNNING_IMAGE = 1 << 1,
};
int is_running(void); // return thread_running
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05 // 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05
@ -456,6 +446,9 @@ protected:
bool is_white_0_; // 是否0代表白色 bool is_white_0_; // 是否0代表白色
public: public:
int start(void);
int stop(void);
void set_ui_callback(sane_callback cb, bool enable_async_io); void set_ui_callback(sane_callback cb, bool enable_async_io);
void set_dev_family(const char* family); void set_dev_family(const char* family);
void set_read_over_with_no_data(bool no_data); void set_read_over_with_no_data(bool no_data);
@ -473,11 +466,19 @@ public:
bool is_online(void); bool is_online(void);
void on_language_changed(void); void on_language_changed(void);
enum thread_running
{
THREAD_RUNNING_IDLE = 0,
THREAD_RUNNING_USB = 1 << 0,
THREAD_RUNNING_IMAGE = 1 << 1,
};
int is_running(void); // return thread_running
public: public:
virtual int start(void); virtual int do_start(void) = 0;
virtual int get_image_info(SANE_Parameters* ii); virtual int do_stop(void) = 0;
virtual int get_image_info(SANE_Parameters* ii, int len);
virtual int read_image_data(unsigned char* buf, int* len); virtual int read_image_data(unsigned char* buf, int* len);
virtual int stop(void);
virtual int reset(void); virtual int reset(void);
virtual int device_io_control(unsigned long code, void* data, unsigned* len); virtual int device_io_control(unsigned long code, void* data, unsigned* len);
virtual int discard_all_images(void) = 0; virtual int discard_all_images(void) = 0;
@ -505,22 +506,18 @@ public:
/////////////成功返回:SCANNER_ERR_OK ///////////// /////////////成功返回:SCANNER_ERR_OK /////////////
/////////////失败返回:IO错误码 ///////////// /////////////失败返回:IO错误码 /////////////
virtual int set_leaflet_scan(void) = 0; //单张扫描 virtual int set_leaflet_scan(void) = 0; //单张扫描
virtual int get_abuot_info(void); //获取软件关于信息 (基类实现) virtual int get_abuot_info(void); //获取软件关于信息 (基类实现)
virtual int restore_default_setting(void); //恢复默认设置 (基类实现) virtual int restore_default_setting(void); //恢复默认设置 (基类实现)
virtual int set_final_image_format(SANE_FinalImgFormat* fmt);//设置图像处理最终输出final())的图像数据格式 (基类实现) *** virtual int set_final_image_format(SANE_FinalImgFormat* fmt);//设置图像处理最终输出final())的图像数据格式 (基类实现) ***
virtual int get_compression_format(void); //获取支持的压缩格式 不支持 virtual int get_compression_format(void); //获取支持的压缩格式 不支持
virtual int set_compression_format(void); //设置图像数据最终输出的压缩格式 不支持 virtual int set_compression_format(void); //设置图像数据最终输出的压缩格式 不支持
virtual int set_auto_color_type(void); //设置自动匹配颜色模式 (基类实现) virtual int set_auto_color_type(void); //设置自动匹配颜色模式 (基类实现)
virtual int set_clear_roller_num(void) = 0; //清除滚轴计数 virtual int set_clear_roller_num(void) = 0; //清除滚轴计数
virtual int set_clear_history_num(void) = 0; //清除历史张数 virtual int set_clear_history_num(void) = 0; //清除历史张数
virtual int get_device_code(void); //获取设备编码 不支持 virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_scanner_paperon(SANE_Bool& type)=0; //获取设备有无纸张 /*/ type : false无纸不正常状态false true有纸 */ virtual int get_scanner_paperon(SANE_Bool& type)=0; //获取设备有无纸张 /*/ type : false无纸不正常状态false true有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) = 0; //获取设备是否休眠当中 /*/ type : false休眠不正常状态false true未休眠*/ virtual int get_scan_is_sleep(SANE_Bool& type) = 0; //获取设备是否休眠当中 /*/ type : false休眠不正常状态false true未休眠*/
virtual int get_sleep_time(int& data) = 0; //获取功耗模式(休眠) /*/ data > 0*/ virtual int get_sleep_time(int& data) = 0; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) = 0; //设置功耗模式(休眠) /*/ data > 0*/ virtual int set_sleep_time(int data) = 0; //设置功耗模式(休眠) /*/ data > 0*/
@ -540,23 +537,22 @@ public:
virtual int get_scan_mode(bool& type) ; //获取设备是否计数模式 /*/ type:false计数模式 true非计数模式 virtual int get_scan_mode(bool& type) ; //获取设备是否计数模式 /*/ type:false计数模式 true非计数模式
virtual int set_speed_mode(int data) = 0; //设置速度模式 /*/ 设备不同值不同,详情见子类注释 virtual int set_speed_mode(int data) = 0; //设置速度模式 /*/ 设备不同值不同,详情见子类注释
virtual int get_speed_mode(int &data) = 0; //获取速度模式 /*/ 设备不同值不同,详情见子类注释 virtual int get_speed_mode(int &data) = 0; //获取速度模式 /*/ 设备不同值不同,详情见子类注释
virtual int set_distortion_image(bool type); //设置畸变校正图 /*/ 基类处理 virtual int set_distortion_image(bool type); //设置畸变校正图 /*/ 基类处理
virtual int get_distortion_check_val(int &val); //获取自动计算畸变校正值 /*/ 基类处理 virtual int get_distortion_check_val(int &val); //获取自动计算畸变校正值 /*/ 基类处理
virtual int set_devs_distortion_check_val(float data) = 0; //设置畸变矫正值 float; virtual int set_devs_distortion_check_val(float data) = 0; //设置畸变矫正值 float;
virtual int get_devs_distortion_check_val(float& data) = 0; //获取设备畸变值 float; virtual int get_devs_distortion_check_val(float& data) = 0; //获取设备畸变值 float;
virtual int set_auto_flat(int data) = 0; //设置自动平场校正 virtual int set_auto_flat(int data) = 0; //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color) // data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
virtual int set_updata0303(void) ; virtual int set_updata0303(void) ;
virtual int get_motor_board_ver(string &ver); //获取G239电机板的固件号 //3399设备支持 virtual int get_motor_board_ver(string &ver); //获取G239电机板的固件号 //3399设备支持
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持 virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
virtual int get_devs_time(string &times); //获取设备时间 //3399设备支持 virtual int get_devs_time(string &times); //获取设备时间 //3399设备支持
virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
virtual int get_devs_cpu(string& cpu); //获取设备内存大小 virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
virtual int get_devs_disk(string& disk); //获取设备硬盘容量大小 virtual int set_restore(); //还原文件
virtual int set_backup(); //备份文件
virtual int set_firmware_language(int language_mode); // 设置固件语言模式 仅139、239设备支持 //0->简体中文; 1->繁体中文; 2->English
virtual int get_firmware_language(int& language_mode); // 获取固件语言模式 仅139、239设备支持 //0->简体中文; 1->繁体中文; 2->English
}; };

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
// hg_scanner is the base class of kinds of scanners // hg_scanner is the base class of kinds of scanners
// //
@ -44,13 +44,14 @@ protected:
virtual int on_pick_paper_threshold(double threshold) override; //设置搓纸阈值 virtual int on_pick_paper_threshold(double threshold) override; //设置搓纸阈值
virtual int on_is_auto_paper(bool isautopaper) override; //待纸扫描 virtual int on_is_auto_paper(bool isautopaper) override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //获取cis原图 virtual int on_cis_get_image(bool isautopaper) override; //获取cis原图
virtual int on_process_double_paper(bool type) override; //双张图像校验
public: public:
hg_scanner_200(const char* dev_name,int vid, usb_io* io); hg_scanner_200(const char* dev_name,int vid, usb_io* io);
~hg_scanner_200(); ~hg_scanner_200();
public: public:
virtual int start(void)override; virtual int do_start(void) override;
virtual int stop(void)override; virtual int do_stop(void) override;
private: private:
int initdevice(); int initdevice();
@ -58,7 +59,7 @@ private:
int readusb(USBCB &usb); int readusb(USBCB &usb);
int pop_image(); int pop_image();
int get_scanner_status(USBCB &usb); int get_scanner_status(USBCB &usb);
int get_img_data(unsigned int bytes, SANE_Image_Statu statu = SANE_Image_Statu_OK); int get_img_data(unsigned int bytes, SANE_Image_Statu statu = IMG_STATUS_OK);
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_DSP *d = NULL); int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_DSP *d = NULL);
void writedown_image_configuration(void); void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_DSP *d = NULL); void printf_devconfig(setting_hardware::HGSCANCONF_DSP *d = NULL);

File diff suppressed because one or more lines are too long

View File

@ -41,7 +41,7 @@ class hg_scanner_239 : public hg_scanner
int writedown_device_configuration(bool type = false, setting_hardware::HGSCANCONF_3399* dev_conf = NULL);//false 在start再把type置为true,其他做设置时不发 int writedown_device_configuration(bool type = false, setting_hardware::HGSCANCONF_3399* dev_conf = NULL);//false 在start再把type置为true,其他做设置时不发
int writedown_image_configuration(void); int writedown_image_configuration(void);
int pop_first_image(void); int pop_first_image(void);
int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK); int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
bool is_dev_image_process_done(void); bool is_dev_image_process_done(void);
bool is_dev_image_keep_last_paper(void); bool is_dev_image_keep_last_paper(void);
@ -51,6 +51,8 @@ class hg_scanner_239 : public hg_scanner
int write_control_device_files(std::string file_path,std::string file_str); int write_control_device_files(std::string file_path,std::string file_str);
int read_control_device_files(std::string file_path, std::string &file_str); int read_control_device_files(std::string file_path, std::string &file_str);
int update_boarddatetime();
protected: protected:
virtual void on_device_reconnected(void) override; virtual void on_device_reconnected(void) override;
virtual int on_scanner_closing(bool force) override; virtual int on_scanner_closing(bool force) override;
@ -73,6 +75,8 @@ protected:
virtual int on_pick_paper_threshold(double threshold)override; virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描 virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取 virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
virtual int on_process_double_paper(bool type) override; //双张图像校验
virtual int on_detect_lens_dirty(bool &type) override; //检测镜头脏污
public: public:
@ -82,8 +86,8 @@ public:
public: public:
//virtual int get_image_info(IMG_PARAM* ii) override; //virtual int get_image_info(IMG_PARAM* ii) override;
//virtual int read_image_data(unsigned char* buf, int* len) override; //virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int start(void) override; virtual int do_start(void) override;
virtual int stop(void) override; virtual int do_stop(void) override;
virtual int reset(void) override; virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override; virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
virtual int get_roller_life(void) override; virtual int get_roller_life(void) override;
@ -142,7 +146,11 @@ public:
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持 virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
virtual int get_devs_time(string& times); //获取设备时间 //3399设备支持 virtual int get_devs_time(string& times); //获取设备时间 //3399设备支持
virtual int get_devs_cpu(string& cpu); //获取设备内存大小 virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
virtual int get_devs_disk(string& disk); //获取设备硬盘容量大小 virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
virtual int set_restore(); //还原文件
virtual int set_backup(); //备份文件
virtual int set_firmware_language(int language_mode); // 设置固件语言模式 仅139、239设备支持 //0->简体中文; 1->繁体中文; 2->English
virtual int get_firmware_language(int& language_mode); // 获取固件语言模式 仅139、239设备支持 //0->简体中文; 1->繁体中文; 2->English
}; };

File diff suppressed because one or more lines are too long

View File

@ -44,13 +44,16 @@ protected:
virtual int on_pick_paper_threshold(double threshold)override; virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描 virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取 virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
virtual int on_process_double_paper(bool type) override; //双张图像校验
virtual int on_detect_lens_dirty(bool &type) override; //检测镜头脏污
public: public:
hg_scanner_300(const char* dev_name,int pid, usb_io* io); hg_scanner_300(const char* dev_name,int pid, usb_io* io);
~hg_scanner_300(); ~hg_scanner_300();
public: public:
virtual int start(void)override; virtual int do_start(void) override;
virtual int stop(void)override; virtual int do_stop(void) override;
private: private:
int set_kernelsnap_ver(); int set_kernelsnap_ver();
int agreement(TwSS tw,int align); int agreement(TwSS tw,int align);
@ -60,13 +63,12 @@ private:
int pop_image(void); int pop_image(void);
int get_scanner_status(USBCB &usb); int get_scanner_status(USBCB &usb);
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata); int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
int get_img_data_7010();
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3288 *d = NULL); int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3288 *d = NULL);
void writedown_image_configuration(void); void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_3288 *d = NULL); void printf_devconfig(setting_hardware::HGSCANCONF_3288 *d = NULL);
int get_device_type(bool &type); int get_devs_distortion_check_val(float& data, int dpi, int dir);//获取设备畸变值 DPI=1、2、3 dir = 0,1;
int update_boarddatetime();
setting3288dsp::HG_JpegCompressInfo frame_info_;
///////////////////////7010专有协议获取校正数据////////////////////// ///////////////////////7010专有协议获取校正数据//////////////////////
//inx:序号// //inx:序号//
//dpi:1--->200 2--->300 3--->600// //dpi:1--->200 2--->300 3--->600//
@ -77,14 +79,7 @@ private:
setting_hardware::HGSCANCONF_3288 dsp_config; setting_hardware::HGSCANCONF_3288 dsp_config;
Device::PaperSize papersize; Device::PaperSize papersize;
bool is_devs_sleep_; bool is_devs_sleep_;
;
int first_frame_total; //设置的帧数
int last_frame_total; //实际采集的帧数
std::vector<unsigned char> jpgdata_;
int index_;
public: public:
//////////////固定的硬件信息设置或获取////////////// //////////////固定的硬件信息设置或获取//////////////
@ -131,6 +126,8 @@ public:
virtual int set_auto_flat(int data)override; //设置自动平场校正 virtual int set_auto_flat(int data)override; //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color) // data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
virtual int set_updata0303(void)override; virtual int set_updata0303(void)override;
virtual int get_devs_cpu(string& cpu); //获取设备内存大小 virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
virtual int get_devs_disk(string& disk); //获取设备硬盘容量大小 virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
virtual int set_restore(); //还原文件
virtual int set_backup(); //备份文件
}; };

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
// hg_scanner is the base class of kinds of scanners // hg_scanner is the base class of kinds of scanners
// //
@ -51,7 +51,7 @@ class hg_scanner_302 : public hg_scanner
int writedown_image_configuration(void); int writedown_image_configuration(void);
int pop_first_image(void); int pop_first_image(void);
int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK); int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
virtual int discard_all_images(); virtual int discard_all_images();
virtual int get_roller_life(void) override; virtual int get_roller_life(void) override;
@ -75,6 +75,7 @@ protected:
virtual int on_pick_paper_threshold(double threshold)override; virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描 virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取 virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
virtual int on_process_double_paper(bool type) override; //双张图像校验
public: public:
@ -82,10 +83,9 @@ public:
~hg_scanner_302(); ~hg_scanner_302();
public: public:
virtual int start(void) override; virtual int do_start(void) override;
//virtual int get_image_info(IMG_PARAM* ii) override; virtual int do_stop(void) override;
//virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int stop(void) override;
virtual int reset(void) override; virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override; virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,157 @@
#pragma once
// hg_scanner is the base class of kinds of scanners
//
// created on 2022-01-30
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include "hg_scanner.h"
#include "../wrapper/hg_log.h"
#include "PaperSize.h"
//#ifdef OEM_HANWANG
//#define hg_scanner_306 hw_scanner_300
//#elif defined(OEM_LISICHENG)
//#define hg_scanner_306 lsc_scanner_300
//#endif
class hg_scanner_306 : public hg_scanner
{
protected:
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual int discard_all_images(void) override;
virtual int get_roller_life(void) override;
protected:
virtual int on_color_mode_changed(int& color_mode) override; //颜色切换
virtual int on_paper_changed(int& paper) override; //纸张大小设置
virtual int on_paper_check_changed(bool& check) override; //尺寸检测
virtual int on_resolution_changed(int& dpi) override; //分辨率设置
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检测
virtual int on_staple_check_changed(bool& check) override; //设置订书针检测
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检测
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强度
virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
virtual int on_pic_type(bool& pic)override; //照片模式或者文本模式
virtual int on_pick_paper(bool autostrength)override; //自动分纸强度
virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
virtual int on_process_double_paper(bool type) override; //双张图像校验
virtual int on_set_period(int val) override; //PWM占空比
protected:
public:
hg_scanner_306(const char* dev_name,int pid, usb_io* io);
~hg_scanner_306();
public:
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int set_kernelsnap_ver();
int agreement(TwSS tw,int align);
int initdevice();
int writeusb(USBCB &usb);
int readusb(USBCB &usb);
int pop_image(void);
int get_scanner_status(USBCB &usb);
/************************************************************************/
/* 注意事项1:7010按帧传输数据 */
/* 注意事项2:7010最后一帧为空包需把最后一帧数据剔除 */
/* 注意事项3:7010最后一帧主要作用是反馈当前纸张问题状态码 error_code */
/************************************************************************/
int get_img_data_7010();
int get_img_data_7010_test();
/*********************获取校正数据***************/
/* inx:序号 */
/* dpi:1--->200dpi 2--->300dpi 3--->600dpi */
/* mode:0 灰度 1彩色 */
/************************************************/
int get_correction_image(int inx, int dpi, int mode);
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_7010 *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_7010 *d = NULL);
int get_device_type(bool &type);
int get_devs_distortion_check_val(float& data, int dpi, int dir);//获取设备畸变值 DPI=1、2、3 dir = 0,1;
setting3288dsp::HG_JpegCompressInfo frame_info_;
private:
std::vector<int> savestatus_;
setting_hardware::HGSCANCONF_7010 dsp_config;
Device::PaperSize papersize;
bool is_devs_sleep_;
int first_frame_total_; //设置的帧数
int last_frame_total_; //实际采集的帧数
int frame_length_ ;
int frame_width_ ;
int frame_hegiht_ ;
std::vector<unsigned char> jpgdata_;
int index_;
public:
//////////////固定的硬件信息设置或获取//////////////
virtual std::string get_firmware_version(void)override;
virtual std::string get_serial_num(void)override;
virtual std::string get_ip(void)override;
virtual int set_serial_num(string str) override; //设置序列号
virtual int set_vid_pid(int data) override; //设置vidpid
virtual int get_vid_pid(int& data)override; //获取vidpid
/////////////////成功返回:SCANNER_ERR_OK /////////////
/////////////////失败返回:IO错误码 /////////////
virtual int set_leaflet_scan(void) override; //单张扫描
virtual int set_clear_roller_num(void) override; //清除滚轴计数
virtual int set_clear_history_num(void) override; //清除历史张数 0303固件版本才支持
virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/
virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/
virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/
virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) override; //唤醒设备
virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) override; //设置设备重启
virtual int set_devshtudown() override; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁1锁定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁1锁定*/
virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/
virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/
virtual int set_clean_paper_road() override; //清理纸道
virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁1 上锁*
virtual int set_speed_mode(int data) override; //设置速度模式 /*/ data:40,50,60,70
virtual int get_speed_mode(int& data)override; //获取速度模式 /*/ data:40,50,60,70
virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正
virtual int get_devs_distortion_check_val(float& data)override;//获取设备畸变值 float to int;
virtual int set_auto_flat(int data)override; //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
virtual int set_updata0303(void)override;
virtual int get_devs_cpu(int& cpu); //获取设备内存大小(kb)
virtual int get_devs_disk(int& disk); //获取设备硬盘容量大小(kb)
};

View File

@ -98,7 +98,7 @@ static int strToWchar(string str, wchar_t* s)
return -1; return -1;
} }
size_t size = str.length(); size_t size = str.length();
//鑾峰彇缂撳啿鍖哄ぇ灏忥紝骞剁敵璇风┖闂达紝缂撳啿鍖哄ぇ灏忔寜瀛楃璁$畻 //閼惧嘲褰囩紓鎾冲暱閸栧搫銇囩亸蹇ョ礉楠炲墎鏁电拠椋庘敄闂傝揪绱濈紓鎾冲暱閸栧搫銇囩亸蹇斿瘻鐎涙顑佺拋锛勭暬
int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, NULL, 0); int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, NULL, 0);
wchar_t* buffer = new wchar_t[size + 1]; wchar_t* buffer = new wchar_t[size + 1];
MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, buffer, len); MultiByteToWideChar(CP_ACP, 0, str.c_str(), size, buffer, len);
@ -217,7 +217,7 @@ namespace hg_imgproc
// construction // construction
public: public:
imgproc(int pid, bool isx86_Advan) : pid_(pid),papersize_(pid_) imgproc(int pid, bool isx86_Advan) : pid_(pid),papersize_(pid_)
, img_statu_(SANE_Image_Statu_OK) , img_statu_(IMG_STATUS_OK)
, my_path_(hg_log::pe_path()) , my_path_(hg_log::pe_path())
,ocrinit_(NULL),ocrgetdirectimage_(NULL) ,ocrinit_(NULL),ocrgetdirectimage_(NULL)
,ocrexit_(NULL),HGBase_CreatImg(NULL) ,ocrexit_(NULL),HGBase_CreatImg(NULL)
@ -334,7 +334,7 @@ namespace hg_imgproc
{ {
return SCANNER_ERR_OUT_OF_RANGE; return SCANNER_ERR_OUT_OF_RANGE;
} }
printf("HGBaselib_path?s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str()); printf("HGBaselib_path?s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str());
Dynamicopen_HGImageprc_pHandle_ = dlopen(HGImagePrclib_path.c_str(), RTLD_LAZY); Dynamicopen_HGImageprc_pHandle_ = dlopen(HGImagePrclib_path.c_str(), RTLD_LAZY);
Dynamicopen_HGBase_pHandle_ = dlopen(HGBaselib_path.c_str(), RTLD_LAZY); Dynamicopen_HGBase_pHandle_ = dlopen(HGBaselib_path.c_str(), RTLD_LAZY);
@ -353,8 +353,8 @@ namespace hg_imgproc
HGBase_FreeImg = (SDKHGBase_FreeImage_)dlsym(Dynamicopen_HGBase_pHandle_,"HGBase_DestroyImage"); HGBase_FreeImg = (SDKHGBase_FreeImage_)dlsym(Dynamicopen_HGBase_pHandle_,"HGBase_DestroyImage");
#else #else
string scanner_path = hg_log::get_module_full_path("scanner.dll"); string scanner_path = hg_log::get_module_full_path(MODULE_NAME_SCANNER);
scanner_path = scanner_path.substr(0, scanner_path.size() - strlen("scanner.dll")); scanner_path = scanner_path.substr(0, scanner_path.size() - strlen(MODULE_NAME_SCANNER));
string HGImagePrclib_path = scanner_path + IMGPRC_LIBNANE; string HGImagePrclib_path = scanner_path + IMGPRC_LIBNANE;
string HGBaselib_path = scanner_path + HGBASE_LIBNAME; string HGBaselib_path = scanner_path + HGBASE_LIBNAME;
@ -369,8 +369,8 @@ namespace hg_imgproc
if (ret == -1) if (ret == -1)
return SCANNER_ERR_INSUFFICIENT_MEMORY; return SCANNER_ERR_INSUFFICIENT_MEMORY;
load_dll(Baselibbuffer, &Dynamicopen_HGBase_pHandle_); //鍏堝姞杞藉悗閲婃斁 load_dll(Baselibbuffer, &Dynamicopen_HGBase_pHandle_); //閸忓牆濮炴潪钘夋倵闁插﹥鏂?
load_dll(Prclibbuffer, &Dynamicopen_HGImageprc_pHandle_); //windows涓嬪彲鑳戒細鎵句笉鍒颁粬鎵€鍦ㄧ殑渚濊禆搴撳鑷寸洿鎺ユ墦寮€鍔ㄦ€佸簱鐨勬椂鍊欐壘涓嶅埌妯″潡 load_dll(Prclibbuffer, &Dynamicopen_HGImageprc_pHandle_); //windows娑撳褰查懗鎴掔窗閹靛彞绗夐崚棰佺铂閹碘偓閸︺劎娈戞笟婵婄鎼存挸顕遍懛瀵告纯閹恒儲澧﹀鈧崝銊︹偓浣哥氨閻ㄥ嫭妞傞崐娆愬娑撳秴鍩屽Ο鈥虫健
SAFE_DELETE(Prclibbuffer); SAFE_DELETE(Prclibbuffer);
SAFE_DELETE(Baselibbuffer); SAFE_DELETE(Baselibbuffer);
@ -418,7 +418,7 @@ namespace hg_imgproc
#if (!defined WIN32) #if (!defined WIN32)
ret = dlclose(Dynamicopen_HGBase_pHandle_); ret = dlclose(Dynamicopen_HGBase_pHandle_);
#else #else
ret = FreeLibrary(Dynamicopen_HGBase_pHandle_); //璨屼技鍔犺浇椤哄簭涓嶅锛屼細瀵艰嚧杩欎釜鍦版柟鐨勬閿侊紵锛燂紵 ret = FreeLibrary(Dynamicopen_HGBase_pHandle_); //鐠ㄥ奔鎶€閸旂姾娴囨い鍝勭碍娑撳秴顕敍灞肩窗鐎佃壈鍤ф潻娆庨嚋閸︾増鏌熼惃鍕劥闁夸緤绱甸敍鐕傜吹
#endif #endif
Dynamicopen_HGBase_pHandle_ = NULL; Dynamicopen_HGBase_pHandle_ = NULL;
} }
@ -431,13 +431,25 @@ namespace hg_imgproc
int ret = SCANNER_ERR_OK; int ret = SCANNER_ERR_OK;
float scale = img_conf_.fillhole.fillholeratio / 100.0; float scale = img_conf_.fillhole.fillholeratio / 100.0;
float val = img_conf_.resolution_dst / 10; int dpi = img_conf_.resolution_dst;
if (!param_.is_sup_real_300dpi_ && !param_.is_sup_real_600dpi_)
{
dpi = 200;
}
else if (param_.is_sup_real_300dpi_ && !param_.is_sup_real_600dpi_)
{
if (dpi >= 300)
dpi = 300;
}
float val = dpi / 10;
cv::Vec4f edgeScale; cv::Vec4f edgeScale;
edgeScale[0] = top; edgeScale[0] = top;
edgeScale[1] = low; edgeScale[1] = low;
edgeScale[2] = l; edgeScale[2] = l;
edgeScale[3] = r; edgeScale[3] = r;
CImageApplyOutHole outh(val, edgeScale, 50); CImageApplyOutHole outh(val, edgeScale, 20);
outh.apply(v, true); outh.apply(v, true);
if (v.empty()) if (v.empty())
{ {
@ -521,40 +533,55 @@ namespace hg_imgproc
else else
mat = m_dst.clone(); mat = m_dst.clone();
cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat); float vratio = 0.0;
float hratio = 0.0;
//cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
int dpi = param_.dpi == 600 ? 3 : (param_.dpi < 599 && param_.dpi >= 300) ? 2 : 1; int dpi = param_.dpi == 600 ? 3 : (param_.dpi < 599 && param_.dpi >= 300) ? 2 : 1;
int mode = param_.color_mode == COLOR_MODE_24_BITS ? 1 : 0; int mode = param_.color_mode == COLOR_MODE_24_BITS ? 1 : 0;
for (auto it : correction_image_map_) for (auto it : correction_image_map_)
{ {
if (img_conf_.removeMorr && param_.dpi != 600) //除摩尔纹 使用300dpi校正数据
{
if (it.second.info.params.dpi == 2 && it.second.info.params.colormode == mode)
{
if (it.second.info.params.status != 100)
break;
vratio = it.second.vratio;
hratio = it.second.hratio;
correctColor(mat, it.second.flat_lut);
break;
}
continue;
}
if (it.second.info.params.colormode == mode && it.second.info.params.dpi == dpi) if (it.second.info.params.colormode == mode && it.second.info.params.dpi == dpi)
{ {
if (it.second.info.params.status != 100) if (it.second.info.params.status != 100)
{ {
break; break;
} }
vratio = it.second.vratio;
hratio = it.second.hratio;
correctColor(mat, it.second.flat_lut);//校正 correctColor(mat, it.second.flat_lut);//校正
break;
} }
} }
//for (size_t i = 0; i < correction_image_map_.size(); i++)
//{
// if (correction_image_map_[i].info.params.colormode == mode && correction_image_map_[i].info.params.dpi == dpi)
// {
// if (correction_image_map_[i].info.params.status != 100)
// {
// continue;
// }
// correctColor(mat, correction_image_map_[i].flat_lut);//校正
// }
//}
//cv::imwrite("C:\\image\\imdecode" + std::to_string(img_idx++) + ".jpg", mat);
//if (param_.dpi < 299)/////7010不支持 200dpi 所以需要手动拉伸宽度 if (!(vratio >= 0.8f && vratio <= 1.20f && hratio > 0.8f && hratio < 1.2f))
//{ vratio = hratio = 1.0f;
// float xy = param_.dpi / 300.0;
// cv::resize(mat, mat, cv::Size(), xy, 1);
//} if (dpi == 1 && img_conf_.removeMorr)
hratio = (200.0 / 300.0) * hratio;
if (img_conf_.removeMorr && dpi != 3)
vratio = dpi == 1 ? vratio * 0.5 : vratio * 0.75; //0.5 = 200/400 0.75= 300/400
if (img_conf_.removeMorr)
resize(mat, mat, cv::Size(0, 0), hratio, vratio, cv::InterpolationFlags::INTER_AREA);
else
resize(mat, mat, cv::Size(0, 0), hratio, vratio);
} }
//cv::imwrite("C:\\image\\imdecode4.png", mat); //cv::imwrite("C:\\image\\imdecode4.png", mat);
@ -712,7 +739,7 @@ namespace hg_imgproc
mats_.clear(); mats_.clear();
CImageApplyFadeBackGroudColor fade(40, 0, img_conf_.fadebackrange); CImageApplyFadeBackGroudColor fade(20, 255, img_conf_.fadebackrange);
for(size_t i = 0; i < mats.size();i++) for(size_t i = 0; i < mats.size();i++)
{ {
fade.apply(mats[i],img_conf_.is_duplex); fade.apply(mats[i],img_conf_.is_duplex);
@ -731,13 +758,13 @@ namespace hg_imgproc
} }
return SCANNER_ERR_OK; return SCANNER_ERR_OK;
} }
int multi_out(int out_type) int multi_out(int out_type, int bw_threshold)
{ {
std::vector<cv::Mat> mats(mats_); std::vector<cv::Mat> mats(mats_);
std::vector<cv::Mat> mat; std::vector<cv::Mat> mat;
mats_.clear(); mats_.clear();
IMageMulti output(out_type); IMageMulti output(out_type, bw_threshold);
for(size_t i = 0;i < mats.size();i++) for(size_t i = 0;i < mats.size();i++)
{ {
@ -815,7 +842,7 @@ namespace hg_imgproc
SIZE temp_Size = papersize_.GetPaperSize(img_conf_.papertype, dpi,img_conf_.paperAlign); SIZE temp_Size = papersize_.GetPaperSize(img_conf_.papertype, dpi,img_conf_.paperAlign);
cv::Size cvSize(temp_Size.cx, temp_Size.cy); cv::Size cvSize(temp_Size.cx, temp_Size.cy);
CImageApplyAutoCrop crop(img_conf_.is_autocrop,img_conf_.autodescrew,img_conf_.fillbackground,cvSize,img_conf_.is_convex,img_conf_.isfillcolor); CImageApplyAutoCrop crop(img_conf_.is_autocrop,img_conf_.autodescrew,img_conf_.fillbackground,cvSize,img_conf_.is_convex,img_conf_.isfillcolor, 30,img_conf_.noise,img_conf_.indent);
crop.apply(mats,img_conf_.is_duplex); crop.apply(mats,img_conf_.is_duplex);
mats_ = mats; mats_ = mats;
@ -827,6 +854,26 @@ namespace hg_imgproc
} }
return SCANNER_ERR_OK; return SCANNER_ERR_OK;
} }
int dispersion()
{
int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_);
mats_.clear();
CImageApplyDispersion disp;
for (int i = 0; i < mats.size(); ++i)
{
disp.apply(mats[i], 0);
mats_.push_back(mats[i]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
int fillhole(float top,float low,float l,float r) int fillhole(float top,float low,float l,float r)
{ {
int ret = SCANNER_ERR_OK; int ret = SCANNER_ERR_OK;
@ -840,7 +887,7 @@ namespace hg_imgproc
edgeScale[1] = low; edgeScale[1] = low;
edgeScale[2] = l; edgeScale[2] = l;
edgeScale[3] = r; edgeScale[3] = r;
CImageApplyOutHole outh(val, edgeScale,50); CImageApplyOutHole outh(val, edgeScale, 20);
outh.apply(mats,img_conf_.is_duplex); outh.apply(mats,img_conf_.is_duplex);
mats_ = mats; mats_ = mats;
@ -962,7 +1009,7 @@ namespace hg_imgproc
std::vector<cv::Mat> mats(mats_); std::vector<cv::Mat> mats(mats_);
mats_.clear(); mats_.clear();
CImageApplyRefuseInflow Inflow(permeate_lv); CImageApplyRefuseInflow Inflow(20, permeate_lv);
for (size_t i = 0; i < mats.size(); ++i) for (size_t i = 0; i < mats.size(); ++i)
{ {
Inflow.apply(mats[i],img_conf_.is_duplex); Inflow.apply(mats[i],img_conf_.is_duplex);
@ -1109,7 +1156,7 @@ namespace hg_imgproc
return SCANNER_ERR_OK; return SCANNER_ERR_OK;
} }
int errorextention() int errorextention(int bw_threshold)
{ {
int ret = SCANNER_ERR_OK; int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_); std::vector<cv::Mat> mats(mats_);
@ -1121,7 +1168,7 @@ namespace hg_imgproc
else else
thrtype = CImageApplyBWBinaray::ThresholdType::THRESH_BINARY; thrtype = CImageApplyBWBinaray::ThresholdType::THRESH_BINARY;
CImageApplyBWBinaray BWBinaray(thrtype); CImageApplyBWBinaray BWBinaray(thrtype, bw_threshold);
for (size_t i = 0; i < mats.size(); ++i) for (size_t i = 0; i < mats.size(); ++i)
{ {
BWBinaray.apply(mats[i],img_conf_.is_duplex); BWBinaray.apply(mats[i],img_conf_.is_duplex);
@ -1140,7 +1187,7 @@ namespace hg_imgproc
mats_.clear(); mats_.clear();
double threshold = 40; double threshold = 40;
int edge = 30; int edge = 100;
int dis = img_conf_.discardblank_percent; int dis = img_conf_.discardblank_percent;
if (img_conf_.is_autodiscradblank_vince) if (img_conf_.is_autodiscradblank_vince)
dis *= 1.5; dis *= 1.5;
@ -1183,7 +1230,7 @@ namespace hg_imgproc
std::vector<cv::Mat> mats(mats_); std::vector<cv::Mat> mats(mats_);
mats_.clear(); mats_.clear();
CImageApplyConcatenation fold((CImageApplyConcatenation::ConcatMode)img_conf_.fold_concatmode); CImageApplyConcatenation fold((CImageApplyConcatenation::ConcatMode)img_conf_.fold_concatmode, cv::Scalar(255, 255, 255));
fold.apply(mats,img_conf_.is_duplex); fold.apply(mats,img_conf_.is_duplex);
mats_= mats; mats_= mats;
@ -1396,11 +1443,35 @@ namespace hg_imgproc
int ret = SCANNER_ERR_OK; int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_); std::vector<cv::Mat> mats(mats_);
mats_.clear(); mats_.clear();
CImageApplyColorCastCorrect ColorCastCorrect(1);
int tmp = -1;
CImageApplyColorCastCorrect::PreScheme deviceType = (CImageApplyColorCastCorrect::PreScheme)tmp;
if (param_.device_7010)
deviceType = CImageApplyColorCastCorrect::G300_7010;
if (0x300 == pid_)
{
deviceType = CImageApplyColorCastCorrect::G300_D8;
}
else if (0x400 == pid_)
{
deviceType = CImageApplyColorCastCorrect::G400_3288;
}
else if (0x402 == pid_)
{
deviceType = CImageApplyColorCastCorrect::G400_402;
}
else if (0x302 == pid_)
{
deviceType = CImageApplyColorCastCorrect::Android302;
}
CImageApplyColorCastCorrect ColorCastCorrect(deviceType);
ColorCastCorrect.apply(mats, true);
//cv::imwrite(to_string(i) + "cis_test_image.jpg", mats[i]); //cv::imwrite(to_string(i) + "cis_test_image.jpg", mats[i]);
ColorCastCorrect.apply(mats,true);
mats_ = mats; mats_ = mats;
if (mats_.empty()) if (mats_.empty())
@ -1410,7 +1481,14 @@ namespace hg_imgproc
return ret; return ret;
//cv::imwrite("CISTestImageProcess.jpg",mats[i]); //cv::imwrite("CISTestImageProcess.jpg",mats[i]);
} }
int lost_frame_test()
{
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return LineContinuityDetection::isContinuous(mats_[0], 100); //妫€娴嬩竴闈㈠氨琛?
}
int correction_image(cv::Mat &flat_lut, cv::Mat black_mat, cv::Mat white_mat) int correction_image(cv::Mat &flat_lut, cv::Mat black_mat, cv::Mat white_mat)
{ {
flat_lut = creatLUTData(black_mat, white_mat);//计算LUT 查值表 flat_lut = creatLUTData(black_mat, white_mat);//计算LUT 查值表
@ -1425,7 +1503,7 @@ namespace hg_imgproc
info.width = mats.cols; info.width = mats.cols;
info.origin = HGBASE_IMGORIGIN_TOP; info.origin = HGBASE_IMGORIGIN_TOP;
int bits = mats.channels() == 1 ? 8 : 24; int bits = mats.channels() == 1 ? 8 : 24;
info.widthStep = mats.step; //opencv鍘熷鍊? info.widthStep = mats.step; //opencv閸樼喎顫愰崐?
info.type = mats.channels() == 1 ? HGBASE_IMGTYPE_GRAY : HGBASE_IMGTYPE_BGR; info.type = mats.channels() == 1 ? HGBASE_IMGTYPE_GRAY : HGBASE_IMGTYPE_BGR;
int ret = HGBase_CreatImg(const_cast<uchar*>(mats.data), &info, &image); int ret = HGBase_CreatImg(const_cast<uchar*>(mats.data), &info, &image);
@ -1437,13 +1515,13 @@ namespace hg_imgproc
/// <summary> /// <summary>
/// 8浣嶅浘杞?浣嶅浘 /// 8娴e秴娴樻潪?娴e秴娴?
/// </summary> /// </summary>
/// <param name="image">8bit?/param> /// <param name="image">8bit?/param>
/// <param name="threshold">闃堝€硷紝寤鸿榛樿127</param> /// <param name="threshold">闂冨牆鈧》绱濆楦款唴姒涙顓?27</param>
/// <param name="reverse">true涓哄弽鑹诧紝鍗抽粦0鐧?锛涘弽涔嬩害鐒?/param> /// <param name="reverse">true娑撳搫寮介懝璇х礉閸楁娊绮?閻?閿涙稑寮芥稊瀣╁閻?/param>
/// <param name="align">true涓哄洓瀛楄妭瀵归綈</param> /// <param name="align">true娑撳搫娲撶€涙濡€靛綊缍?/param>
/// <returns>1浣嶅浘</returns> /// <returns>1娴e秴娴?/returns>
/// ///
static cv::Mat convert_8bit_2_1bit(const cv::Mat& image, uchar threshold, bool reverse, bool align) static cv::Mat convert_8bit_2_1bit(const cv::Mat& image, uchar threshold, bool reverse, bool align)
{ {
@ -1737,7 +1815,7 @@ namespace hg_imgproc
#define GAMMA_EX 1.7f #define GAMMA_EX 1.7f
#define BLACK_OFFSET 0 #define BLACK_OFFSET 8
void fittingLUT(const std::vector<unsigned char>& points, unsigned char min_value, unsigned char max_value, unsigned char* data) void fittingLUT(const std::vector<unsigned char>& points, unsigned char min_value, unsigned char max_value, unsigned char* data)
{ {
@ -1753,7 +1831,7 @@ namespace hg_imgproc
float temp; float temp;
for (int j = 0, length = (255 - b + 1); j < length; j++) for (int j = 0, length = (255 - b + 1); j < length; j++)
{ {
temp = tb + step * j;// gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET; temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;//tb + step * j;//
data[j + b] = (cv::min)(255, (cv::max)(0, static_cast<int>(temp))); data[j + b] = (cv::min)(255, (cv::max)(0, static_cast<int>(temp)));
} }
} }
@ -1813,7 +1891,7 @@ namespace hg_imgproc
memcpy(lutROI.data, tran.data, tran.total()); memcpy(lutROI.data, tran.data, tran.total());
} }
cv::imwrite("C:\\image\\" + std::to_string(lut_idx++) + ".bmp", lut); //cv::imwrite("C:\\image\\" + std::to_string(lut_idx++) + ".bmp", lut);
return lut; return lut;
} }
@ -1915,9 +1993,9 @@ namespace hg_imgproc
{ {
return ((imgproc*)himg)->fadeback(); return ((imgproc*)himg)->fadeback();
} }
int multi_out(HIMGPRC himg,int out_type) int multi_out(HIMGPRC himg, int out_type, int bw_threshold)
{ {
return ((imgproc*)himg)->multi_out(out_type); return ((imgproc*)himg)->multi_out(out_type, bw_threshold);
} }
int multi_out_red(HIMGPRC himg) int multi_out_red(HIMGPRC himg)
{ {
@ -1931,6 +2009,10 @@ namespace hg_imgproc
{ {
return ((imgproc*)himg)->auto_crop(dpi); return ((imgproc*)himg)->auto_crop(dpi);
} }
int dispersion(HIMGPRC himg)
{
return ((imgproc*)himg)->dispersion();
}
int fillhole(HIMGPRC himg, float top, float low, float l, float r) int fillhole(HIMGPRC himg, float top, float low, float l, float r)
{ {
return ((imgproc*)himg)->fillhole(top, low, l,r); return ((imgproc*)himg)->fillhole(top, low, l,r);
@ -1979,9 +2061,9 @@ namespace hg_imgproc
{ {
return ((imgproc*)himg)->nosieDetach(); return ((imgproc*)himg)->nosieDetach();
} }
int errorextention(HIMGPRC himg) int errorextention(HIMGPRC himg, int bw_threshold)
{ {
return ((imgproc*)himg)->errorextention(); return ((imgproc*)himg)->errorextention(bw_threshold);
} }
int discardBlank(HIMGPRC himg) int discardBlank(HIMGPRC himg)
{ {
@ -2024,6 +2106,11 @@ namespace hg_imgproc
{ {
return ((imgproc*)himg)->color_cast_correction(); return ((imgproc*)himg)->color_cast_correction();
} }
int lost_frame_test(HIMGPRC himg)
{
return ((imgproc*)himg)->lost_frame_test();
return 0;
}
int final(HIMGPRC himg) int final(HIMGPRC himg)
{ {
return ((imgproc*)himg)->final(); return ((imgproc*)himg)->final();

View File

@ -153,6 +153,8 @@ namespace hg_imgproc
int width; // in pixel int width; // in pixel
int height; // in pixel int height; // in pixel
unsigned total_bytes;// total bytes unsigned total_bytes;// total bytes
bool is_sup_real_300dpi_;
bool is_sup_real_600dpi_;
bool device_7010; bool device_7010;
}IMGPRCPARAM, *LPIMGPRCPARAM; }IMGPRCPARAM, *LPIMGPRCPARAM;
typedef struct _img_header typedef struct _img_header
@ -180,10 +182,11 @@ namespace hg_imgproc
//拆分 //拆分
int split(HIMGPRC himg,int split3399); int split(HIMGPRC himg,int split3399);
int fadeback(HIMGPRC himg); int fadeback(HIMGPRC himg);
int multi_out(HIMGPRC himg,int out_type); int multi_out(HIMGPRC himg,int out_type, int bw_threshold);
int multi_out_red(HIMGPRC himg); int multi_out_red(HIMGPRC himg);
int auto_matic_color(HIMGPRC himg,int color_type); int auto_matic_color(HIMGPRC himg,int color_type);
int auto_crop(HIMGPRC himg, float dpi); int auto_crop(HIMGPRC himg, float dpi);
int dispersion(HIMGPRC himg);
int fillhole(HIMGPRC himg, float top, float low, float r, float l); int fillhole(HIMGPRC himg, float top, float low, float r, float l);
int resolution_change(HIMGPRC himg,float dpi3288); int resolution_change(HIMGPRC himg,float dpi3288);
int croprect(HIMGPRC himg); int croprect(HIMGPRC himg);
@ -196,7 +199,7 @@ namespace hg_imgproc
int remove_morr(HIMGPRC himg); int remove_morr(HIMGPRC himg);
int sharpenType(HIMGPRC himg); int sharpenType(HIMGPRC himg);
int nosieDetach(HIMGPRC himg); int nosieDetach(HIMGPRC himg);
int errorextention(HIMGPRC himg); int errorextention(HIMGPRC himg, int bw_threshold);
int discardBlank(HIMGPRC himg); int discardBlank(HIMGPRC himg);
int answerSheetFilterRed(HIMGPRC himg); int answerSheetFilterRed(HIMGPRC himg);
int imgtypechange(HIMGPRC himg,std::string img_type_,void *buf,std::vector<unsigned char> &bmpdata); int imgtypechange(HIMGPRC himg,std::string img_type_,void *buf,std::vector<unsigned char> &bmpdata);
@ -207,6 +210,7 @@ namespace hg_imgproc
int size_detection(HIMGPRC himg); int size_detection(HIMGPRC himg);
int cis_test_image(HIMGPRC himg, CISTestImageProcess::CISTestResult& res); int cis_test_image(HIMGPRC himg, CISTestImageProcess::CISTestResult& res);
int color_cast_correction(HIMGPRC himg); int color_cast_correction(HIMGPRC himg);
int lost_frame_test(HIMGPRC himg);
int final(HIMGPRC himg); int final(HIMGPRC himg);

View File

@ -16,6 +16,7 @@
#include "hg_scanner_239.h" #include "hg_scanner_239.h"
#include "hg_scanner_300.h" #include "hg_scanner_300.h"
#include "hg_scanner_302.h" #include "hg_scanner_302.h"
#include "hg_scanner_306.h"
/// <summary> /// <summary>
@ -46,6 +47,7 @@ g_supporting_devices[] = {
, {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439} , {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439}
, {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100}
, {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239} , {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239}
, {0x31c9, PID_AND_NAME(8630, SCANNER_NAME_LSC_G63S), "G63S", "", &hg_scanner_mgr::create_scanner_g239}
, {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100}
, {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239} , {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239}
#endif #endif
@ -72,22 +74,35 @@ g_supporting_devices[] = {
#elif defined(OEM_ZHONGJING) #elif defined(OEM_ZHONGJING)
{0X05DA, 0x9220, SCANNER_NAME_ZJ_6500, "S6570", "",& hg_scanner_mgr::create_scanner_g439} {0X05DA, 0x9220, SCANNER_NAME_ZJ_6570, "S6570", "",& hg_scanner_mgr::create_scanner_g439}
, {0X05DA, 0x9222, SCANNER_NAME_ZJ_8790, "S8790", "",& hg_scanner_mgr::create_scanner_g239}
, {0X05DA, 0x9223, SCANNER_NAME_ZJ_500DC, "S500DC", "",& hg_scanner_mgr::create_scanner_g239}
#elif defined(OEM_ZIGUANG) #elif defined(OEM_ZIGUANG)
{0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"Q7110", "", & hg_scanner_mgr::create_scanner_g239} {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"Q7110", "", & hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "Q1070", "", &hg_scanner_mgr::create_scanner_g402} , {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "Q1070", "", &hg_scanner_mgr::create_scanner_g402}
#elif defined(OEM_NEUTRAL) #elif defined(OEM_NEUTRAL)
{0x3072, PID_AND_NAME(100, SCANNER_NAME_HGNEU_G100), "G100", "",& hg_scanner_mgr::create_scanner_g100}
, {0x3072, PID_AND_NAME(139, SCANNER_NAME_HGNEU_G100), "G100", "", &hg_scanner_mgr::create_scanner_g239}
, {0x3072, PID_AND_NAME(200, SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} {0x3072, PID_AND_NAME(100, SCANNER_NAME_HG_G100), "G100", "",& hg_scanner_mgr::create_scanner_g100}
, {0x3072, PID_AND_NAME(239, SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, PID_AND_NAME(139, SCANNER_NAME_HG_G100), "G100", "", &hg_scanner_mgr::create_scanner_g239}
, {0x3072, PID_AND_NAME(300, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300} , {0x3072, PID_AND_NAME(200, SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
, {0x3072, PID_AND_NAME(302, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_g302} , {0x3072, PID_AND_NAME(239, SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g239}
, {0x3072, PID_AND_NAME(339, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_empty} , {0x3072, PID_AND_NAME(300, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
, {0x3072, PID_AND_NAME(400, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400} , {0x3072, PID_AND_NAME(302, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g302}
, {0x3072, PID_AND_NAME(402, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402} , {0x3072, PID_AND_NAME(339, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_empty}
, {0x3072, PID_AND_NAME(439, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439} , {0x3072, PID_AND_NAME(400, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} , {0x3072, PID_AND_NAME(402, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402}
, {0x3072, PID_AND_NAME(439, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439}
, {0x3072, PID_AND_NAME(306, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g306}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G400", "", &hg_scanner_mgr::create_scanner_g400}
, {0x31c9, PID_AND_NAME(8426, SCANNER_NAME_LSC_G42S), "G4245F", "",& hg_scanner_mgr::create_scanner_g300}
, {0x31c9, PID_AND_NAME(8626, SCANNER_NAME_LSC_G62S), "G6290U", "", &hg_scanner_mgr::create_scanner_g239}
, {0x31c9, PID_AND_NAME(8200, SCANNER_NAME_LSC_G42S), "G42S", "",& hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8200, SCANNER_NAME_LSC_G42S), "G42S", "",& hg_scanner_mgr::create_scanner_g300}
, {0x31c9, PID_AND_NAME(8420, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8420, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_g300}
, {0x31c9, PID_AND_NAME(8429, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_empty} , {0x31c9, PID_AND_NAME(8429, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_empty}
@ -95,16 +110,44 @@ g_supporting_devices[] = {
, {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439} , {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439}
, {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100}
, {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239} , {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239}
, {0x31c9, PID_AND_NAME(8630, SCANNER_NAME_LSC_G63S), "G63S", "", &hg_scanner_mgr::create_scanner_g239}
, {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100}
, {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239} , {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"", "",& hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "", "", &hg_scanner_mgr::create_scanner_g402}
, {0X05DA, 0x9220, SCANNER_NAME_ZJ_6500, "S6500", "",&hg_scanner_mgr::create_scanner_g439} , {0x2903, 0x1000, SCANNER_NAME_HW_1000, SCANNER_NAME_HW_1000, "",& hg_scanner_mgr::create_scanner_g300} // "HW-1060A"
, {0x3308, 0x6006, SCANNER_NAME_CT_9020, SCANNER_NAME_CT_9020, "",& hg_scanner_mgr::create_scanner_g239} , {0x2903, 0x1002, SCANNER_NAME_HW_1002, SCANNER_NAME_HW_1002, "", &hg_scanner_mgr::create_scanner_g302} // "HW-1060A"
, {0x2903, 0x7000, SCANNER_NAME_HW_7000, SCANNER_NAME_HW_7000, "", &hg_scanner_mgr::create_scanner_g400} // "HW-74x0WA"
, {0x2903, 0x7002, SCANNER_NAME_HW_7002, SCANNER_NAME_HW_7002, "", &hg_scanner_mgr::create_scanner_g402} // "HW-7002"
, {0x2903, 0x7039, SCANNER_NAME_HW_7039, SCANNER_NAME_HW_7039, "", &hg_scanner_mgr::create_scanner_g439} // "HW-7039F"
, {0x2903, 0x8000, SCANNER_NAME_HW_8000, SCANNER_NAME_HW_8000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-8090F"
, {0x2903, 0x9000, SCANNER_NAME_HW_9000, SCANNER_NAME_HW_9000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-9110E"
, {0x3072, 0x0303, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "",& hg_scanner_mgr::create_scanner_g300}
, {0x3072, 0x0403, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g439}
, {0x3072, 0x0138, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x0238, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x0138, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x0238, SCANNER_NAME_CT_238, SCANNER_NAME_CT_238, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x6006, SCANNER_NAME_CT_9020, SCANNER_NAME_CT_9020, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x6005, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300} , {0x3308, 0x6005, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300}
, {0x3308, 0x0238, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x0138, SCANNER_NAME_CT_238, SCANNER_NAME_CT_238, "", &hg_scanner_mgr::create_scanner_g239} , {0X05DA, 0x9220, SCANNER_NAME_ZJ_6570, "S6570", "",& hg_scanner_mgr::create_scanner_g439}
, {0x3072, 0x0303, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300} , {0X05DA, 0x9222, SCANNER_NAME_ZJ_8790, "S8790", "",&hg_scanner_mgr::create_scanner_g239}
, {0X05DA, 0x9223, SCANNER_NAME_ZJ_500DC, "S500DC", "",&hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"Q7110", "",& hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "Q1070", "", &hg_scanner_mgr::create_scanner_g402}
, { 0x300E, PID_AND_NAME(401C, SANNER_NAME_DL_S3000), "S3000", "", &hg_scanner_mgr::create_scanner_g239 }
, { 0x300E, PID_AND_NAME(4020, SANNER_NAME_DL_S3400), "S3000", "", &hg_scanner_mgr::create_scanner_g239 }
, { 0x300E, PID_AND_NAME(4015, SANNER_NAME_DL_S2000), "S2000", "", &hg_scanner_mgr::create_scanner_g300 }
, { 0x300E, PID_AND_NAME(4019, SANNER_NAME_DL_DL9000), "DL9000", "", &hg_scanner_mgr::create_scanner_g439 }
#elif defined(OEM_DELI) #elif defined(OEM_DELI)
{0x300E, PID_AND_NAME(401C, SANNER_NAME_DL_S3000), "S3000", "", &hg_scanner_mgr::create_scanner_g239} {0x300E, PID_AND_NAME(401C, SANNER_NAME_DL_S3000), "S3000", "", &hg_scanner_mgr::create_scanner_g239}
, {0x300E, PID_AND_NAME(4020, SANNER_NAME_DL_S3400), "S3000", "", &hg_scanner_mgr::create_scanner_g239} , {0x300E, PID_AND_NAME(4020, SANNER_NAME_DL_S3400), "S3000", "", &hg_scanner_mgr::create_scanner_g239}
@ -121,9 +164,11 @@ g_supporting_devices[] = {
, {0x3072, PID_AND_NAME(400, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400} , {0x3072, PID_AND_NAME(400, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
, {0x3072, PID_AND_NAME(402, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402} , {0x3072, PID_AND_NAME(402, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402}
, {0x3072, PID_AND_NAME(439, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439} , {0x3072, PID_AND_NAME(439, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439}
, {0x3072, PID_AND_NAME(306, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g306}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G100), "G100", "", &hg_scanner_mgr::create_scanner_g100}
, {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400}
#endif #endif
}; };
@ -348,6 +393,15 @@ hg_scanner* hg_scanner_mgr::create_scanner_g439(const char* name, usb_io* io, sc
return dynamic_cast<hg_scanner*>(s); return dynamic_cast<hg_scanner*>(s);
} }
hg_scanner* hg_scanner_mgr::create_scanner_g306(const char* name, usb_io* io, scanner_handle* h)
{
hg_scanner_306* s = new hg_scanner_306(name, 0x300, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
void hg_scanner_mgr::usb_event_handle(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l void hg_scanner_mgr::usb_event_handle(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l
{ {
hg_scanner_mgr* obj = (hg_scanner_mgr*)user; hg_scanner_mgr* obj = (hg_scanner_mgr*)user;
@ -407,14 +461,14 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
size_t i = 0; size_t i = 0;
for (; i < online_devices_.size(); ++i) for (; i < online_devices_.size(); ++i)
{ {
if (online_devices_[i].dev == device) // 濮濄倕顦╅崑鍥х暰閸氬奔绔撮崣鎷岊啎婢跺洭鍣搁弬鎷岀箾閹恒儱鎮楅敍宀冾啎婢跺洤顕挒鈾€鈧竸evice閳ユ繀绻氶幐浣风瑝閸欐﹫绱辨俊鍌涚亯閸嬪洩顔曟稉宥嗗灇缁斿绱濇导姘嚤閼风顔曟径鍥櫢鏉╃偞绉烽幁顖欑瑝閼宠姤顒滅敮鍛婂复閺€璁圭礉缂佹垵鐣鹃崚鎷岊嚉鐠佹儳顦惃鍓哻anner鐎电钖勫妞剧瑝閸掍即鍣撮弨? if (online_devices_[i].dev == device) // 濮濄倕顦╅å´é<EFBFBD>¥Ñ…æš°é¸æ°¬å¥”ç»”æ®å´£éŽ·å²Šå•Žå©¢è·ºæ´­é<EFBFBD>£æ<EFBFBD><EFBFBD>弬鎷岀箾é¹æ<EFBFBD>儱鎮楅æ•<EFBFBD>宀冾啎婢跺洤顕æŒéˆ¾â¬éˆ§î„<EFBFBD>竸eviceé³ãƒ¦ç¹€ç»»æ°¶å¹<EFBFBD>浣风ç<EFBFBD>é¸æ¬<EFBFBD>﹫绱辨俊é<EFBFBD>Œæ¶šäº¯é¸å¬ªæ´©é¡”æŸç¨‰å®¥å——ç<EFBFBD>‡ç¼<EFBFBD>æ¿îƒç»±æ¿‡å¯¼å§˜î„‰åš¤é¼é£Žî—<EFBFBD>é¡”æŸå¾„é<EFBFBD>¥î„€æ«¢é<EFBFBD>‰â•ƒå<EFBFBD>žç»‰çƒ½å¹<EFBFBD>é¡æ¬ç<EFBFBD>é¼å® å§¤é¡æ»…æ•®é<EFBFBD>å©å¤<EFBFBD>éºâ¬ç<EFBFBD>圭礉ç¼ä½¹åžµé<EFBFBD>£é¹ƒå´šéŽ·å²Šåš‰é<EFBFBD> ä½¹å„³é¡¦î„„惃é<EFBFBD>“å“»anneré<EFBFBD>Žç”µî”Šéå«î‡¥å¦žå‰§ç<EFBFBD>é¸æŽ<EFBFBD>å<EFBFBD>³é<EFBFBD>£æ®å¼?
{ {
online_devices_[i].ind = index; online_devices_[i].ind = index;
add = false; add = false;
break; break;
} }
} }
if (add) // 婢跺嫮鎮婄€电钖勯垾娓別vice閳ユ繃鏁奸崣妯兼畱閹懏娅? if (add) // 婢跺嫮鎮婄â¬ç”µî”Šéå¯åž¾å¨“別viceé³ãƒ¦ç¹ƒé<EFBFBD><EFBFBD>奸崣妯兼畱é¹îˆšæ‡<EFBFBD>å¨?
{ {
i = 0; i = 0;
for (auto& v : online_devices_) for (auto& v : online_devices_)
@ -732,6 +786,11 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
ret = (scanner_err)usb_manager::instance()->open(it->dev, &io, &hg_scanner_mgr::last_open_msg_); ret = (scanner_err)usb_manager::instance()->open(it->dev, &io, &hg_scanner_mgr::last_open_msg_);
if (ret == SCANNER_ERR_OK) if (ret == SCANNER_ERR_OK)
{ {
if (io->get_ver() > 1)
{
// new version ...
}
hg_scanner* scanner = g_supporting_devices[it->ind].create_scanner(it->display_name.c_str(), io, h); hg_scanner* scanner = g_supporting_devices[it->ind].create_scanner(it->display_name.c_str(), io, h);
if (!scanner) if (!scanner)
{ {
@ -751,6 +810,7 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
g_supporting_devices[it->ind].pid == 0x9000 || g_supporting_devices[it->ind].pid == 0x9000 ||
g_supporting_devices[it->ind].pid == 0x8739 || g_supporting_devices[it->ind].pid == 0x8739 ||
g_supporting_devices[it->ind].pid == 0x8629 || g_supporting_devices[it->ind].pid == 0x8629 ||
g_supporting_devices[it->ind].pid == 0x8630 ||
g_supporting_devices[it->ind].pid == 0x0439 || g_supporting_devices[it->ind].pid == 0x0439 ||
g_supporting_devices[it->ind].pid == 0x7039 || g_supporting_devices[it->ind].pid == 0x7039 ||
g_supporting_devices[it->ind].pid == 0x8529) g_supporting_devices[it->ind].pid == 0x8529)
@ -780,6 +840,16 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
if (scanner) if (scanner)
{ {
int devStatus = scanner->status();
if (SCANNER_ERR_OK != devStatus)
{
io->release();
*h = NULL;
delete scanner;
scanner = nullptr;
return (scanner_err)devStatus;
}
scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_); scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_);
scanner->set_dev_family(g_supporting_devices[it->ind].type.c_str()); scanner->set_dev_family(g_supporting_devices[it->ind].type.c_str());
scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_); scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_);
@ -790,8 +860,8 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
if (ptr != online_devices_.end()) if (ptr != online_devices_.end())
ptr->scanner = (hg_scanner*)*h; ptr->scanner = (hg_scanner*)*h;
} }
else if(hg_scanner_mgr::last_open_msg_.length()) //else if(hg_scanner_mgr::last_open_msg_.length())
hg_scanner_mgr::ui_default_callback(nullptr, SANE_EVENT_ERROR, (void*)hg_scanner_mgr::last_open_msg_.c_str(), (unsigned int*)&ret, nullptr); // hg_scanner_mgr::ui_default_callback(nullptr, SANE_EVENT_ERROR, (void*)hg_scanner_mgr::last_open_msg_.c_str(), (unsigned int*)&ret, nullptr);
if(io) if(io)
io->release(); io->release();
@ -813,6 +883,7 @@ scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force)
} }
} }
//SCAN_PTR(h)->stop(); //shield on 2023.12.13,BUG-853
SCAN_PTR(h)->close(force); SCAN_PTR(h)->close(force);
delete SCAN_PTR(h); delete SCAN_PTR(h);
@ -1056,11 +1127,17 @@ scanner_err hg_scanner_mgr::hg_scanner_start(scanner_handle h, void* async_event
} }
scanner_err hg_scanner_mgr::hg_scanner_stop(scanner_handle h) scanner_err hg_scanner_mgr::hg_scanner_stop(scanner_handle h)
{ {
return (scanner_err)SCAN_PTR(h)->stop(); scanner_err err = (scanner_err)SCAN_PTR(h)->stop();
// call from APP, block when all working-threads stopped - added on 2023-10-18 when handled double-feeding in SANE
while (SCAN_PTR(h)->is_running() != hg_scanner::THREAD_RUNNING_IDLE)
std::this_thread::sleep_for(std::chrono::milliseconds(3));
return err;
} }
scanner_err hg_scanner_mgr::hg_scanner_get_img_info(scanner_handle h, SANE_Parameters* bmi, long len) scanner_err hg_scanner_mgr::hg_scanner_get_img_info(scanner_handle h, SANE_Parameters* bmi, long len)
{ {
return (scanner_err)SCAN_PTR(h)->get_image_info(bmi); return (scanner_err)SCAN_PTR(h)->get_image_info(bmi, (int)len);
} }
scanner_err hg_scanner_mgr::hg_scanner_read_img_data(scanner_handle h, unsigned char* data, long* len) scanner_err hg_scanner_mgr::hg_scanner_read_img_data(scanner_handle h, unsigned char* data, long* len)
{ {

View File

@ -120,6 +120,7 @@ public:
static hg_scanner* create_scanner_g400(const char* name, usb_io* io, scanner_handle* h); static hg_scanner* create_scanner_g400(const char* name, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g402(const char* name, usb_io* io, scanner_handle* h); static hg_scanner* create_scanner_g402(const char* name, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g439(const char* name, usb_io* io, scanner_handle* h); static hg_scanner* create_scanner_g439(const char* name, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g306(const char* name, usb_io* io, scanner_handle* h);
public: public:
scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only); scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only);

View File

@ -70,7 +70,7 @@ int LIBUSB_CALL usb_manager::usb_pnp_callback(libusb_context* ctx, libusb_device
usb_manager* obj = (usb_manager*)monitor; usb_manager* obj = (usb_manager*)monitor;
// if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) // if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
libusb_ref_device(device); // keep the object until handle it //libusb_ref_device(device); // keep the object until handle it
//else if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) //else if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
// libusb_unref_device(device); // libusb_unref_device(device);
@ -187,17 +187,22 @@ void usb_manager::thread_notify_usb_event()
} }
} }
libusb_ref_device(pd.dev); // for re-enter the queue pnp_events_
notify_usb_event(pd, &retry); notify_usb_event(pd, &retry);
if (retry) if (retry)
{ {
if(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - pd.happen_time).count() if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - pd.happen_time).count()
<= 5000) <= 5000)
pnp_events_.Put(pd, sizeof(pd)); pnp_events_.Put(pd, sizeof(pd));
else
retry = false;
if(pnp_events_.Size() == 1) if(pnp_events_.Size() == 1)
this_thread::sleep_for(chrono::milliseconds(1000)); this_thread::sleep_for(chrono::milliseconds(1000));
else else
this_thread::sleep_for(chrono::milliseconds(delay)); this_thread::sleep_for(chrono::milliseconds(delay));
} }
if (!retry)
libusb_unref_device(pd.dev);
} }
} }
} }
@ -283,6 +288,7 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
PNPDEV pd; PNPDEV pd;
unsigned ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - born_).count(); unsigned ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - born_).count();
libusb_ref_device(device);
pd.ctx = ctx; pd.ctx = ctx;
pd.dev = device; pd.dev = device;
pd.event = event; pd.event = event;
@ -295,9 +301,12 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
else else
{ {
bool retry = false; bool retry = false;
libusb_ref_device(device);
notify_usb_event(pd, &retry); notify_usb_event(pd, &retry);
if(retry) if(retry)
pnp_events_.Put(pd, sizeof(pd)); pnp_events_.Put(pd, sizeof(pd));
else
libusb_unref_device(device);
} }
return 0; return 0;
@ -760,6 +769,24 @@ void usb_io::init_after_open(void)
close(); close();
last_err_ = err; last_err_ = err;
} }
else
{
char str[128] = { 0 }, *ver = nullptr;
libusb_device_descriptor dd = { 0 };
libusb_get_device_descriptor(dev_info_.device, &dd);
libusb_get_string_descriptor_ascii(handle_, dd.iProduct, (unsigned char*)str, _countof(str) - 1);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Device Product: '%s'\n", str);
ver = strstr(str, "(V");
if (ver)
{
ver_ = (int)atof(ver + 2);
}
else
{
ver_ = 1;
}
}
} }
void usb_io::open(void) void usb_io::open(void)
{ {
@ -1098,6 +1125,10 @@ int usb_io::get_pid(void)
{ {
return dev_info_.pid; return dev_info_.pid;
} }
int usb_io::get_ver(void)
{
return ver_;
}
void usb_io::on_disconnected(void) void usb_io::on_disconnected(void)
{ {

View File

@ -152,6 +152,7 @@ class usb_io
int last_err_; int last_err_;
std::string init_err_msg_; std::string init_err_msg_;
libusb_device *ref_device_; libusb_device *ref_device_;
unsigned int ver_ = 1;
// endpoint ports // endpoint ports
usb_manager::USBTRANSENDP endpoints_; usb_manager::USBTRANSENDP endpoints_;
@ -191,6 +192,7 @@ public:
libusb_device* get_usb_device(void); // 获取该USB对象 libusb_device* get_usb_device(void); // 获取该USB对象
int get_vid(void); // 获取连接到该USB端口上的设备VID int get_vid(void); // 获取连接到该USB端口上的设备VID
int get_pid(void); // 获取连接到该USB端口上的设备PID int get_pid(void); // 获取连接到该USB端口上的设备PID
int get_ver(void);
void on_disconnected(void); void on_disconnected(void);
std::string init_error_msg(void); std::string init_error_msg(void);

View File

@ -36,7 +36,7 @@ endif()
target_link_libraries(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/../../../build/libgdev.a ${PROJECT_SOURCE_DIR}/../../../build/libgdev.a
${PROJECT_SOURCE_DIR}/../../../build/libgimgproc.a ${PROJECT_SOURCE_DIR}/../../../build/libgimgproc.a
${PROJECT_SOURCE_DIR}/../../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/liblang.so ${PROJECT_SOURCE_DIR}/../../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libyuyanbao.so
${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_imgproc.a ${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_imgproc.a
${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_imgcodecs.a ${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_imgcodecs.a
${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_highgui.a ${PROJECT_SOURCE_DIR}/../3rdparty/opencv/lib/uos/${CMAKE_SYSTEM_PROCESSOR}/libopencv_highgui.a

View File

@ -66,7 +66,7 @@ class log_cls
} }
std::string now(g_time_tag + hg_log::current_time() + g_time_tag); std::string now(g_time_tag + hg_log::current_time() + g_time_tag);
now += truncate ? " trcated.\n" : " started.\n"; now += truncate ? " truncated.\n" : " started.\n";
now.insert(0, log_divider); now.insert(0, log_divider);
fwrite(now.c_str(), 1, now.length(), file_); fwrite(now.c_str(), 1, now.length(), file_);
} }
@ -264,6 +264,13 @@ extern "C"
return true; return true;
} }
static bool save_dir_files(const char* path_file, void* param)
{
((std::vector<std::string>*)param)->push_back(path_file);
return true;
}
#if defined(WIN32) || defined(_WIN64) #if defined(WIN32) || defined(_WIN64)
static std::string u2a(const wchar_t* u, UINT cp = CP_ACP) static std::string u2a(const wchar_t* u, UINT cp = CP_ACP)
{ {
@ -287,25 +294,56 @@ extern "C"
static int enum_files(const char* dir, bool recursive, bool(*found_file)(const char* path_file, void* param), void* param) static int enum_files(const char* dir, bool recursive, bool(*found_file)(const char* path_file, void* param), void* param)
{ {
int ret = 0; int ret = 0;
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32W pei = { 0 };
if (h == INVALID_HANDLE_VALUE) if (!dir || *dir == 0)
ret = GetLastError(); {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32W pei = { 0 };
if (h == INVALID_HANDLE_VALUE)
ret = GetLastError();
else
{
pei.dwSize = sizeof(pei);
if (Module32FirstW(h, &pei))
{
do
{
std::string ansi(u2a(pei.szExePath));
if (!found_file(ansi.c_str(), param))
break;
pei.dwSize = sizeof(pei);
} while (Module32NextW(h, &pei));
}
CloseHandle(h);
}
}
else else
{ {
pei.dwSize = sizeof(pei); WIN32_FIND_DATAA wfd = { 0 };
if (Module32FirstW(h, &pei)) HANDLE h = FindFirstFileA((std::string(dir) + "\\*").c_str(), &wfd);
if (h == INVALID_HANDLE_VALUE)
ret = GetLastError();
else
{ {
do do
{ {
std::string ansi(u2a(pei.szExePath)); if (strcmp(wfd.cFileName, ".") == 0 || strcmp(wfd.cFileName, "..") == 0)
if (!found_file(ansi.c_str(), param)) continue;
if (!found_file((std::string(dir) + "\\" + wfd.cFileName).c_str(), param))
{
ret = ECANCELED;
break; break;
pei.dwSize = sizeof(pei); }
} while (Module32NextW(h, &pei)); if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && recursive)
{
ret = enum_files((std::string(dir) + "\\" + wfd.cFileName).c_str(), recursive, found_file, param);
if (ret == ECANCELED)
break;
}
} while (FindNextFileA(h, &wfd));
FindClose(h);
} }
CloseHandle(h);
} }
return ret; return ret;
@ -539,6 +577,10 @@ extern "C"
{ {
return MKDIR(fodler, S_IREAD | S_IWRITE | S_IEXEC) == 0 || errno == EEXIST; return MKDIR(fodler, S_IREAD | S_IWRITE | S_IEXEC) == 0 || errno == EEXIST;
} }
void get_foler_files(const char* folder, std::vector<std::string>& files, bool recursive)
{
enum_files(folder, recursive, save_dir_files, &files);
}
std::string ini_get(const char* app, const char* key) std::string ini_get(const char* app, const char* key)
{ {
return ini_.get(app, key); return ini_.get(app, key);

View File

@ -6,6 +6,8 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h" #include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "lang/app_language.h" #include "lang/app_language.h"
#if defined(WIN32) || defined(_WIN64) #if defined(WIN32) || defined(_WIN64)
@ -64,6 +66,7 @@ extern "C"
unsigned long long available_memory(void); unsigned long long available_memory(void);
void str_tolower(std::string& str); void str_tolower(std::string& str);
bool create_folder(const char* fodler); bool create_folder(const char* fodler);
void get_foler_files(const char* folder, std::vector<std::string>& files, bool recursive = false);
std::string ini_get(const char* app, const char* key); std::string ini_get(const char* app, const char* key);
void ini_set(const char* app, const char* key, const char* val); void ini_set(const char* app, const char* key, const char* val);

View File

@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#endif #endif
#include <math.h> #include <math.h>
#include <exception>
#define MAKE_VERSION(a, b, c, d) \ #define MAKE_VERSION(a, b, c, d) \
@ -138,7 +139,26 @@ extern "C"
scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc) scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc)
{ {
return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc); try
{
return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc);
}
catch (std::exception& e)
{
if (h)
*h = nullptr;
VLOG_MINI_2(LOG_LEVEL_FATAL, "Exception occurs when open '%s': %s.\n", name, e.what());
return SCANNER_ERR_DATA_DAMAGED;
}
catch (...)
{
if (h)
*h = nullptr;
VLOG_MINI_1(LOG_LEVEL_FATAL, "Exception occurs when open '%s'!\n", name);
return SCANNER_ERR_DATA_DAMAGED;
}
} }
scanner_err hg_scanner_close(scanner_handle h, bool force) scanner_err hg_scanner_close(scanner_handle h, bool force)
@ -220,6 +240,8 @@ extern "C"
RETURN_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED); RETURN_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
RETURN_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM); RETURN_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
RETURN_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM); RETURN_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
RETURN_IF(err, SCANNER_ERR_IMAGE_PROC_FATAL);
RETURN_IF(err, SCANNER_ERR_NOT_OPEN); RETURN_IF(err, SCANNER_ERR_NOT_OPEN);
RETURN_IF(err, SCANNER_ERR_NOT_START); RETURN_IF(err, SCANNER_ERR_NOT_START);
RETURN_IF(err, SCANNER_ERR_NOT_ANY_MORE); RETURN_IF(err, SCANNER_ERR_NOT_ANY_MORE);
@ -258,6 +280,8 @@ extern "C"
RETURN_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE); RETURN_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE);
RETURN_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING); RETURN_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING);
RETURN_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS); RETURN_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS);
RETURN_IF(err, SCANNER_ERR_DEVICE_LENS_DIRTY);
RETURN_IF(err, SCANNER_ERR_DEVICE_AUTO_FAIL_OVER);
if (err == SCANNER_ERR_LANG_PAK_LOST) if (err == SCANNER_ERR_LANG_PAK_LOST)
return "SCANNER_ERR_LANG_PAK_LOST"; return "SCANNER_ERR_LANG_PAK_LOST";
@ -296,6 +320,8 @@ extern "C"
RETURN_DESC_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED); RETURN_DESC_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED);
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM); RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM);
RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM); RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM);
RETURN_DESC_IF(err, SCANNER_ERR_IMAGE_PROC_FATAL);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_OPEN); RETURN_DESC_IF(err, SCANNER_ERR_NOT_OPEN);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_START); RETURN_DESC_IF(err, SCANNER_ERR_NOT_START);
RETURN_DESC_IF(err, SCANNER_ERR_NOT_ANY_MORE); RETURN_DESC_IF(err, SCANNER_ERR_NOT_ANY_MORE);
@ -334,6 +360,8 @@ extern "C"
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_LENS_DIRTY);
RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_AUTO_FAIL_OVER);
if (err == SCANNER_ERR_LANG_PAK_LOST) if (err == SCANNER_ERR_LANG_PAK_LOST)
return "SCANNER_ERR_LANG_PAK_LOST"; return "SCANNER_ERR_LANG_PAK_LOST";
@ -415,10 +443,10 @@ extern "C"
const char* hg_scanner_image_statu_name(int img_statu) const char* hg_scanner_image_statu_name(int img_statu)
{ {
RETURN_IF(img_statu, SANE_Image_Statu_OK); RETURN_IF(img_statu, IMG_STATUS_OK);
RETURN_IF(img_statu, SANE_Image_Statu_Blank); RETURN_IF(img_statu, IMG_STATUS_BLANK);
RETURN_IF(img_statu, SANE_Image_Statu_Double); RETURN_IF(img_statu, IMG_STATUS_DOUBLE);
RETURN_IF(img_statu, SANE_Image_Statu_Jammed); RETURN_IF(img_statu, IMG_STATUS_JAM);
// NOTE: multi-thread unsafe here // NOTE: multi-thread unsafe here
static char g_unk_statu[80] = { 0 }; static char g_unk_statu[80] = { 0 };

View File

@ -18,7 +18,7 @@ link_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR} ${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}
) )
target_link_libraries(${PROJECT_NAME} PRIVATE hgdriver target_link_libraries(${PROJECT_NAME} PRIVATE hgdriver
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/liblang.so ${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libyuyanbao.so
${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libhgdriver.so ${PROJECT_SOURCE_DIR}/../../release/uos/${CMAKE_SYSTEM_PROCESSOR}/libhgdriver.so
) )

View File

@ -26,6 +26,7 @@ extern SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void
extern const char* inner_sane_err_desc(SANE_Status err); extern const char* inner_sane_err_desc(SANE_Status err);
extern SANE_Status inner_sane_read_ext(SANE_Img_Ext_Info* ext_info, SANE_Int* len); extern SANE_Status inner_sane_read_ext(SANE_Img_Ext_Info* ext_info, SANE_Int* len);
extern SANE_Status inner_sane_ex_get_driver_version(SANE_Int* hh, SANE_Int* hl, SANE_Int* lh, SANE_Int* ll); extern SANE_Status inner_sane_ex_get_driver_version(SANE_Int* hh, SANE_Int* hl, SANE_Int* lh, SANE_Int* ll);
extern SANE_Status inner_sane_get_parameters_ex(SANE_Handle h, SANE_Image* info);
/// <summary> /// <summary>
/// 导出接口 /// 导出接口
@ -115,6 +116,10 @@ SANE_Status sane_read_ext_info(SANE_Img_Ext_Info* ext_info, SANE_Int* len)
{ {
return inner_sane_read_ext(ext_info, len); return inner_sane_read_ext(ext_info, len);
} }
SANE_Status sane_get_parameters_ex(SANE_Handle h, SANE_Image* info)
{
return inner_sane_get_parameters_ex(h, info);
}
int sane_ex_get_driver_version(int* hh, int* hl, int* lh, int* ll) int sane_ex_get_driver_version(int* hh, int* hl, int* lh, int* ll)
{ {
return inner_sane_ex_get_driver_version(hh, hl, lh, ll); return inner_sane_ex_get_driver_version(hh, hl, lh, ll);

View File

@ -342,6 +342,7 @@ namespace local_utility
TRY_MATCH(LANGUAGE); TRY_MATCH(LANGUAGE);
TRY_MATCH(INITIAL_BOOT_TIME); TRY_MATCH(INITIAL_BOOT_TIME);
TRY_MATCH(DISCARDBLANK); TRY_MATCH(DISCARDBLANK);
TRY_MATCH(LENS_DIRTY);
//TRY_MATCH(HISTORY_COUNT); //TRY_MATCH(HISTORY_COUNT);
//TRY_MATCH(DRIVER_VERSION); //TRY_MATCH(DRIVER_VERSION);
@ -1669,12 +1670,26 @@ SANE_Status hg_sane_middleware::get_image_parameters(SANE_Handle handle, SANE_Pa
return local_utility::scanner_err_2_sane_statu(err); return local_utility::scanner_err_2_sane_statu(err);
} }
SANE_Status hg_sane_middleware::get_image_parameters_ex(SANE_Handle handle, SANE_Image* params)
{
scanner_handle h = find_openning_device(handle);
scanner_err err = SCANNER_ERR_NOT_START;
if (!params)
return SANE_STATUS_INVAL;
err = hg_scanner_get_img_info(h, (SANE_Parameters*)params, sizeof(*params));
return local_utility::scanner_err_2_sane_statu(err);
}
SANE_Status hg_sane_middleware::start(SANE_Handle h, void* async_event) SANE_Status hg_sane_middleware::start(SANE_Handle h, void* async_event)
{ {
LPDEVINST dev; LPDEVINST dev;
scanner_handle hs = find_openning_device(h); scanner_handle hs = find_openning_device(h);
scanner_err err = SCANNER_ERR_INVALID_PARAMETER; scanner_err err = SCANNER_ERR_INVALID_PARAMETER;
LOG_INFO(LOG_LEVEL_ALL, "sane_start ...\n");
if(hs) if(hs)
err = hg_scanner_start(hs, async_event, -1); err = hg_scanner_start(hs, async_event, -1);
@ -1696,6 +1711,7 @@ SANE_Status hg_sane_middleware::read(SANE_Handle h, void* buf, int* bytes)
} }
SANE_Status hg_sane_middleware::stop(SANE_Handle h) SANE_Status hg_sane_middleware::stop(SANE_Handle h)
{ {
LOG_INFO(LOG_LEVEL_ALL, "sane_cancel\n");
scanner_handle hs = find_openning_device(h); scanner_handle hs = find_openning_device(h);
if(hs) if(hs)
@ -2575,8 +2591,6 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
} }
SANE_Status inner_sane_start(SANE_Handle handle) SANE_Status inner_sane_start(SANE_Handle handle)
{ {
LOG_INFO(LOG_LEVEL_ALL, "sane_start\n");
return hg_sane_middleware::instance()->start(handle, NULL); return hg_sane_middleware::instance()->start(handle, NULL);
} }
SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length) SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length)
@ -2590,8 +2604,6 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
} }
void inner_sane_cancel(SANE_Handle handle) void inner_sane_cancel(SANE_Handle handle)
{ {
LOG_INFO(LOG_LEVEL_ALL, "sane_cancel\n");
hg_sane_middleware::instance()->stop(handle); hg_sane_middleware::instance()->stop(handle);
} }
SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking) SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)
@ -2643,6 +2655,10 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
SANE_Status inner_sane_get_parameters_ex(SANE_Handle h, SANE_Image* info)
{
return hg_sane_middleware::instance()->get_image_parameters_ex(h, info);
}
void sanei_debug_msg(int level, int max_level, const char* be, const char* fmt, va_list ap) void sanei_debug_msg(int level, int max_level, const char* be, const char* fmt, va_list ap)
{ {

View File

@ -223,6 +223,7 @@ public:
SANE_Status open_device(SANE_String_Const devicename, SANE_Handle* handle); SANE_Status open_device(SANE_String_Const devicename, SANE_Handle* handle);
SANE_Status close_device(SANE_Handle h); SANE_Status close_device(SANE_Handle h);
SANE_Status get_image_parameters(SANE_Handle handle, SANE_Parameters* params); SANE_Status get_image_parameters(SANE_Handle handle, SANE_Parameters* params);
SANE_Status get_image_parameters_ex(SANE_Handle handle, SANE_Image* params);
SANE_Status start(SANE_Handle h, void* async_event); SANE_Status start(SANE_Handle h, void* async_event);
SANE_Status read(SANE_Handle h, void* buf, int* bytes); SANE_Status read(SANE_Handle h, void* buf, int* bytes);
SANE_Status stop(SANE_Handle h); SANE_Status stop(SANE_Handle h);

View File

@ -31,7 +31,7 @@
#if defined(WIN32) || defined(_WIN64) #if defined(WIN32) || defined(_WIN64)
#include "../../../sdk/include/huagao/brand.h" #include "../../../sdk/include/huagao/brand.h"
#ifndef HGSCANNER_EXPORT #ifndef HGSCANNER_EXPORT
#pragma comment(lib, "scanner.lib") #pragma comment(lib, "scannerqd.lib")
#endif #endif
#define VERSION_MAJOR VERSION_MAIN #define VERSION_MAJOR VERSION_MAIN
#define VERSION_MINOR VERSION_SUB #define VERSION_MINOR VERSION_SUB