当前位置:   article > 正文

java实现电子发票中的发票税号等信息识别的几种可用方案_java 纳税人识别号校验码 csdn

java 纳税人识别号校验码 csdn

先说一下背景:

今天领导突然说需要做一个电子发票中发票税号的识别,于是乎就开始去调研看有哪些方案,最先想到的就是OCR文字识别,自己去画框训练模型去识别税号等相关信息

话不多说开整思路:

思路一:百度AI平台去直接调用

思路二:自己基于模型训练

思路三:基于本地化代码识别票据中信息

这几种思路接下来我都会详细展开说,且每种方式的优缺点博主也会说清楚,仅供大家参考

思路一:百度AI平台去直接调用

  1. 百度OCR识别介绍

官网地址:OCR文字识别_免费试用_图片转文字-百度AI开放平台

你还别说,百度这几个模块想当成熟,模型训练的很好

  1. 使用方式

使用百度账号登录,创建应用,比较重要的是API KEY 和 SECRET KEY

服务与支持-自助服务-自助工具

3.代码调用:(java)

  • 加入依赖

  1. <!--百度OCR-->
  2. <dependency>
  3. <groupId>com.baidu.aip</groupId>
  4. <artifactId>java-sdk</artifactId>
  5. <version>4.16.5</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.baidubce</groupId>
  9. <artifactId>api-explorer-sdk</artifactId>
  10. <version>1.0.3.1</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>com.squareup.okhttp3</groupId>
  14. <artifactId>okhttp</artifactId>
  15. <version>3.10.0</version>
  16. </dependency>
  • 创建工具类

