JavaSE图像验证码简单识别程序详解

本文为大家分享了JavaSE图像验证码简单识别程序,供大家参考,具体内容如下

首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色。

然后你就可以使用该类,对目标文件进行分析。具体怎么实现我觉得这个类非常清楚,就是将样本从左都有这么横向移动,匹配出一个合适的就将坐标调整到下个位置。

此程序已是3年多前写的,后来没有在深入写下去,图像识别一个很深的领域,得需要很深的数学功底跟思维能力,这个java的程序效率不高,也不能识别变形的或者拉伸的图片,但在那个年代,已经足够用了,大家如果有更好的开源的图像识别代码,请务必来信交流:)

/**
 * 图片解析引擎,适合做网站验证码的分析。
 * 首先必须载入样品,解析器将从左到右横向扫描,发现于样本的就自动记录。
 * 当然本程序不适合样本不是唯一的,也就是说要识别的图片被缩放或者坐标变动和变形本程序无法进行这样的识别。
 * 如果图片中的颜色变化非常大,此程序可能会有问题,当然了你可以选择一个标准的值做为转换成0,1矩阵的标准。
 *
 * 样本的制作:请将样本转换成灰度模式,只含有两色最好,当然了不转换我也帮你转换了。
 *
 */

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;

public class ImageParser {

  // ------------------------------------------------------------ Private Data

  // 样本的矩阵
  private static List swatches   = null;

  // 样本的值
  private static List swatcheValues = null;

  // 图片文件的矩阵化
  private byte[][]  targetColors;

