|
|
|
@@ -0,0 +1,290 @@ |
|
|
|
package com.iformall.ocr; |
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.OutputStream; |
|
|
|
import java.net.MalformedURLException; |
|
|
|
import java.net.URISyntaxException; |
|
|
|
import java.net.URL; |
|
|
|
import java.net.URLConnection; |
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker; |
|
|
|
import com.recognition.software.jdeskew.ImageDeskew; |
|
|
|
import net.sourceforge.tess4j.ITessAPI.TessPageIteratorLevel; |
|
|
|
import net.sourceforge.tess4j.ITesseract; |
|
|
|
import net.sourceforge.tess4j.ITesseract.RenderedFormat; |
|
|
|
import net.sourceforge.tess4j.Tesseract; |
|
|
|
import net.sourceforge.tess4j.Word; |
|
|
|
import net.sourceforge.tess4j.util.ImageHelper; |
|
|
|
import net.sourceforge.tess4j.util.LoggHelper; |
|
|
|
import net.sourceforge.tess4j.util.Utils; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
import javax.imageio.ImageIO; |
|
|
|
import java.awt.*; |
|
|
|
import java.awt.image.BufferedImage; |
|
|
|
import java.io.File; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
/** |
|
|
|
* https://www.cnblogs.com/pejsidney/p/9487881.html |
|
|
|
* Tess4J是对Tesseract OCR API.的Java JNA 封装。使java能够通过调用Tess4J的API来使用Tesseract OCR。支持的格式:TIFF,JPEG,GIF,PNG,BMP,JPEG,and PDF |
|
|
|
Tesseract 的github地址:https://github.com/tesseract-ocr/tesseract |
|
|
|
Tess4J的github地址:https://github.com/nguyenq/tess4j |
|
|
|
|
|
|
|
Tess4J API 提供的功能: |
|
|
|
1、直接识别支持的文件 |
|
|
|
2、识别图片流 |
|
|
|
3、识别图片的某块区域 |
|
|
|
4、将识别结果保存为 TEXT/ HOCR/ PDF/ UNLV/ BOX |
|
|
|
5、通过设置取词的等级,提取识别出来的文字 |
|
|
|
6、获得每一个识别区域的具体坐标范围 |
|
|
|
7、调整倾斜的图片 |
|
|
|
8、裁剪图片 |
|
|
|
9、调整图片分辨率 |
|
|
|
10、从粘贴板获得图像 |
|
|
|
11、克隆一个图像(目的:创建一份一模一样的图片,与原图在操作修改上,不相 互影响) |
|
|
|
12、图片转换为二进制、黑白图像、灰度图像 |
|
|
|
13、反转图片颜色 |
|
|
|
* @author alascor |
|
|
|
*/ |
|
|
|
public class FormallTess4j { |
|
|
|
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(new LoggHelper().toString()); |
|
|
|
static final double MINIMUM_DESKEW_THRESHOLD = 0.05d; |
|
|
|
|
|
|
|
private static final String datapath = "src/main/resources"; |
|
|
|
private static final String testResourcesLanguagePath = datapath+"/tessdata"; |
|
|
|
private static final String tempfile = "/ocrtempfile/"; |
|
|
|
|
|
|
|
private static ITesseract instance = new Tesseract(); |
|
|
|
|
|
|
|
static { |
|
|
|
instance.setDatapath(new File(datapath).getPath()); |
|
|
|
} |
|
|
|
|
|
|
|
private static File urlImgToFile(String fileUrl) { |
|
|
|
InputStream ins = null; |
|
|
|
OutputStream os = null; |
|
|
|
try { |
|
|
|
URL url = new URL(fileUrl); |
|
|
|
URLConnection c = url.openConnection(); |
|
|
|
ins = c.getInputStream(); |
|
|
|
File folder = new File (tempfile) ; |
|
|
|
if (!folder.exists()) { |
|
|
|
folder.mkdirs(); |
|
|
|
} |
|
|
|
File f = new File(tempfile+System.currentTimeMillis()+"-"+IdWorker.get32UUID()+".jpg"); |
|
|
|
if (f.exists()) { |
|
|
|
f.delete(); |
|
|
|
} |
|
|
|
f.createNewFile(); |
|
|
|
os = new FileOutputStream(f); |
|
|
|
int bytesRead = 0; |
|
|
|
byte[] buffer = new byte[8192]; |
|
|
|
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { |
|
|
|
os.write(buffer, 0, bytesRead); |
|
|
|
} |
|
|
|
os.close(); |
|
|
|
ins.close(); |
|
|
|
return f; |
|
|
|
} catch (MalformedURLException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} catch (IOException e) { |
|
|
|
// TODO Auto-generated catch block |
|
|
|
e.printStackTrace(); |
|
|
|
}finally { |
|
|
|
if (null != os) { |
|
|
|
try { |
|
|
|
os.close(); |
|
|
|
} catch (IOException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (null != ins) { |
|
|
|
try { |
|
|
|
ins.close(); |
|
|
|
} catch (IOException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private static void deletetempFile(File file) { |
|
|
|
if (file.exists()) { |
|
|
|
file.delete(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static String ocrLocalImgFile(String languagePath,String filePath,String fontName) throws Exception { |
|
|
|
File imageFile = new File(filePath); |
|
|
|
String result = testDoOCR_File(languagePath,imageFile,fontName); |
|
|
|
deletetempFile(imageFile); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
public static String ocrNetImgFile(String languagePath,String fileUrl,String fontName) throws Exception { |
|
|
|
File imageFile = urlImgToFile(fileUrl); |
|
|
|
String result = testDoOCR_File(languagePath,imageFile,fontName); |
|
|
|
deletetempFile(imageFile); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Test of doOCR method, of class Tesseract. |
|
|
|
* 根据图片文件进行识别 |
|
|
|
* @throws Exception while processing image. |
|
|
|
*/ |
|
|
|
public static String testDoOCR_File(String languagePath,File imageFile,String fontName) throws Exception { |
|
|
|
logger.info("doOCR on a jpg image"); |
|
|
|
//set language |
|
|
|
instance.setDatapath(languagePath); |
|
|
|
instance.setLanguage(fontName); |
|
|
|
String result = instance.doOCR(imageFile); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) { |
|
|
|
try { |
|
|
|
//System.out.println(ocrNetImgFile(testResourcesLanguagePath,"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.my0832.com%2Fattachments%2Fbbs%2F20140424%2F201442413083356803_740_1186.jpg&refer=http%3A%2F%2Fimg.my0832.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1613903848&t=985fc4c6c7b7ee82cb98f97ab5bf1459","test1")); |
|
|
|
System.out.println(ocrLocalImgFile(testResourcesLanguagePath,"C:\\Users\\iformall\\Desktop\\01.jpg","test1")); |
|
|
|
} catch (Exception e) { |
|
|
|
// TODO Auto-generated catch block |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// |
|
|
|
// /** |
|
|
|
// * Test of doOCR method, of class Tesseract. |
|
|
|
// * 根据图片流进行识别 |
|
|
|
// * @throws Exception while processing image. |
|
|
|
// */ |
|
|
|
// public void testDoOCR_BufferedImage() throws Exception { |
|
|
|
// logger.info("doOCR on a buffered image of a PNG"); |
|
|
|
// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); |
|
|
|
// BufferedImage bi = ImageIO.read(imageFile); |
|
|
|
// |
|
|
|
// //set language |
|
|
|
// instance.setDatapath(testResourcesLanguagePath); |
|
|
|
// instance.setLanguage("chi_sim"); |
|
|
|
// |
|
|
|
// String result = instance.doOCR(bi); |
|
|
|
// logger.info(result); |
|
|
|
// } |
|
|
|
// |
|
|
|
// /** |
|
|
|
// * Test of getSegmentedRegions method, of class Tesseract. |
|
|
|
// * 得到每一个划分区域的具体坐标 |
|
|
|
// * @throws java.lang.Exception |
|
|
|
// */ |
|
|
|
// public void testGetSegmentedRegions() throws Exception { |
|
|
|
// logger.info("getSegmentedRegions at given TessPageIteratorLevel"); |
|
|
|
// File imageFile = new File(testResourcesDataPath, "ocr.png"); |
|
|
|
// BufferedImage bi = ImageIO.read(imageFile); |
|
|
|
// int level = TessPageIteratorLevel.RIL_SYMBOL; |
|
|
|
// logger.info("PageIteratorLevel: " + Utils.getConstantName(level, TessPageIteratorLevel.class)); |
|
|
|
// List<Rectangle> result = instance.getSegmentedRegions(bi, level); |
|
|
|
// for (int i = 0; i < result.size(); i++) { |
|
|
|
// Rectangle rect = result.get(i); |
|
|
|
// logger.info(String.format("Box[%d]: x=%d, y=%d, w=%d, h=%d", i, rect.x, rect.y, rect.width, rect.height)); |
|
|
|
// } |
|
|
|
// |
|
|
|
// assertTrue(result.size() > 0); |
|
|
|
// } |
|
|
|
// |
|
|
|
// |
|
|
|
// /** |
|
|
|
// * Test of doOCR method, of class Tesseract. |
|
|
|
// * 根据定义坐标范围进行识别 |
|
|
|
// * @throws Exception while processing image. |
|
|
|
// */ |
|
|
|
// public void testDoOCR_File_Rectangle() throws Exception { |
|
|
|
// logger.info("doOCR on a BMP image with bounding rectangle"); |
|
|
|
// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); |
|
|
|
// //设置语言库 |
|
|
|
// instance.setDatapath(testResourcesLanguagePath); |
|
|
|
// instance.setLanguage("chi_sim"); |
|
|
|
// //划定区域 |
|
|
|
// // x,y是以左上角为原点,width和height是以xy为基础 |
|
|
|
// Rectangle rect = new Rectangle(84, 21, 15, 13); |
|
|
|
// String result = instance.doOCR(imageFile, rect); |
|
|
|
// logger.info(result); |
|
|
|
// } |
|
|
|
// |
|
|
|
// /** |
|
|
|
// * Test of createDocuments method, of class Tesseract. |
|
|
|
// * 存储结果 |
|
|
|
// * @throws java.lang.Exception |
|
|
|
// */ |
|
|
|
// public void testCreateDocuments() throws Exception { |
|
|
|
// logger.info("createDocuments for png"); |
|
|
|
// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); |
|
|
|
// String outputbase = "target/test-classes/docrenderer-2"; |
|
|
|
// List<RenderedFormat> formats = new ArrayList<RenderedFormat>(Arrays.asList(RenderedFormat.HOCR, RenderedFormat.TEXT)); |
|
|
|
// |
|
|
|
// //设置语言库 |
|
|
|
// instance.setDatapath(testResourcesLanguagePath); |
|
|
|
// instance.setLanguage("chi_sim"); |
|
|
|
// |
|
|
|
// instance.createDocuments(new String[]{imageFile.getPath()}, new String[]{outputbase}, formats); |
|
|
|
// } |
|
|
|
// |
|
|
|
// /** |
|
|
|
// * Test of getWords method, of class Tesseract. |
|
|
|
// * 取词方法 |
|
|
|
// * @throws java.lang.Exception |
|
|
|
// */ |
|
|
|
// public void testGetWords() throws Exception { |
|
|
|
// logger.info("getWords"); |
|
|
|
// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); |
|
|
|
// |
|
|
|
// //设置语言库 |
|
|
|
// instance.setDatapath(testResourcesLanguagePath); |
|
|
|
// instance.setLanguage("chi_sim"); |
|
|
|
// |
|
|
|
// //按照每个字取词 |
|
|
|
// int pageIteratorLevel = TessPageIteratorLevel.RIL_SYMBOL; |
|
|
|
// logger.info("PageIteratorLevel: " + Utils.getConstantName(pageIteratorLevel, TessPageIteratorLevel.class)); |
|
|
|
// BufferedImage bi = ImageIO.read(imageFile); |
|
|
|
// List<Word> result = instance.getWords(bi, pageIteratorLevel); |
|
|
|
// |
|
|
|
// //print the complete result |
|
|
|
// for (Word word : result) { |
|
|
|
// logger.info(word.toString()); |
|
|
|
// } |
|
|
|
// } |
|
|
|
// |
|
|
|
// /** |
|
|
|
// * Test of Invalid memory access. |
|
|
|
// * 处理倾斜 |
|
|
|
// * @throws Exception while processing image. |
|
|
|
// */ |
|
|
|
// public void testDoOCR_SkewedImage() throws Exception { |
|
|
|
// //设置语言库 |
|
|
|
// instance.setDatapath(testResourcesLanguagePath); |
|
|
|
// instance.setLanguage("chi_sim"); |
|
|
|
// |
|
|
|
// logger.info("doOCR on a skewed PNG image"); |
|
|
|
// File imageFile = new File(this.testResourcesDataPath, "ocr_skewed.jpg"); |
|
|
|
// BufferedImage bi = ImageIO.read(imageFile); |
|
|
|
// ImageDeskew id = new ImageDeskew(bi); |
|
|
|
// double imageSkewAngle = id.getSkewAngle(); // determine skew angle |
|
|
|
// if ((imageSkewAngle > MINIMUM_DESKEW_THRESHOLD || imageSkewAngle < -(MINIMUM_DESKEW_THRESHOLD))) { |
|
|
|
// bi = ImageHelper.rotateImage(bi, -imageSkewAngle); // deskew image |
|
|
|
// } |
|
|
|
// |
|
|
|
// String result = instance.doOCR(bi); |
|
|
|
// logger.info(result); |
|
|
|
// } |
|
|
|
|
|
|
|
} |