FileUtil,Base64Util,HttpUtil,GsonUtils 工具类从下面链接下载

  1. https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
  2. https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
  3. https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
  4. https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
  • 获取 Token 类

  1. import org.json.JSONObject;
  2. import java.io.BufferedReader;
  3. import java.io.InputStreamReader;
  4. import java.net.HttpURLConnection;
  5. import java.net.URL;
  6. import java.util.List;
  7. import java.util.Map;
  8. /**
  9. * 获取token类
  10. */
  11. public class AuthService {
  12. /**
  13. * 获取权限token
  14. * @return 返回示例:
  15. * {
  16. * "access_token": "24.46ad247221975.2592000.1491995545.282335-1234567",
  17. * "expires_in": 2592000
  18. * }
  19. */
  20. public static String getAuth() {
  21. // 官网获取的 API Key 更新为你注册的
  22. String clientId = "74AHm9bwIfrVU16EDF9uxXbO";
  23. // 官网获取的 Secret Key 更新为你注册的
  24. String clientSecret = "c1fzjB8jy8GmLfe8rzMzvDZYheklTZNh";
  25. return getAuth(clientId, clientSecret);
  26. }
  27. public static void main(String[] args) {
  28. System.out.println(getAuth());
  29. }
  30. /**
  31. * 获取API访问token
  32. * 该token有一定的有效期,需要自行管理,当失效时需重新获取.
  33. * @param ak - 百度云官网获取的 API Key
  34. * @param sk - 百度云官网获取的 Secret Key
  35. * @return assess_token 示例:
  36. * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
  37. */
  38. public static String getAuth(String ak, String sk) {
  39. // 获取token地址
  40. String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
  41. String getAccessTokenUrl = authHost
  42. // 1. grant_type为固定参数
  43. + "grant_type=client_credentials"
  44. // 2. 官网获取的 API Key
  45. + "&client_id=" + ak
  46. // 3. 官网获取的 Secret Key
  47. + "&client_secret=" + sk;
  48. try {
  49. URL realUrl = new URL(getAccessTokenUrl);
  50. // 打开和URL之间的连接
  51. HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
  52. connection.setRequestMethod("GET");
  53. connection.connect();
  54. // 获取所有响应头字段
  55. Map<String, List<String>> map = connection.getHeaderFields();
  56. // 遍历所有的响应头字段
  57. /*for (String key : map.keySet()) {
  58. System.err.println(key + "--->" + map.get(key));
  59. }*/
  60. // 定义 BufferedReader输入流来读取URL的响应
  61. BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  62. String result = "";
  63. String line;
  64. while ((line = in.readLine()) != null) {
  65. result += line;
  66. }
  67. /**
  68. * 返回结果示例
  69. */
  70. //System.err.println("result:" + result);
  71. JSONObject jsonObject = new JSONObject(result);
  72. String access_token = jsonObject.getString("access_token");
  73. return access_token;
  74. } catch (Exception e) {
  75. System.err.printf("获取token失败!");
  76. e.printStackTrace(System.err);
  77. }
  78. return null;
  79. }
  80. }
  • 图片/PDF 发票识别测试类

  1. import okhttp3.*;
  2. import java.io.*;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. import java.util.Base64;
  6. class Sample {
  7. static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
  8. public static void main(String[] args) throws IOException {
  9. MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
  10. // image 可以通过 getFileContentAsBase64("C:\fakepath\下载.png") 方法获取
  11. String path = "C:\\Users\\Desktop\\1.png";
  12. String image = getFileContentAsBase64(path);
  13. image = image.replaceAll("\\+","%2B");
  14. image = image.replaceAll("\\/","%2F");
  15. // 官网获取的 API Key 更新为你注册的
  16. String clientId = "74AHm9bwIfrVO";
  17. // 官网获取的 Secret Key 更新为你注册的
  18. String clientSecret = "c1fzjB8jy8GZNh";
  19. String access_token = AuthService.getAuth(clientId, clientSecret);
  20. //String access_token = "24.acd9426de6760aa.2592000.1678264-30210143";
  21. RequestBody body = RequestBody.create(mediaType, "image="+image);
  22. Request request = new Request.Builder()
  23. .url("https://aip.baidubce.com/rest/2.0/ocr/v1/vat_invoice?access_token="+access_token)
  24. .method("POST", body)
  25. .addHeader("Content-Type", "application/x-www-form-urlencoded")
  26. .addHeader("Accept", "application/json")
  27. .build();
  28. Response response = HTTP_CLIENT.newCall(request).execute();
  29. System.out.println(response.body().string());
  30. }
  31. /**
  32. * 获取文件base64编码
  33. *
  34. * @param path 文件路径
  35. * @return base64编码信息,不带文件头
  36. * @throws IOException IO异常
  37. */
  38. static String getFileContentAsBase64(String path) throws IOException {
  39. byte[] b = Files.readAllBytes(Paths.get(path));
  40. return Base64.getEncoder().encodeToString(b);
  41. }
  42. }

输出结果

4.使用注意点

这种目前是每月免费调用1000次,但是这个需要把信息上传到百度云上,有信息安全方面考虑的同学需要思考一下,私有部署需要付费,大概是299买一个sdk

百度OCR识别发票 Java 代码实现 | 言曌博客

思路二:自己基于模型训练

这种提供思路,需要自己训练模型,基于百度OCR自训练平台训练模型,使用方式如下,这块做个简单介绍,仅供参考

1.使用步骤

百度智能云-登录

根据步骤操作几个,提供数据标注训练

2.使用注意点

这种方式好处是比较自定义化,这种本地部署比较麻烦,需要额外付费用,需多多斟酌

思路三:识别二维码

这个思路是跟财务同事再三确认后,目前只识别电子发票信息,且发票中都一定会有二维码信息,这就好办了,我们可以识别二维码中的信息,这不就问题解决了,且这种方式只要有二维码,准确率达到100%

重点说说第三种

1.代码实现:

干搂代码开始:

加入maven依赖包:


<code class="language-plaintext hljs"><dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.20</version>
</dependency><dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.1.0</version>
</dependency><dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.1.0</version>
</dependency></code>

