当前位置: 首页 > 后端技术 > Java

如何在Java中使用Tessdata做OCR图片文字描述,就看这篇文章吧~

时间:2023-04-01 20:59:55 Java

作者:Yoyoasafairy来源:恒生LIGHT云社区ocrad等。1、我用过百度接口(可以去百度开发者申请,免费),识别率还可以,但不是100%,但是使用次数有限制,虽然是够了,但总是有限的怕多了不准用。2.canvas的话,需要对图片做具体的处理,涉及图片翻转,设置灰度,设置文字间隔等,成功率很高,但是公司的产品验证码五花八门,并且没有办法使用它们。这个方法处理过,所以暂时放弃。3、目前用的是.js版本的ocrad,识别率还是比较低。后面会写一篇文章介绍具体的使用。虽然网上有很多关于Tessdata的技术介绍文章,但其实小仙实际使用的时候,也是费了一番周折。:fendou:思路:截取全图-截取元素图-处理-识别-输出注意:图片截取格式统一为.jpg,使用png会有问题。1.添加项目依赖在项目的pom.xml文件中,添加如下依赖net.java.dev.jnajna4.1.0net.sourceforge.tess4jtess4j2.0.1com.sun.jnajna2、从全图抓取元素图片//元素截图publicstaticString[]elementscreenShot(WebElementelement)throwsException{WrapsDriverwrapsDriver=(WrapsDriver)element;长时间=System.currentTimeMillis();//对整个页面进行截图Filescreen=((TakesScreenshot)wrapsDriver.getWrappedDriver()).getScreenshotAs(OutputType.FILE);缓冲图像img=ImageIO.read(屏幕);//获取元素的高度和宽度intwidth=element.getSize().getWidth();intheight=element.getSize().getHeight();//使用上面的高度和宽度创建一个矩形Rectanglerect=newRectangle(width,height);//获取元素Point的坐标p=element.getLocation();BufferedImagedest=img.getSubimage(p.getX(),p.getY(),(int)rect.getWidth(),(int)rect.getHeight());//保存为png格式ImageIO.write(dest,"png",screen);DateFormatdateFormat=newSimpleDateFormat("yyyyMMddhhmmss");FileSystemViewfsv=FileSystemView.getFileSystemView();文件com=fsv.getHomeDirectory();//这是读取桌面路径的方法Stringurl=com.getPath()+"/test";文件位置=新文件(url);如果(!location.exists()){location.mkdirs();}StringimgPath=location.getAbsolutePath()+File.separator+"pic_"+time+".jpg";StringcleanPath=location.getAbsolutePath();//存放原图和清除后图片的地址String[]imgpath={imgPath,clean小路};文件targetFile=新文件(imgPath);尝试{FileUtils.copyFile(screen,targetFile);}catch(IOExceptione1){e1.printStackTrace();}//元素图像路径returnimgpath;}3.对于截取图像处理:灰度化、二值化、去除干扰线等,以下是图像处理类,其中去除干扰线操作要慎用,以及文字也可能被删除publicclassCleanElementImage{/****@paramsfile*需要去噪的图片*@paramdestDir*去噪后图片保存地址*@throwsIOException*/publicstaticvoidhandlImage(Filesfile,StringdestDir)throwsIOException{文件destF=新文件(destDir);如果(!destF.exists()){destF.mkdirs();}BufferedImagebufferedImage=ImageIO.read(sfile);inth=bufferedImage.getHeight();intw=缓冲图像。得到宽度();//灰度int[][]gray=newint[w][h];对于(intx=0;x>16)&0xFF)*1.1+30);intg=(int)(((argb>>8)&0xFF)*1.1+30);intb=(int)(((argb>>0)&0xFF)*1.1+30);如果(r>=255){r=255;}如果(g>=255){g=255;}如果(b>=255){b=255;}gray[x][y]=(int)Math.pow((Math.pow(r,2.2)*0.2973+Math.pow(g,2.2)*0.6274+Math.pow(b,2.2)*0.0753),1/2.2);}}//二值化intthreshold=ostu(gray,w,h);BufferedImagebinaryBufferedImage=newBufferedImage(w,h,BufferedImage.TYPE_BYTE_BINARY);for(intx=0;xthreshold){gray[x][y]|=0x00FFFF;}else{灰色[x][y]&=0xFF0000;}binaryBufferedImage.setRGB(x,y,gray[x][y]);}}//去除干扰线//for(inty=1;y300){返回true;}returnfalse;}publicstaticintisBlackOrWhite(intcolorInt){if(getColorBright(colorInt)<30||getColorBright(colorInt)>730){r返回1;}return0;}publicstaticintgetColorBright(intcolorInt){颜色color=newColor(colorInt);返回color.getRed()+color.getGreen()+color.getBlue();}publicstaticintostu(int[][]gray,intw,inth){int[]histData=newint[w*h];//计算直方图for(intx=0;xvarMax){varMax=varBetween;阈值=t;}}returnthreshold;}}4.默认要识别的语言包是英文(识别字母和数字)。如果要识别中文(数字+中文),需要制定语言包。语言包可以指定路径,就可以了。源码下载地址您可以下载源码,然后到如下路径找到语言包,将语言包放在一个路径下:例如:XXX/tessdata/。tesseract.js-master.zip\tesseract.js-master\tests\assets\traineddata5.识别图片/***图片识别*@authorwangy*@date2019-08-26*@param参数*/publicstaticStringocrResult(WebElement元素)抛出异常{FileSystemViewfsv=FileSystemView.getFileSystemView();文件com=fsv.getHomeDirectory();//这是读取桌面路径的方式Stringurl="";Stringos=System.getProperty("os.name");//识别系统,找到不同的语言包路径if(os.indexOf("Windows")==-1){url="/opt/google/";}else{url=com.getPath();}//获取元素截图的路径Stringpath[]=Screenshot.elementscreenShot(element);//获取未处理的截图路径Stringimgpath=path[0];字符串结果=空;文件imageFile=newFile(imgpath);//处理图像CleanElementImage.handlImage(imageFile,path[1]);ITesseract实例=newTesseract();//读取语言包的路径地址instance.setDatapath(url+File.separator+"test"+File.separator+"tessdata");//默认是英文(识别字母和Number),如果要识别中文(数字+中文),需要做语言包,这里是数字,所以没有语言包//instance.setLanguage("chi_sim");//为了防止在图片被截取之前识别,做一个简单的循环try{StringocrResult=instance.doOCR(imageFile);if(imageFile.exists()&&ocrResult!=""){结果=ocrResult;}else{while(true){Thread.sleep(1000);if(imageFile.exists()&&ocrResult!=""){结果=ocrResult;休息;}}}}catch(TesseractExceptione){System.out.println(e.getMessage());}returnresult;}这部分由于项目问题,这里做了特殊处理,原代码略有不同,供大家使用,如有问题,欢迎反馈!6.下面是简单的结果对比。图片看效果。识别结果大概在90%以上: