JavaSE图像验证码简单识别程序详解
作者:o_ochongchong
这篇文章主要为大家详细介绍了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(); } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- Java swing 图像处理多种效果实现教程
- java如何用Processing生成马赛克风格的图像
- JAVA演示阿里云图像识别API,印刷文字识别-营业执照识别
- Java实现图片旋转、指定图像大小和水平翻转
- java通过jni调用opencv处理图像的方法
- Java获取彩色图像中的主色彩的实例代码
- Java图像之自定义角度旋转(实例)
- Java OCR tesseract 图像智能文字字符识别技术实例代码
- 详解使用JavaCV/OpenCV抓取并存储摄像头图像
- java 使用ImageIO.writer从BufferedImage生成jpeg图像遇到问题总结及解决
- Java利用AlphaComposite类合并图像