  // ------------------------------------------------------------ Test main method
  public static void main(String[] args) {
    // 加入样本与其样本对应的数值
    String[] files = new String[10];
    String[] values = new String[10];
    for (int i = 0; i < files.length; i++){
      files[i] = "D:/workspace/SZXClientAPP/res/" + i + ".jpg";
      values[i] = String.valueOf(i);
    }

    ImageParser parse = new ImageParser(files, values);
    long startime = System.currentTimeMillis();
    try {
      // 解析图片
      System.out.println(parse.parseValue("D:/workspace/SZXClientAPP/res/ValidateNum"));
      long sincetime = System.currentTimeMillis();
      System.out.println("所花时间 = " + (sincetime - startime));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  // ------------------------------------------------------------ Constructors

  /**
   * 载入所有样本路径与其样本对应的数值
   *
   * @param files
   */
  public ImageParser(String[] files, String[] values) {
    // 只允许样本创建一次即可
    if (swatches == null && swatcheValues == null) {
      int fileslength = files.length;
      int valueslength = values.length;
      if(fileslength != valueslength){
        System.out.println("样本文件与样本数值不匹配!请重新设置!");
        return;
      }
      swatches = new ArrayList(fileslength);
      swatcheValues = new ArrayList(valueslength);
      int i = 0;
      try {
        for (; i < files.length; i++) {
          swatches.add(imageToMatrix(files[i]));
          swatcheValues.add(i, values[i]);
        }
      } catch (Exception e) {
        System.out.println(files[i] + " can not be parsed");
        e.printStackTrace();
      }
    }
  }

  public ImageParser() {
    super();
    if (swatches == null || swatcheValues == null) {
      System.out.println("您未载入样本,请先载入样本!");
    }
  }

  /**
   * 解析图片的值
   *
   * @param parseFilePath
   *      给出图片路径
   * @return 返回字符串
   * @throws Exception
   */
  public String parseValue(String parseFilePath) throws Exception {
    StringBuffer result = new StringBuffer();
    targetColors = imageToMatrix(parseFilePath);
    // printMatrix(targetColors);
    int height = targetColors.length;
    int targetWidth = targetColors[0].length;

    int width = 0;
    Iterator it = swatches.iterator();
    while (it.hasNext()) {
      byte[][] bytes = (byte[][]) it.next();
      int templen = bytes[0].length;
      if (templen > width)
        width = templen;
    }
    // System.out.println("MaxWidth = " + width);
    // System.out.println("MaxHeight = " + height);
    int xTag = 0;
    while ((xTag + width) < targetWidth) {
      cout: {
        Iterator itx = swatches.iterator();
        int i = 0;
        while (itx.hasNext()) {
          byte[][] bytes = (byte[][]) itx.next();
          byte[][] temp = splitMatrix(targetColors, xTag, 0, width, height);
          // System.out.println(i++);
          if (isMatrixInBigMatrix(bytes, temp)) {
            xTag += width;
            // System.out.println("new maxtrix: ");
            // printMatrix(temp);

            result.append(swatcheValues.get(i));
            break cout;
          }
          i++;
        }
        xTag++;
      }
    }
    return result.toString();
  }

  // ------------------------------------------------------------ Private methods

  /**
   * 判断一个矩阵是否在另外的矩阵中
   *
   * @param source
   *      源矩阵
   * @param bigMatrix
   *      大的矩阵
   * @return 如果存在就返回 true
   */
  private static final boolean isMatrixInBigMatrix(byte[][] source, byte[][] bigMatrix) {
    if (source == bigMatrix)
      return true;
    if (source == null || bigMatrix == null)
      return false;

    if (source.length > bigMatrix.length)
      return false;

    try {
      for (int i = 0; i < source.length; i++) {
        if (source[i].length > bigMatrix[i].length)
          return false;
      }
    } catch (ArrayIndexOutOfBoundsException e) {
      return false;
    }

    int height = source.length;
    int width = source[0].length;
    int x = 0, y = 0;
    int i = 0, j = 0;
    int count = 0;

    int comparecount = height * width;

    for (; i < bigMatrix.length - height + 1; i++) {
      for (j = 0; j < bigMatrix[i].length - width + 1; j++) {
        cout: {
          x = 0;
          count = 0;
          for (int k = i; k < height + i; k++) {
            y = 0;
            for (int l = j; l < width + j; l++) {
              // System.out.println("bytes[" + x + "][" + y + "]"
              // + " = " + source[x][y] + ", " + "other["
              // + k + "][" + l + "] = " + bigMatrix[k][l]);
              if ((source[x][y] & bigMatrix[k][l]) == source[x][y]) {
                count++;
              } else
                break cout;
              y++;
            }
            x++;
          }
          // System.out.println("count = " + count);
          if (count == comparecount)
            return true;
        }
      }
    }
    return false;
  }

  /**
   * 切割矩阵
   *
   * @param source
   *      源矩阵
   * @param x
   *      X坐标
   * @param y
   *      Y坐标
   * @param width
   *      矩阵的宽度
   * @param height
   *      矩阵的高度
   * @return 切割后的矩阵
   */
  private static final byte[][] splitMatrix(byte[][] source, int x, int y, int width, int height) {
    byte[][] resultbytes = new byte[height][width];
    for (int i = y, k = 0; i < height + y; i++, k++) {
      for (int j = x, l = 0; j < width + x; j++, l++) {

        resultbytes[k][l] = source[i][j];
        // System.out.println("source[" + i + "][" + j + "]" + " = " +
        // source[i][j] + ", " + "resultbytes["
        // + k + "][" + l + "] = " + resultbytes[k][l]);
      }

    }
    return resultbytes;
  }

  /**
   * 图片转换成矩阵数组
   *
   * @param filePath
   *      文件路径
   * @return 返回矩阵
   * @throws Exception
   *       可能会抛出异常
   */
  private byte[][] imageToMatrix(String filePath) throws Exception {
    // 读入文件
    Image image = ImageIO.read(new File(filePath));
    int w = image.getWidth(null);
    int h = image.getHeight(null);
    BufferedImage src = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    src.getGraphics().drawImage(image, 0, 0, null);

    byte[][] colors = new byte[h][w];

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        int rgb = src.getRGB(j, i);
        // 像素进行灰度处理
        String sRed = Integer.toHexString(rgb).substring(2, 4);
        String sGreen = Integer.toHexString(rgb).substring(4, 6);
        String sBlank = Integer.toHexString(rgb).substring(6, 8);
        long ired = Math.round((Integer.parseInt(sRed, 16) * 0.3 + 0.5d));
        long igreen = Math.round((Integer.parseInt(sGreen, 16) * 0.59 + 0.5d));
        long iblank = Math.round((Integer.parseInt(sBlank, 16) * 0.11 + 0.5d));
        long al = ired + igreen + iblank;

        // if (al > 127)
        // System.out.print(" " + " ");
        // else
        // System.out.print(" " + "1");
        // System.out.print(" " + (tempint > = maxint ? 0 : 1));
        // System.out.println("tempInt = " + tempint);

        /* 将图像转换成0,1 */
        // 此处的值可以将来修改成你所需要判断的值
        colors[i][j] = (byte) (al > 127 ? 0 : 1);
      }
      // System.out.println();
    }

    return colors;
  }