上代码:

  1. import ch.qos.logback.classic.Level;
  2. import ch.qos.logback.classic.LoggerContext;
  3. import com.google.zxing.BinaryBitmap;
  4. import com.google.zxing.EncodeHintType;
  5. import com.google.zxing.MultiFormatReader;
  6. import com.google.zxing.Result;
  7. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  8. import com.google.zxing.common.HybridBinarizer;
  9. import com.huatek.base.utils.LoggerUtil;
  10. import org.apache.commons.lang3.StringUtils;
  11. import org.apache.pdfbox.cos.COSName;
  12. import org.apache.pdfbox.pdmodel.PDDocument;
  13. import org.apache.pdfbox.pdmodel.PDPage;
  14. import org.apache.pdfbox.pdmodel.PDResources;
  15. import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. import java.awt.image.BufferedImage;
  19. import java.io.File;
  20. import java.util.ArrayList;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. public class InvoiceTest {
  25.     //这块是为了避免log4j打印一些没必要的信息
  26. static {
  27. LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
  28. List<ch.qos.logback.classic.Logger> loggerList = loggerContext.getLoggerList();
  29. loggerList.forEach(logger -> {
  30. logger.setLevel(Level.INFO);
  31. });
  32. }
  33. private Logger logger = LoggerUtil.getLogger();
  34. public static void main(String[] args) {
  35. InvoiceTest fapiao1 = new InvoiceTest();
  36.         //填写你自己的路径即可
  37. fapiao1.getInvoiceInfo("C:\\Users\\Desktop\\temp\\1.pdf");
  38. }
  39. /**
  40. * 获取电子发票pdf文件中的发票信息
  41. *
  42. * @param filePath 电子发票路径
  43. * @return 发票信息
  44. */
  45. public Object getInvoiceInfo(String filePath) {
  46. try {
  47. List<BufferedImage> imageList = extractImage(new File(filePath));
  48. if (imageList.isEmpty()) {
  49. logger.info("pdf中未解析出图片,返回空");
  50. return null;
  51. }
  52. MultiFormatReader formatReader = new MultiFormatReader();
  53. //正常解析出来有3张图片,第一张是二维码,其他两张图片是发票上盖的章
  54. BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(imageList.get(0))));
  55. Map hints = new HashMap<>();
  56. hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
  57. Result result = formatReader.decode(binaryBitmap);
  58. if (result == null || StringUtils.isEmpty(result.getText())) {
  59. logger.info("pdf中的第一张图片没有解析了字符串信息,直接返回空");
  60. return null;
  61. }
  62. logger.info("从电子发票中识别出的信息为:{}", result.getText());
  63. // 读取到的信息为 : 01,发票类型,发票代码,发票号码,发票金额,开票日期,校验码,随机产生的摘要信息
  64. String[] infos = result.getText().split(",");
  65. if (infos.length != 8) {
  66. logger.info("pdf中的第一张图片解析出的字符串数组长度不为8,返回空。");
  67. return null;
  68. }
  69.             //这里自己去定义对象,属性自己看着定义,仅供参考
  70. /*Invoice invoice = new Invoice();
  71. invoice.setInvoiceType(infos[1]); //发票类型
  72. invoice.setInvoiceCode(infos[2]); //发票代码
  73. invoice.setInvoiceNo(infos[3]); // 发票号码
  74. invoice.setAmount(new BigDecimal(infos[4])); // 发票金额
  75. invoice.setInvoiceDate(DateUtils.parseDate(infos[5], "yyyyMMdd")); //开票日期
  76. invoice.setCheckCode(infos[6]); // 校验码*/
  77. //return invoice;
  78. return null;
  79. } catch (Exception e) {
  80. logger.info("解析pdf中的二维码出现异常", e);
  81. return null;
  82. }
  83. }
  84. /**
  85. * 提取电子发票里面的图片
  86. *
  87. * @param pdfFile 电子发票文件对象
  88. * @return pdf中解析出的图片列表
  89. * @throws Exception
  90. */
  91. private List<BufferedImage> extractImage(File pdfFile) throws Exception {
  92. List<BufferedImage> imageList = new ArrayList<BufferedImage>();
  93. PDDocument document = PDDocument.load(pdfFile);
  94. PDPage page = document.getPage(0); //电子发票只有一页
  95. PDResources resources = page.getResources();
  96. for (COSName name : resources.getXObjectNames()) {
  97. if (resources.isImageXObject(name)) {
  98. PDImageXObject obj = (PDImageXObject) resources.getXObject(name);
  99. imageList.add(obj.getImage());
  100. }
  101. }
  102. document.close();
  103. return imageList;
  104. }
  105. }

至此代码完成,有的同学可能会说那如果传的是图片怎么办,别慌那就继续实现就完事儿了

依赖还是那些依赖,根据你自己的需求封装工具类和上面代码相互配合判断调用

  1. import com.google.zxing.*;
  2. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  3. import com.google.zxing.common.HybridBinarizer;
  4. import javax.imageio.ImageIO;
  5. import java.awt.image.BufferedImage;
  6. import java.io.File;
  7. import java.io.IOException;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. /**
  11. * 作用:二维码识别(图片)
  12. * 类名:QRCodeUtils
  13. **/
  14. public class QRCodeUtils {
  15. /**
  16. * 解析二维码,此方法解析一个路径的二维码图片
  17. * path:图片路径
  18. */
  19. public static String deEncodeByPath(String path) {
  20. String content = null;
  21. BufferedImage image;
  22. try {
  23. image = ImageIO.read(new File(path));
  24. LuminanceSource source = new BufferedImageLuminanceSource(image);
  25. Binarizer binarizer = new HybridBinarizer(source);
  26. BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
  27. Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
  28. hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
  29. Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
  30. System.out.println("图片中内容: ");
  31. System.out.println("content: " + result.getText());
  32. content = result.getText();
  33. } catch (IOException e) {
  34. e.printStackTrace();
  35. } catch (NotFoundException e) {
  36. //这里判断如果识别不了带LOGO的图片,重新添加上一个属性
  37. try {
  38. image = ImageIO.read(new File(path));
  39. LuminanceSource source = new BufferedImageLuminanceSource(image);
  40. Binarizer binarizer = new HybridBinarizer(source);
  41. BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
  42. Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
  43. //设置编码格式
  44. hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
  45. //设置优化精度
  46. hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
  47. //设置复杂模式开启(我使用这种方式就可以识别微信的二维码了)
  48. hints.put(DecodeHintType.PURE_BARCODE,Boolean.TYPE);
  49. Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
  50. System.out.println("图片中内容: ");
  51. System.out.println("content: " + result.getText());
  52. content = result.getText();
  53. } catch (IOException e1) {
  54. e1.printStackTrace();
  55. } catch (NotFoundException e2) {
  56. e2.printStackTrace();
  57. }
  58. }
  59. return content;
  60. }
  61. public static void main(String [] args){
  62. System.out.println(deEncodeByPath("C:\\Users\\Desktop\\3-1.jpg"));//二维码图片路径
  63. }
  64. }

