java中识别验证码比较简单,使用的软件是tesseractocr,这个软件需要安装在本地中,傻瓜式安装(方便调用) 。

github下载地址 
https://github.com/tesseract-ocr/tessdata

博主是在官网下载的。

该软件默认的识别的是英文。如果需要识别中文,需要将中文的训练文本chi_sim.traineddata存放到C:\Program Files (x86)\Tesseract-OCR\tessdata。

简单的验证码识别 直接调用 Tesseract的 doOCR(image)方法即可。如果验证码的噪点多 并且有干扰线,这时候就需要对图像就行处理了。

图片处理大致思路:做灰度然后二值化 然后去除干扰线。

话不多说上代码。

实现代码

public static void main(String[] args) { String url = "验证图片地址";//验证码保存地址String path= "C:\\Users\\Administrator\\Desktop\\1.jpg"; //下载验证码 downloadPicture(url,path);Demo demo= new Demo(); String code= demo.FindOCR(path,false);System.out.println(code);
}

下载验证码很简单就是用HTTPClient获取验证图片的链接然后下载就可以了。我这里只放一个下载的代码。至于获取连接的每个网站的请求也不一样就不放出了。

    private static void downloadPicture(String urlList,String path) {URL url = null;try {url = new URL(urlList);DataInputStream dataInputStream = new DataInputStream(url.openStream());FileOutputStream fileOutputStream = new FileOutputStream(new File(path));ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int length;while ((length = dataInputStream.read(buffer)) > 0) {output.write(buffer, 0, length);}fileOutputStream.write(output.toByteArray());dataInputStream.close();fileOutputStream.close();} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

识别验证码的工具类

public  String FindVCode(String srcImg, boolean language) {try {File imgFile = new File(srcImg);if (!srcImg.exists()) {return "图片路径有误或不存在";}BufferedImage testImage = ImageIO.read(imgFile);Tesseract tesseract= new Tesseract();// 默认的图片库instance.setDatapath("/usr/local/share/tessdata/");if (language) {tesseract.setLanguage("chi_sim");}String vCode= null;// 下面是去图像优化的过程 不需要的可以不用 直接 vCode =instance.doOCR(testImage) ;BufferedImage cleanedImg = cleanLinesInImage(testImage);vCode= tesseract.doOCR(cleanedBufferedImage);return vCode;} catch (Exception e) {e.printStackTrace();return "未知错误";}}

图片处理过程

private BufferedImage cleanLinesInImage(BufferedImage image) throws IOException{BufferedImage bufferedImage = oriBufferedImage;int h = bufferedImage.getHeight();int w = bufferedImage.getWidth();for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {boolean c = true;// 这个像素块上下左右是不是都是黑色的,如果是,这个像素当作黑色的int roundWhiteCount = 0;if (isBlackColor(bufferedImage , x + 1, y + 1)){roundWhiteCount++;}if (isBlackColor(bufferedImage , x + 1, y - 1)){roundWhiteCount++;}if (isBlackColor(bufferedImage , x - 1, y + 1)){roundWhiteCount++;}if (isBlackColor(bufferedImage , x - 1, y - 1)){roundWhiteCount++;}if (roundWhiteCount >= 4) {c = false;}if (!isBlackColor(bufferedImage , x, y) && c) {image.setRGB(x, y, 0xFFFFFFFF); //argb:AARRGGBB}}}//把不是纯白色的像素块变成黑色的,用来做判断条件for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {// 不是纯白就填黑if ((bufferedImage .getRGB(x, y) & 0xFFFFFF) != (new Color(255, 255, 255).getRGB() & 0xFFFFFF)) {bufferedImage .setRGB(x, y, 0xFF000000);}}}// 二值化int threshold = ostu(gray, w, h);BufferedImage binaryBufferedImage= new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);for (int x = 0; x < w; x++){for (int y = 0; y < h; y++){if (gray[x][y] > threshold){gray[x][y] |= 0x00FFFF;} else{gray[x][y] &= 0xFF0000;}binaryBufferedImage.setRGB(x, y, gray[x][y]);}}cleanImage(binaryBufferedImage,h,w );return binaryBufferedImage;
}
private boolean isBlackColor(BufferedImage image, int x, int y) {// 检查这个像素块是不是边缘的if (x < 0 || y < 0 || x >= image.getWidth() || y >= image.getHeight()) {return false;}int pixel = image.getRGB(x, y);return// R(pixel & 0xFF0000) >> 16 < 30// G&& (pixel & 0xFF00) >> 8 < 30// B&& (pixel & 0xFF) < 30;
}
public void cleanImage(BufferedImage binaryBufferedImage,int h ,int w ){//去除干扰线条for(int y = 1; y < h-1; y++){for(int x = 1; x < w-1; x++){boolean flag = false ;if(isBlack(binaryBufferedImage.getRGB(x, y))){//左右均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y)) && isWhite(binaryBufferedImage.getRGB(x+1, y))){flag = true;}//上下均为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x, y+1)) && isWhite(binaryBufferedImage.getRGB(x, y-1))){flag = true;}//斜上下为空时,去掉此点if(isWhite(binaryBufferedImage.getRGB(x-1, y+1)) && isWhite(binaryBufferedImage.getRGB(x+1, y-1))){flag = true;}if(isWhite(binaryBufferedImage.getRGB(x+1, y+1)) && isWhite(binaryBufferedImage.getRGB(x-1, y-1))){flag = true;}if(flag){binaryBufferedImage.setRGB(x,y,-1);}}}}}public Mat bufferedImageToMat(BufferedImage bi) {Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_8UC1);byte[] white = new byte[] { (byte) 255 };byte[] black = new byte[] { (byte) 0 };for (int x=0; x<bi.getWidth(); x++) {for (int y=0; y<bi.getHeight(); y++) {if (bi.getRGB(x, y) == Color.BLACK.getRGB()) {mat.put(y, x, black);} else {mat.put(y, x, white);}}}return mat;}/*** Mat转换成BufferedImage** @param matrix*            要转换的Mat* @param fileExtension*            格式为 ".jpg", ".png", etc* @return*/public BufferedImage mat2BufImg (Mat matrix, String fileExtension) {// convert the matrix into a matrix of bytes appropriate for// this file extensionMatOfByte mob = new MatOfByte();Imgcodecs.imencode(fileExtension, matrix, mob);// convert the "matrix of bytes" into a byte arraybyte[] byteArray = mob.toArray();BufferedImage bufImage = null;try {InputStream in = new ByteArrayInputStream(byteArray);bufImage = ImageIO.read(in);} catch (Exception e) {e.printStackTrace();}return bufImage;}public boolean isBlack(int colorInt){Color color = new Color(colorInt);if (color.getRed() + color.getGreen() + color.getBlue() <= 300){return true;}return false;}public boolean isWhite(int colorInt){Color color = new Color(colorInt);if (color.getRed() + color.getGreen() + color.getBlue() > 300){return true;}return false;}public int isBlackOrWhite(int colorInt){if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730){return 1;}return 0;}public int getColorBright(int colorInt){Color color = new Color(colorInt);return color.getRed() + color.getGreen() + color.getBlue();}public int ostu(int[][] gray, int w, int h){int[] histData = new int[w * h];// Calculate histogramfor (int x = 0; x < w; x++){for (int y = 0; y < h; y++){int red = 0xFF & gray[x][y];histData[red]++;}}// Total number of pixelsint total = w * h;float sum = 0;for (int t = 0; t < 256; t++)sum += t * histData[t];float sumB = 0;int wB = 0;int wF = 0;float varMax = 0;int threshold = 0;for (int t = 0; t < 256; t++){wB += histData[t]; // Weight Backgroundif (wB == 0)continue;wF = total - wB; // Weight Foregroundif (wF == 0)break;sumB += (float) (t * histData[t]);float mB = sumB / wB; // Mean Backgroundfloat mF = (sum - sumB) / wF; // Mean Foreground// Calculate Between Class Variancefloat varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);// Check if new maximum foundif (varBetween > varMax){varMax = varBetween;threshold = t;}}return threshold;}

其中部分是借鉴网上的源代码。如果有编写不对,或者可以修改的更好的建议请指出。

Java实现验证码识别相关推荐

  1. java 12306验证码识别_GitHub - sunqipeng-cn/JavaVerify: 用java 编写的验证码识别

    基于惯性大水滴滴水算法和支持向量机的验证码识别 Inertial big drop fall algorithm, libsvm Introduction: Functions: 1.Download ...

  2. java o 验证码识别_验证码识别(一)

    开始做简单的ORC,从昨天到今天总算有个小小的成绩了. 图像的文字识别我拿验证码开刀,因为验证码稍微简单点,说说验证思路: 一.获取验证图片 二.程序加载要验证的字体库 三.程序加载需匹配的文字库(字 ...

  3. java图形验证码识别-阿里云OCR(精准率50%)

    1. 通用文字识别 请求参数详情https://market.aliyun.com/products/57124001/cmapi028554.html?spm=5176.2020520132.101 ...

  4. Java简单验证码的识别

    1. 需求 因为项目需要,需要多次登录某网站抓取信息.所以学习了验证码的一些小知识.文章参考http://blog.csdn.net/problc/article/details/5794460的部分 ...

  5. java 识别图片 边框_atitit.验证码识别step3----去除边框---- 图像处理类库 attilax总结java版本...

    atitit.验证码识别step3----去除边框----图像处理类库 attilax总结java版本 1. 去除边框思路原理 图像裁剪::从图片的Positions.CENTER,wid,hit)裁 ...

  6. Java 验证码识别之多线程打码兔

    验证码识别,爬虫永远的话题~ 用打码兔总体的体验就是单线程速度太慢~ importjava.io.IOException;importjava.net.MalformedURLException;im ...

  7. 【java】opencv + Tesseract(tess4j) 实现图片处理验证码识别

    2022/12/27 有的小伙伴说maven导入不了依赖,加了一种方法,百分百解决. 2022/12/28 写了半天,想去论坛放松休息下,结果看到别人已经有成品了,难受啊马飞,晚点看情况要不要写个搭建 ...

  8. java莱茨狗_百度莱茨狗爬虫,支持本地验证码识别

    百度莱茨狗购买爬虫 如果这个项目对你有帮助,烦请点一下右上角的star,thanks~ v0.6版本使用前请先解压resources/下的svm.model.zip文件到该目录: 效果图: 功能 当前 ...

  9. java验证码识别库

    java验证码识别库 使用J4L识别验证码 使用 Tess4J 进行 OCR 识别 使用J4L识别验证码 将解压文件下bits64目录的三个文件 liblept168.dll tess3Wrapper ...

最新文章

  1. miniUI怎么显示HTML显示整数,MINIUI后台获取数据
  2. AAuto 快速开发win32小程序
  3. 【Spring注解系列10】SpringBean的生命周期
  4. delphi7升级delphi2007可以互用马_奶爸带娃玩“升级版摇摇马”火了,像极了传说中的“甘为孺子牛”...
  5. FlexPaper不能跨服务器加载远程文件解决办法
  6. 人身三流指什么_电气隔离是什么意思呢?
  7. git reset --hard_Git紧急自救简易指南(二)——版本的游历
  8. HALCON示例程序check_blister.hdev药品胶囊检测
  9. java语言jdk_Java语言环境(JDK的安装教学)
  10. fckeditor异常总结---1.NoClassDefFoundError: org/slf4j/LoggerFactory和NoClassDefFoundError: org/apache/log
  11. 软件测试之python面试题_常见Python面试题整理带答案
  12. 机器学习第五回——学习方法与学习曲线
  13. php ip 转,用php进行ip/子网到IP 地址范围的转换
  14. 单层感知器神经网络matlab,MATLAB神经网络——单层感知器
  15. cnavas手绘图形库 : rough.js
  16. IP种子眼中的《延禧攻略》流落何处?
  17. Mysql必知必会概要总结
  18. 【弄nèng - Elasticsearch】运维篇 —— ES分片unassigned解决方案(ALLOCATION_FAILED,REPLICA_ADDED等
  19. [VCS]后仿真中的几个基本概念
  20. laydate时间控件在谷歌浏览器中兼容性问题

热门文章

  1. 橄榄山2014总结,祝福2015
  2. linux steam root,Steam
  3. 设备和打印机或设备管理器中有多个爱奇艺客厅电视越来越多解决办法
  4. Java Gradle 入门与实践
  5. Aptina荣获2010年EDN创新奖
  6. 论文阅读-Robust Image Retargeting via Axis-Aligned Deformation
  7. 第十四章、Linux 账号管理与 ACL 权限配置
  8. VS2019 离线安装包(C++ Python C#5.3G多)
  9. 现在电脑的主流配置_主流游戏主机 2019年九代i59400F配GTX1060独显电脑装机配置清单...
  10. 国家统计局与企业开发利用大数据