  /**
   * 打印矩阵
   *
   * @param matrix
   */
  private static final void printMatrix(byte[][] matrix) {
    for (int i = 0; i < matrix.length; i++) {
      for (int j = 0; j < matrix[i].length; j++) {
        if (matrix[i][j] == 0)
          System.out.print(" ");
        else
          System.out.print(" 1");
      }
      System.out.println();
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java OCR tesseract 图像智能文字字符识别技术实例代码

    接着上一篇OCR所说的,上一篇给大家介绍了tesseract 在命令行的简单用法,当然了要继承到我们的程序中,还是需要代码实现的,下面给大家分享下Java实现的例子. 拿代码扫描上面的图片,然后输出结果.主要思想就是利用Java调用系统任务. 下面是核心代码: package com.zhy.test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.i

  • Java基于直方图应用的相似图片识别实例

    本文实例讲述了Java实现基于直方图应用的相似图片识别,是非常实用的技巧.分享给大家供大家参考.具体分析如下: 一.算法概述: 首先对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再使用巴氏系数算法对直方图数据进行计算,最终得出图像相似度值,其值范围在[0, 1]之间 0表示极其不同,1表示极其相似(相同). 二.算法步骤详解: 大致可以分为两步,根据源图像与候选图像的像素数据,生成各自直方图数据.第二步:使用第一步输出的直方图结果,运用巴氏系数(Bhattachary

  • Java实现的百度语音识别功能示例

    本文实例讲述了Java实现的百度语音识别功能.分享给大家供大家参考,具体如下: SDK以及示例代码下载地址: http://yuyin.baidu.com/sdk 最近一直在搞java,就选择了java工程.将代码拷过去.同时复制文件"test.pcm"到工程目录下.就基本上可以了. 注:test.pcm是语音文件,可以用audacity软件打开,选择 文件->导入->裸数据. 设置采样率为8000Hz.点击播放就能听见声音了. 这个时候程序跑起来还有问题,需要将apiKe

  • 识别率很高的java文字识别技术

    java文字识别程序的关键是寻找一个可以调用的OCR引擎.tesseract-ocr就是一个这样的OCR引擎,在1985年到1995年由HP实验室开发,现在在Google.tesseract-ocr 3.0发布,支持中文.不过tesseract-ocr 3.0不是图形化界面的客户端,别人写的FreeOCR图形化客户端还不支持导入新的 3.0 traineddata.但这标志着,现在有自由的中文OCR软件了. java中使用tesseract-ocr3.01的步骤如下: 1.下载安装tessera

  • OPENCV+JAVA实现人脸识别

    本文实例为大家分享了JAVA实现人脸识别的具体代码,供大家参考,具体内容如下 官方下载 安装文件 ,以win7为例,下载opencv-2.4.13.3-vc14.exe 安装后,在build目录下 D:\opencv\build\java,获取opencv-2413.jar,copy至项目目录 同时需要dll文件 与 各 识别xml文件,进行不同特征的识别(人脸,侧脸,眼睛等) dll目录:D:\opencv\build\java\x64\opencv_java2413.dll xml目录:D:

  • java指纹识别以及谷歌图片识别技术源码

    本文实例为大家分享了java指纹识别和图片识别源代码,供大家参考,具体内容如下 主类: import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; public class SimilarImageSearch { /** * @param args */ public static void main(String[] args) { List<String> hashCode

  • java微信企业号开发之发送消息(文本、图片、语音)

    上篇文章介绍了开启回调模式,开始回调模式后我们就要实现聊天功能了.平时使用微信聊天可以发送文本消息.语音.图片.视频等,这里只实现了其中的一些功能和大家分享. 一.与微信企业号建立连接 1.企业应用调用企业号提供的接口,管理或查询企业号后台所管理的资源.或给成员发送消息等,以下称主动调用模式. 2.企业号把用户发送的消息或用户触发的事件推送给企业应用,由企业应用处理,以下称回调模式. 3.用户在微信中阅读企业应用下发的H5页面,该页面可以调用微信提供的原生接口,使用微信开放的终端能力,以下称JS

  • java实现图片文字识别ocr

    最近在开发的时候需要识别图片中的一些文字,网上找了相关资料之后,发现google有一个离线的工具,以下为java使用的demo 在此之前,使用这个工具需要在本地安装OCR工具: 下面一个是一定要安装的离线包,建议默认安装 上面一个是中文的语言包,如果网络可以FQ的童鞋可以在安装的时候就选择语言包在线安装,有多种语言可供选择,默认只有英文的 exe安装好之后,把上面一个文件拷到安装目录下tessdata文件夹下 如C:\Program Files (x86)\Tesseract-OCR\tessd

  • JavaSE图像验证码简单识别程序详解

    本文为大家分享了JavaSE图像验证码简单识别程序,供大家参考,具体内容如下 首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色. 然后你就可以使用该类,对目标文件进行分析.具体怎么实现我觉得这个类非常清楚,就是将样本从左都有这么横向移动,匹配出一个合适的就将坐标调整到下个位置. 此程序已是3年多前写的,后来没有在深入写下去,图像识别一个很深的领域,得需要很深的数学功底跟思维能力,这个java的程序效率不高,也不能识别变形的或者拉伸的图片,但在那个年代,已经足够用了,大家如

  • 微信小程序之网络请求简单封装实例详解

    微信小程序之网络请求简单封装实例详解 在微信小程序中实现网络请求相对于Android来说感觉简单很多,我们只需要使用其提供的API就可以解决网络请求问题. 普通HTTPS请求(wx.request) 上传文件(wx.uploadFile) 下载文件(wx.downloadFile) WebSocket通信(wx.connectSocket) 为了数据安全,微信小程序网络请求只支持https,当然各个参数的含义就不在细说,不熟悉的话可以:可以去阅读官方文档的网络请求api,当我们使用request

  • Python完全识别验证码自动登录实例详解

    1.直接贴代码 #!C:/Python27 #coding=utf-8 from selenium import webdriver from selenium.webdriver.common.keys import Keys from pytesser import * from PIL import Image,ImageEnhance,ImageFilter from selenium.common.exceptions import NoSuchElementException,Tim

  • Android中用Bmob实现短信验证码功能的方法详解

    这篇文章主要介绍发送验证码和校验验证码的功能,用到一个第三方平台Bmob,那Bmob是什么呢?Bmob可以开发一个云存储的移动应用软件,他提供了大量的标准的API接口,根据需要接入相关服务,开发者可以更加专注于应用的开发,让产品交付更快速,验证码功能就是其中一个. 一.跟其他第三方一样,我们开发之前要做一些准备工作. 1.首先,去官网注册一个帐号:http://www.bmob.cn/: 2.然后就可以创建应用了:具体怎么做Bmob说得很清楚了(官方操作介绍),如果你不想看,我简单说一下:点击右

  • Python深度学习之图像标签标注软件labelme详解

    前言 labelme是一个非常好用的免费的标注软件,博主看了很多其他的博客,有的直接是翻译稿,有的不全面.对于新手入门还是有点困难.因此,本文的主要是详细介绍labelme该如何使用. 一.labelme是什么? labelme是图形图像注释工具,它是用Python编写的,并将Qt用于其图形界面.说直白点,它是有界面的, 像软件一样,可以交互,但是它又是由命令行启动的,比软件的使用稍微麻烦点.其界面如下图: 它的功能很多,包括: 对图像进行多边形,矩形,圆形,多段线,线段,点形式的标注(可用于目

  • 基于Opencv图像识别实现答题卡识别示例详解

    目录 1. 项目分析 2.项目实验 3.项目结果 总结 在观看唐宇迪老师图像处理的课程中,其中有一个答题卡识别的小项目,在此结合自己理解做一个简单的总结. 1. 项目分析 首先在拿到项目时候,分析项目目的是什么,要达到什么样的目标,有哪些需要注意的事项,同时构思实验的大体流程. 图1. 答题卡测试图像 比如在答题卡识别的项目中,针对测试图片如图1 ,首先应当实现的功能是: 能够捕获答题卡中的每个填涂选项. 将获取的填涂选项与正确选项做对比计算其答题正确率. 2.项目实验 在对测试图像进行形态学操

  • OpenCV学习之图像的分割与修复详解

    目录 背景 一.分水岭法 二.GrabCut法 三.MeanShift法 四.MOG前景背景分离法 五.拓展方法 六.图像修复 总结 背景 图像分割本质就是将前景目标从背景中分离出来.在当前的实际项目中,应用传统分割的并不多,大多是采用深度学习的方法以达到更好的效果:当然,了解传统的方法对于分割的整体认知具有很大帮助,本篇将介绍些传统分割的一些算法: 一.分水岭法 原理图如下: 利用二值图像的梯度关系,设置一定边界,给定不同颜色实现分割: 实现步骤: 标记背景 —— 标记前景 —— 标记未知区域

  • 实现一个基于Servlet的hello world程序详解步骤

    目录 一. 引入相关jar包 二. 编写java代码 1. 创建一个类 2. 删除super方法 3. 构造相关字符串 4. 将类和HTTP特定请求相关联 三. 创建一些必要的目录和文件 四. 打包程序 五. 部署程序 六. 验证程序是否正常工作 一. 引入相关jar包 首先,我们先在idea里创建出一个Maven项目出来,除了路径要填成自己的希望路径以外,其他都可以一路next和finish 创建好后,我们需要在pom.xml中加上一组<dependencies>标签,在标签里引入servl

  • Spring Boot实现登录验证码功能的案例详解

    目录 验证码的作用 案例要求 前端页面准备 准备login.html页面 随机验证码工具类 后端控制器 验证码的作用 验证码的作用:可以有效防止其他人对某一个特定的注册用户用特定的程序暴力破解方式进行不断的登录尝试我们其实很经常看到,登录一些网站其实是需要验证码的,比如牛客,QQ等.使用验证码是现在很多网站通行的一种方式,这个问题是由计算机生成并且评判的,但是必须只有人类才能解答,因为计算机无法解答验证码的问题,所以回答出问题的用户就可以被认为是人类.验证码一般用来防止批量注册. 案例要求 验证

  • Tensorflow加载模型实现图像分类识别流程详解

    目录 前言 正文 VGG19网络介绍 总结 前言 深度学习框架在市面上有很多.比如Theano.Caffe.CNTK.MXnet .Tensorflow等.今天讲解的就是主角Tensorflow.Tensorflow的前身是Google大脑项目的一个分布式机器学习训练框架,它是一个十分基础且集成度很高的系统,它的目标就是为研究超大型规模的视觉项目,后面延申到各个领域.Tensorflow 在2015年正式开源,开源的一个月内就收获到1w多的starts,这足以说明Tensorflow的优越性以及

随机推荐