JAVA语言之JavaSE图像验证码简单识别程序详解[Java代码]
龚超 2018-07-19 来源 : 阅读 1210 评论 0

摘要:本文主要向大家介绍了JAVA语言的JavaSE图像验证码简单识别程序详解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言的JavaSE图像验证码简单识别程序详解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文为大家分享了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();

}

}

}


复制代码

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @职坐标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论
本文作者 联系TA

擅长针对企业软件开发的产品设计及开发的细节与流程设计课程内容。座右铭:大道至简!

  • 370
    文章
  • 23048
    人气
  • 87%
    受欢迎度

已有23人表明态度,87%喜欢该老师!

进入TA的空间
求职秘籍 直通车
  • 索取资料 索取资料 索取资料
  • 答疑解惑 答疑解惑 答疑解惑
  • 技术交流 技术交流 技术交流
  • 职业测评 职业测评 职业测评
  • 面试技巧 面试技巧 面试技巧
  • 高薪秘笈 高薪秘笈 高薪秘笈
TA的其他文章 更多>>
WEB前端必须会的基本知识题目
经验技巧 93% 的用户喜欢
Java语言中四种遍历List的方法总结(推荐)
经验技巧 91% 的用户喜欢
Java语言之SHA-256加密的两种实现方法详解
经验技巧 75% 的用户喜欢
java语言实现把两个有序数组合并到一个数组的实例
经验技巧 75% 的用户喜欢
通过Java语言代码来创建view的方法
经验技巧 80% 的用户喜欢
其他海同师资 更多>>
吕益平
吕益平 联系TA
熟悉企业软件开发的产品设计及开发
孔庆琦
孔庆琦 联系TA
对MVC模式和三层架构有深入的研究
周鸣君
周鸣君 联系TA
擅长Hadoop/Spark大数据技术
范佺菁
范佺菁 联系TA
擅长Java语言,只有合理的安排和管理时间你才能做得更多,行得更远!
金延鑫
金延鑫 联系TA
擅长与学生或家长及时有效沟通
经验技巧30天热搜词 更多>>

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程