如果上述不能识别的话,那么就需要对图片处理一次,然后再进行识别,这里是个调优图片的工具类。

  1. package com.face.ele.common.utils;
  2. import javax.imageio.ImageIO;
  3. import java.awt.*;
  4. import java.awt.image.BufferedImage;
  5. import java.io.File;
  6. import java.io.IOException;
  7. /*
  8. * @description: 图片清晰处理
  9. */
  10. public class ImageOptimizationUtil {
  11. // 阈值0-255
  12. public static int YZ = 150;
  13. /**
  14. * 图像二值化处理
  15. *
  16. * @param filePath 要处理的图片路径
  17. * @param fileOutputPath 处理后的图片输出路径
  18. */
  19. public static void binarization(String filePath, String fileOutputPath) throws IOException {
  20. File file = new File(filePath);
  21. BufferedImage bi = ImageIO.read(file);
  22. // 获取当前图片的高,宽,ARGB
  23. int h = bi.getHeight();
  24. int w = bi.getWidth();
  25. int arr[][] = new int[w][h];
  26. // 获取图片每一像素点的灰度值
  27. for (int i = 0; i < w; i++) {
  28. for (int j = 0; j < h; j++) {
  29. // getRGB()返回默认的RGB颜色模型(十进制)
  30. arr[i][j] = getImageGray(bi.getRGB(i, j));// 该点的灰度值
  31. }
  32. }
  33. // 构造一个类型为预定义图像类型,BufferedImage
  34. BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
  35. // 和预先设置的阈值大小进行比较,大的就显示为255即白色,小的就显示为0即黑色
  36. for (int i = 0; i < w; i++) {
  37. for (int j = 0; j < h; j++) {
  38. if (getGray(arr, i, j, w, h) > YZ) {
  39. int white = new Color(255, 255, 255).getRGB();
  40. bufferedImage.setRGB(i, j, white);
  41. } else {
  42. int black = new Color(0, 0, 0).getRGB();
  43. bufferedImage.setRGB(i, j, black);
  44. }
  45. }
  46. }
  47. ImageIO.write(bufferedImage, "jpg", new File(fileOutputPath));
  48. }
  49. /**
  50. * 图像的灰度处理
  51. * 利用浮点算法:Gray = R*0.3 + G*0.59 + B*0.11;
  52. *
  53. * @param rgb 该点的RGB值
  54. * @return 返回处理后的灰度值
  55. */
  56. private static int getImageGray(int rgb) {
  57. String argb = Integer.toHexString(rgb);// 将十进制的颜色值转为十六进制
  58. // argb分别代表透明,红,绿,蓝 分别占16进制2位
  59. int r = Integer.parseInt(argb.substring(2, 4), 16);// 后面参数为使用进制
  60. int g = Integer.parseInt(argb.substring(4, 6), 16);
  61. int b = Integer.parseInt(argb.substring(6, 8), 16);
  62. int gray = (int) (r*0.28 + g*0.95 + b*0.11);
  63. return gray;
  64. }
  65. /**
  66. * 自己加周围8个灰度值再除以9,算出其相对灰度值
  67. *
  68. * @param gray
  69. * @param x 要计算灰度的点的横坐标
  70. * @param y 要计算灰度的点的纵坐标
  71. * @param w 图像的宽度
  72. * @param h 图像的高度
  73. * @return
  74. */
  75. public static int getGray(int gray[][], int x, int y, int w, int h) {
  76. int rs = gray[x][y] + (x == 0 ? 255 : gray[x - 1][y]) + (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])
  77. + (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1]) + (y == 0 ? 255 : gray[x][y - 1])
  78. + (y == h - 1 ? 255 : gray[x][y + 1]) + (x == w - 1 ? 255 : gray[x + 1][y])
  79. + (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])
  80. + (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);
  81. return rs / 9;
  82. }
  83. /**
  84. * 二值化后的图像的开运算:先腐蚀再膨胀(用于去除图像的小黑点)
  85. *
  86. * @param filePath 要处理的图片路径
  87. * @param fileOutputPath 处理后的图片输出路径
  88. * @throws IOException
  89. */
  90. public static void opening(String filePath, String fileOutputPath) throws IOException {
  91. File file = new File(filePath);
  92. BufferedImage bi = ImageIO.read(file);
  93. // 获取当前图片的高,宽,ARGB
  94. int h = bi.getHeight();
  95. int w = bi.getWidth();
  96. int arr[][] = new int[w][h];
  97. // 获取图片每一像素点的灰度值
  98. for (int i = 0; i < w; i++) {
  99. for (int j = 0; j < h; j++) {
  100. // getRGB()返回默认的RGB颜色模型(十进制)
  101. arr[i][j] = getImageGray(bi.getRGB(i, j));// 该点的灰度值
  102. }
  103. }
  104. int black = new Color(0, 0, 0).getRGB();
  105. int white = new Color(255, 255, 255).getRGB();
  106. BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
  107. // 临时存储腐蚀后的各个点的亮度
  108. int temp[][] = new int[w][h];
  109. // 1.先进行腐蚀操作
  110. for (int i = 0; i < w; i++) {
  111. for (int j = 0; j < h; j++) {
  112. /*
  113. * 为0表示改点和周围8个点都是黑,则该点腐蚀操作后为黑
  114. * 由于公司图片态模糊,完全达到9个点全为黑的点太少,最后效果很差,故改为了小于30
  115. * (写30的原因是,当只有一个点为白,即总共255,调用getGray方法后得到255/9 = 28)
  116. */
  117. if (getGray(arr, i, j, w, h) < 30) {
  118. temp[i][j] = 0;
  119. } else{
  120. temp[i][j] = 255;
  121. }
  122. }
  123. }
  124. // 2.再进行膨胀操作
  125. for (int i = 0; i < w; i++) {
  126. for (int j = 0; j < h; j++) {
  127. bufferedImage.setRGB(i, j, white);
  128. }
  129. }
  130. for (int i = 0; i < w; i++) {
  131. for (int j = 0; j < h; j++) {
  132. // 为0表示改点和周围8个点都是黑,则该点腐蚀操作后为黑
  133. if (temp[i][j] == 0) {
  134. bufferedImage.setRGB(i, j, black);
  135. if(i > 0) {
  136. bufferedImage.setRGB(i-1, j, black);
  137. }
  138. if (j > 0) {
  139. bufferedImage.setRGB(i, j-1, black);
  140. }
  141. if (i > 0 && j > 0) {
  142. bufferedImage.setRGB(i-1, j-1, black);
  143. }
  144. if (j < h-1) {
  145. bufferedImage.setRGB(i, j+1, black);
  146. }
  147. if (i < w-1) {
  148. bufferedImage.setRGB(i+1, j, black);
  149. }
  150. if (i < w-1 && j > 0) {
  151. bufferedImage.setRGB(i+1, j-1, black);
  152. }
  153. if (i < w-1 && j < h-1) {
  154. bufferedImage.setRGB(i+1, j+1, black);
  155. }
  156. if (i > 0 && j < h-1) {
  157. bufferedImage.setRGB(i-1, j+1, black);
  158. }
  159. }
  160. }
  161. }
  162. ImageIO.write(bufferedImage, "jpg", new File(fileOutputPath));
  163. }
  164. public static void main(String[] args) {
  165. String fullPath="E:\\test\\img\\1.jpg";
  166. String newPath="E:\\test\\img\\1new.jpg";
  167. try {
  168. ImageOptimizationUtil.binarization(fullPath,newPath);
  169. } catch (IOException e) {
  170. e.printStackTrace();
  171. }
  172. }
  173. }

可以手动测试,然后对改代码的部分进行调正对应的参数-- gray变量里的计算进行灰度调整

  1. private static int getImageGray(int rgb) {
  2. String argb = Integer.toHexString(rgb);// 将十进制的颜色值转为十六进制
  3. // argb分别代表透明,红,绿,蓝 分别占16进制2位
  4. int r = Integer.parseInt(argb.substring(2, 4), 16);// 后面参数为使用进制
  5. int g = Integer.parseInt(argb.substring(4, 6), 16);
  6. int b = Integer.parseInt(argb.substring(6, 8), 16);
  7. int gray = (int) (r*0.28 + g*0.95 + b*0.11);
  8. return gray;
  9. }

对图片进行调整之后,再对图片进行识别即可。

2.优点

可以直接识别二维码读取部分票面信息,然后用这部分信息作为参数,通过调用税务的接口获取全票面信息。只要是正常的电子发票,识别率差不多是100%,效率极高,准确率也极高

3.缺点

只能获取部分信息,如果需要更多的信息,那就不能获取了,但是大部分场景还是可以覆盖的

如何识别电子发票中的二维码(java实现) - 简书

java实现识别二维码图片功能_java_脚本之家

至此三种思路都已经说完了,用哪个各位同学自己定夺,我目前采用的思路三,暂时没什么问题,基本满足业务需求,后续有问题就得去模型库中自己训练了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/298032
推荐阅读
相关标签
  

闽ICP备14008679号